The reality of this increase in flexibility is unfortunately an increase also in the complexity meaning that this reasonably simple VBS script becomes a little more complicated and while its possible to put together a script using SOAP strings it can be a pain to make this reusable and reliable in wide number of scenarios. To make this easier i've included the EWS routine's in a .NET class library along with a parser to write the XML RSS feed. This helper library has become a little dysfunctional and needs a clean up but it does handle the important tasks when creating a RSS feed from an Exchange Mailbox such as.
- Creating a EWS Connection and using Autodisover if needed to find the CAS URL and handle Self Signed SSL certificates if they are used.
- Implement the ability to use EWS impersonation or delegation to access another users Mailbox folder
- Use Covertid to covert the EWS ID into OWA id to be used in the RSS links
- Use FindItem , Calendar Paging and Restrictions to produce an array of items for the Feed based on Calendar or Inbox folders and a Time , Read/Unread restrictions.
- Use GetItem to get the Body of Message to include in the Description Property of a RSS feed
To use the library to create a RSS feed from powershell you basically need to first load the dll
[void][Reflection.Assembly]::LoadFile("C:\temp\EWSUtil.dll")
Then you can use the objects that are defined within this class the first thing you need to do is create a EWS connection (this is a custom class i've created within the Class library that contains a Exchange Service Binding for EWS). The parameters you pass into the object creation affect what authentication is used (eg impersonation or delegation) and also whether autodisover is used or not. I haven't included any overloads this time as i didn't really have the time so all the parameters are mandatory you just need to pass in $null if you don't want to use some. So the parameters for the EWSConnection object.
$casURL = "https://" + $servername + "/EWS/Exchange.asmx"
$ewc = new-object EWSUtil.EWSConnection("user@domamain.com",$false, "username", "password", "domain", $casURL )
- This is the email address of the mailbox you want to create the feed from.
- This is a boolean that indicates whether you want to use EWS impersonation to access the mailbox you specified in 1. If this is set to $false then delegate access is used.
- This is the username to use if you want to specify implicant credentials if you want to use the currently logged on user set this to $null
- This is the password to use if you want to specify implicant credentials if you want to use the currently logged on user set this to $null
- This is the domain to use if you want to specify implicant credentials if you want to use the currently logged on user set this to $null
- This is the URL for the CAS server to use if you set this to $null the library will try to use autodiscover to find a CAS server URL. (this isn't site aware)
$drDuration = new-object EWSUtil.EWS.Duration
$drDuration.StartTime = [DateTime]::UtcNow
$drDuration.EndTime = [DateTime]::UtcNow.AddDays(30)
The next thing you need to define is the folder you want to report on the writefeed method at the moment can only deal with Mail and calendar folders/objects well. You could use this on a public folder as well i wanted to include some easy search functions in the library to help find public folders easy (but again haven't had time). So at the moment if you want to do a pubic folder you would need to pass in the EWSID of the folder.
[EWSUtil.EWS.DistinguishedFolderIdType] $dType = new-object EWSUtil.EWS.DistinguishedFolderIdType
$dType.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::calendar
The Queryfolder class is a class that uses a finditem operation to query Folder items based on some restrictions that are determined by the parameter passed into it. This has one overload in that it allows you to either specify a normal FolderID or a DistinguishedFolderId. So the parameter for the QueryFolder class are
$qfolder = new-object EWSUtil.QueryFolder($ewc,$dType, $drDuration,$false,$true)
- The Exchange WebServices Connection (custom class from library)
- The FolderIDtype or DistinguishedFolderIdType of the folder you want to produce the feed from
- Duration for query this can be either the time period for the calendar view you want to create or the time period of inbox emails you want to display.
- Unread or Read this is only relative to Mail items if you want the feed to only show unread items in the inbox for example set this to true
- IsCalendar you need to set this to $true if you want to create a feed from a Calendar folder correctly
$wfeed = new-object EWSUtil.WriteFeed($ewc.esb,$ewc.emEmailAddress, "c:\calendarfeed1.xml", "Calendar-Feed", $servername, $qfolder.fiFolderItems)
- The Exchange WebServices Connection (custom class from library)
- The filename and path for the feed you want created
- The Title for the feed.
- The ServerName used for the Links
- The folderItems generic list
Thats pretty much it I've included two sample powershell scripts in the download as well as a compiled version of the code and the source itself if you want to do your own thing. I've put a download of the code here .
11 comments:
u are THE man!!! the new dll works great, i love the powershell way with .net
you should work for microsoft and build this stuff into exchange.
Working great for me mate.
Can I use the old style event sink or do you have something available to work with an EWS notification?
Would be great to add this onto the blog thread if you can?
Also, a precompiled version that excludes the body of the calendar item would be ideal for my scenario.
Thanks Glen
Hi John,
No I dont have any notification code for this at the moment i just use a scheduled task but an event sink would work okay if you need real time updates.
Cheers
Glen
Hi Glen, I had a look around for a transport agent for calendar events but didnt find anything.
Have you made anything before you would care to share? :)
You generally wouldn't use a transport Agent for calendar event because in the case of normal appointments no actual email is generated so no transport events would fire. If you want to look at a event type approach you need to look at using EWS notifications or look at using Event sink which have been deemphasised in 2007
Cheers
Glen
Where are the settings to determine if the body of the email is just a link or is completely listed in the rss feed?
sorry there is no option for this it will allways try and include the body if availible.
Cheers
Glen
How can you find the EWSID of a public folder?
You should be able to use something like
[void][Reflection.Assembly]::LoadFile("C:\temp\EWSUtil.dll")
$pfPublicFolderPath = "/Level 1/Level2/Level3"
$mbMailboxEmail = "administrator@domain.com.au"
$ewc = new-object EWSUtil.EWSConnection($mbMailboxEmail,$false, "", "", "","")
$parentFolder = new-object EWSUtil.EWS.DistinguishedFolderIdType
$parentFolder.Id = [EWSUtil.EWS.DistinguishedFolderIdNameType]::publicfoldersroot
$fldarry = new-object EWSUtil.EWS.BaseFolderIdType[] 1
$fldarry[0] = $parentFolder
$rfRootFolder = $ewc.getFolder($fldarry)
$rfRootFolder[0].DisplayName
$pfArray = $pfPublicFolderPath.Split("/")
$pfFolder = $rfRootFolder[0]
for ($lint = 1; $lint -lt $pfArray.Length; $lint++) {
$pfFolder = $ewc.FindSubFolder($pfFolder, $pfArray[$lint]);
}
"Folder Name : " + $pfFolder.DisplayName.ToString()
"Folder Id : " + $pfFolder.FolderID.ID.ToString()
Cheers
Glen
Hi Glen, FindSubFolder does not exist as a method of EWSConnection. Did you mean something else, or was this method lost over time?
Hi I found this updated version of EWSUtil at another location...
http://msgdev.mvps.org/exdevblog/ewsutil.zip
Post a Comment