Thursday, March 09, 2006

Using Monad to query an Exchange Mailbox via WebDAV to display Unread Emails

I’ve had a chance this week to play around a bit more with MSH and the .NET 2.0 framework and thought I’d share this sample that uses the .net framework to query an Exchange mailbox via WebDAV to display the number of unread email in a mailbox and the subject of the unread email. One of the good things with monad is that you can use both Com and .NET objects pretty easy so all the Microsoft.http browser object stuff will still work but its better to use the new stuff whenever you can. Vivek and Lee Holmes have come up with a good sample of doing a http get using Monad. This helped along with the basic .NET sample from the Exchange SDK in coming up with a simple script that queries an Exchange mailbox using the currently logged on users credentials for any email that is unread. The query itself is a simple WebDAV search that looks for any mail in the inbox folder where the urn:schemas:httpmail:read property is false.

The script itself takes two command-line parameters which is the servername and the mailbox alias (in Exchange 2003 you could use the email address). Eg to run the script you can use displayunread.msh servername mailboxalias (or displayunread.msh servername in Exchange 2003 would work)

I put a downloadable copy of the script here the code itself looks like

param([String] $servername = $(throw "Please specify the Servername"),
[String] $mailbox = $(throw "Please specify a Mailbox"))
$strRootURI = "http://" + $servername + "/exchange/" + $mailbox + "/inbox"
$strQuery = "<?xml version=`"1.0`"?><D:searchrequest xmlns:D = `"DAV:`" ><D:sql>
SELECT `"DAV:displayname`",`"urn:schemas:httpmail:subject`" FROM scope('shallow
traversal of `"" + $strRootURI + "`"')
Where `"DAV:ishidden`" = False AND `"DAV:isfolder`" = False AND
`"urn:schemas:httpmail:read`" = false</D:sql></D:searchrequest>"
$WDRequest = [System.Net.WebRequest]::Create($strRootURI)
$WDRequest.ContentType = "text/xml"
$WDRequest.Headers.Add("Translate", "F")
$WDRequest.Method = "SEARCH"
$WDRequest.UseDefaultCredentials = $True
$bytes = [System.Text.Encoding]::UTF8.GetBytes($strQuery)
$WDRequest.ContentLength = $bytes.Length
$RequestStream = $WDRequest.GetRequestStream()
$RequestStream.Write($bytes, 0, $bytes.Length)
$WDResponse = $WDRequest.GetResponse()
$ResponseStream = $WDResponse.GetResponseStream()
$ResponseXmlDoc = new-object System.Xml.XmlDocument
$DisplayNameNodes = $ResponseXmlDoc.GetElementsByTagName("d:subject")
"Number of Unread Email : " + $DisplayNameNodes.Count


Anonymous said...

I don't understand the $'s not defined prior to evaluating it in the assignment to $strQuery. I'm new to Monad, can you explain this variable ?


Glen said...

Actually that was a slight bug. The $strRootURI should have been the name of the folder to query eg

http://servername/exchange/user/inbox. You can get away with having it blank with WebDAV but for postertiy i've updated the post thanks