Skip to main content

Creating an RSS Feed from a calendar or inbox folder using Powershell with an EWS helper class

A number of years ago i posted some scripts to create RSS feeds from public folders and calendar folders using Exchange event sinks and some pretty simple VBS. These scripts where pretty simple and worked pretty well and I've still got some running today. On Exchange 2007 development technologies have moved on and so its time to move these scripts along as well. The big advantage is that with Powershell, .NET 2.0 and Exchange Web Services the flexibility or what you can do and therefore what you can then leverage with the newer advances in the .NET framework offer you a pretty nice sandpit to play in.

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
These are some of the challenges to producing a usable RSS feed with Exchange 2007 and a good argument to actually use Visual Studio instead of Powershell. But this is why building your own class library can give you the best of both worlds and simplify the Powershell code you need to write. Also a library can help put this power in the hands of those sysadmin that don't want to dive into .NET coding.

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 )

  1. This is the email address of the mailbox you want to create the feed from.
  2. 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.
  3. 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
  4. 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
  5. 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
  6. 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)
If your creating a calendar feed you need to set a duration to show the appointments within.The following will create a duration object to show appointments for the next 30 days. If your creating a feed from a mail folder like the inbox you need to do the reverse of this to get the items from the last 30 day received in the inbox etc.

$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)

  1. The Exchange WebServices Connection (custom class from library)
  2. The FolderIDtype or DistinguishedFolderIdType of the folder you want to produce the feed from
  3. 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.
  4. 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
  5. IsCalendar you need to set this to $true if you want to create a feed from a Calendar folder correctly
This object will return a Generic list of mailbox items which you can then choose to either use yourself in any manner you wish or if you use it with the WriteFeed object it will generate an RSS feed file from this Generic list. Again this object has a number of parameters you need to pass to it.

$wfeed = new-object EWSUtil.WriteFeed($ewc.esb,$ewc.emEmailAddress, "c:\calendarfeed1.xml", "Calendar-Feed", $servername, $qfolder.fiFolderItems)

  1. The Exchange WebServices Connection (custom class from library)
  2. The filename and path for the feed you want created
  3. The Title for the feed.
  4. The ServerName used for the Links
  5. 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 .

Popular posts from this blog

The MailboxConcurrency limit and using Batching in the Microsoft Graph API

If your getting an error such as Application is over its MailboxConcurrency limit while using the Microsoft Graph API this post may help you understand why. Background   The Mailbox  concurrency limit when your using the Graph API is 4 as per https://docs.microsoft.com/en-us/graph/throttling#outlook-service-limits . This is evaluated for each app ID and mailbox combination so this means you can have different apps running under the same credentials and the poor behavior of one won't cause the other to be throttled. If you compared that to EWS you could have up to 27 concurrent connections but they are shared across all apps on a first come first served basis. Batching Batching in the Graph API is a way of combining multiple requests into a single HTTP request. Batching in the Exchange Mail API's EWS and MAPI has been around for a long time and its common, for email Apps to process large numbers of smaller items for a variety of reasons.  Batching in the Graph is limited to a m

Sending a Message in Exchange Online via REST from an Arduino MKR1000

This is part 2 of my MKR1000 article, in this previous post  I looked at sending a Message via EWS using Basic Authentication.  In this Post I'll look at using the new Outlook REST API  which requires using OAuth authentication to get an Access Token. The prerequisites for this sketch are the same as in the other post with the addition of the ArduinoJson library  https://github.com/bblanchon/ArduinoJson  which is used to parse the Authentication Results to extract the Access Token. Also the SSL certificates for the login.windows.net  and outlook.office365.com need to be uploaded to the devices using the wifi101 Firmware updater. To use Token Authentication you need to register an Application in Azure https://msdn.microsoft.com/en-us/office/office365/howto/add-common-consent-manually  with the Mail.Send permission. The application should be a Native Client app that use the Out of Band Callback urn:ietf:wg:oauth:2.0:oob. You need to authorize it in you tenant (eg build a small ap

How to test SMTP using Opportunistic TLS with Powershell and grab the public certificate a SMTP server is using

Most email services these day employ Opportunistic TLS when trying to send Messages which means that wherever possible the Messages will be encrypted rather then the plain text legacy of SMTP.  This method was defined in RFC 3207 "SMTP Service Extension for Secure SMTP over Transport Layer Security" and  there's a quite a good explanation of Opportunistic TLS on Wikipedia  https://en.wikipedia.org/wiki/Opportunistic_TLS .  This is used for both Server to Server (eg MTA to MTA) and Client to server (Eg a Message client like Outlook which acts as a MSA) the later being generally Authenticated. Basically it allows you to have a normal plain text SMTP conversation that is then upgraded to TLS using the STARTTLS verb. Not all servers will support this verb so if its not supported then a message is just sent as Plain text. TLS relies on PKI certificates and the administrative issue s that come around certificate management like expired certificates which is why I wrote th
All sample scripts and source code is provided by for illustrative purposes only. All examples are untested in different environments and therefore, I cannot guarantee or imply reliability, serviceability, or function of these programs.

All code contained herein is provided to you "AS IS" without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.