Wednesday, December 15, 2010

Exchange EWS Powershell module for the EWS Managed API

One of the constant challenges in IT especially where scripting is involved is abstracting things that seem complicated and trying to make them easier. Because what we do a lot of the time are slightly different iterations of the same idea making simpler these repetitions can be a good thing. The EWS Managed API is a great tools for making it easier to access Exchange using powershell and other .NET languages. One of the freelance projects I've been working on over the past couple of months was firstly a powershell snapin just for BPOS that we have now turned this into a Powershell module that will work with any version of on premise Exchange (Starting with 2007) as well as BPOS and Office365. This module contains a bunch of growing cmdlets that help automate what would generally be a large number of lines of script within a normal EWS powershell script down to a one or two lines. The advantage of this was making it easy to reuse large chucks of code in simpler scripts to do more complicated tasks. Because it uses the EWS Managed API it exposes these objects and methods so you can mix and match between using the cmdlets and just pure Managed API code. Fortunately MessageOps who i wrote this for (and have a great array of other apps) have decided to provide it free to everyone to use. This is still a work in process so there are a few bugs here and there and the documentation is a little sparse but for the most it works pretty well you can download the module and some instructions and examples of how to use it from http://www.messageops.com/downloads/MessageOps-Exchange-Module.zip . As an example of what it can do here's how easy you can use this to create RSS feeds from Inbox or Public folder Items

Using the MessageOps Exchange PowerShell Module to generate a RSS feeds of a specific mailbox folder or public folder in Exchange.

The EWS Powershell module contains Out-MessageOps.MessagesToRSS cmdlet that will output a collection of EWS Messages Items to a RSS feed. To get the Collection of Items to Output to the RSS Feed you can use one either one of the following 3 cmdlets which will retrieve Items from a Mailbox or public folder.

Get-MessageOps.Messages : This is a generic retrieve and simple search cmdlets that returns messages and message details from a mailbox. Supports several switches to find messages based on Subject, Read Status, Attachments, etc. It returns information such as message recipients, sender information, message headers, message body, and attachment details.

Search-MessageOps.MailFolder : Allows you to search a mailbox folder based on a number or parameters such as StartDate, EndDate, Subject Contains, Body Contains.

Search-MessageOps.CrawlMailFolder : Allows more advanced searching of mailboxes. Allows you to use Regular Expressions in mailbox searches. Includes a built in Credit Card search function.

Which cmdlet you use depends on what your trying to achieve and how detailed the filtering you want to apply to the collection of messages you want in the RSS feed. Examples of using this with the different cmdlets

Before you start you need a EWSProfile object to create one use the following

$ewsProfile = New-MessageOps.EWSProfile -id “user@.domain.com

Creating a feed of the last 20 items in the Inbox

$ItemCollection = Get-MessageOps.Messages -p $ewsprofile -fp "\\Inbox" -messagecount 20 -fulldetails $true

Out-MessageOps.MessagesToRSS -p $ewsprofile -FileName c:\outrss.xml -FeedTitle "Mailbox Feed" -Items $ItemCollection

Create a feed of the last 20 Items in Public Folder called company-emails

$ItemCollection = Get-MessageOps.Messages -p $ewsprofile -fp "\\publicfolderroot\company-emails" -messagecount 20 -fulldetails $true

Out-MessageOps.MessagesToRSS -p $ewsprofile -FileName c:\outrsspf.xml -FeedTitle "Public Folder Feed" -Items $ItemCollection -PublicFolder $true

Create a feed of just email from a specific address

$ItemCollection = Search-MessageOps.MailFolder -p $ewsprofile -fp \\inbox -from bob@domain.com -fulldetail $true -messagecount 20 -fulldetails $true

Out-MessageOps.MessagesToRSS -p $ewsprofile -FileName c:\outrs22s.xml -FeedTitle "Mailbox Feed" -Items $ItemCollection -PublicFolder $true

Using different options for unread email, attachments or use your own custom EWS Managed API searchfilter object can allow you to create any custom filter to suit most needs.

7 comments:

John said...

Glen,

We are trying the Search-MessageOps.CrawlMailFolder - Allows for advanced mailbox searches . It seems to only search the \Inbox and not subfolders can you tell me if it is possible to do this with the CrawlMailFolder? Thanks gain for all your work.

Glen said...

It only searchs the folder you feed it with so if you want to say search all folders in a mailbox you need to feed it all the folders eg

Find-MessageOps.MailboxFolders -identity $mailboxToAccess -p $ewsprofile -MsgFolderRoot | foreach-object{
if ($_.TotalCount -gt 0){
"Processing Folder " + $_.DisplayName
$folder = $_
Search-MessageOps.CrawlMailFolder -identity $mailboxToAccess -p $ewsprofile -ewsFolder $folder -creditcard $true
}
}

Cheers
Glen

John said...

Glen,

That seems to work. Thank you. Now that I can get the information out will work on generating a report so that the messages identified can be removed or archived.

Regards,

John

John said...

Glen,

I can run the script and output the results to a file on an individual mailbox. I am trying to see if we can use the import-csv and then run the script against a list of mailboxes with each result outputting to a different file?

Any suggestions appreciated. Thank you.

Glen said...

Try something like

If (( import-module -Name messageops-exchange -ErrorAction SilentlyContinue) -eq $null){
import-module messageops-exchange
}
$ewsprofile = $null


Import-Csv -Path $args[0] | ForEach-Object{
"Processing Mailbox " + $_.EmailAddress
$mailboxToAccess = $_.EmailAddress

if($ewsprofile -eq $null){
$ewsprofile = New-MessageOps.EWSProfile -identity $mailboxToAccess
}

Find-MessageOps.MailboxFolders -identity $mailboxToAccess -p $ewsprofile -MsgFolderRoot | foreach-object{
if ($_.TotalCount -gt 0){
"Processing Folder " + $_.DisplayName
$folder = $_
Search-MessageOps.CrawlMailFolder -identity $mailboxToAccess -p $ewsprofile -ewsFolder $folder -creditcard $true
}
}

}

Anonymous said...

I''ve been looking at using this as a sort of PST import/export replacement. Does Copy-MessageOps.ExportUploadMailboxFolder work on subfolders? (for example \\inbox\test) I get strange errors about folder not found, but the same code works just fine if the FolderPath is just \\inbox.

Anonymous said...

Glen
I've been trying to get this module loaded and have installed EWS Managed API 2.1. (1.1 is no longer available) and when I try to load the module using "MessageOps-Exchange-Module> Import-Module .\MessageOps-Exchange.psd1 after running the install-module.ps1 to copy the files, I get "Import-Module : Could not load file or assembly 'Microsoft.Exchange.WebServices, Version=14.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file
specified." But it doesn't tell me what file it can't find and I can't see in the DLL to try and figure it out. Does this pack of cmdlet's still work? I need to work with delegates administratively. thanks!

Todd