Skip to main content

Generic Toolbox script for using EWS to enumerate Folders and Items in an Exchange Mailbox

There's a old saying that a tradesmen is only as good as their tools and the same can be said for ITPro's and developers. You can save yourself a lot of time when investigating particular tasks you want a script by having something ready built that can do 90% of task at hand.  I've decided to share a script that I use quite often during the investigation phase of any EWS scripting tasks that allows you to generically grab a folder (or collection of Folders) and the Items within those folder. While this is something that can be put together quite quickly together using snippets there always tends to be extra properties that you need for different tasks so the generic script I'm showing today includes all the niceties kind of like having the right sized spanner rather the shifter.

So the script in question can be found on GitHub here https://github.com/gscales/Powershell-Scripts/blob/master/GenericFolderAndItem.ps1

So what can it do

Connect and show the properties on a Mailbox Folder eg
Invoke-GenericFolderConnect -MailboxName mailbox@domain.com -FolderPath \Inbox -Credentials $cred


So in the above example this is my Inbox, some of the extra things I've added in this script over what you would normally see in EWS is to promote the ExtendedProperties for the retentionTags,FolderSize,FolderPath and AttachmentCount to first class folder properties on the object so they are much easy to first view but to also script on top off. Eg say I only want to look at the Inbox and Subfolders of the Inbox there where larger then 10 MB I can do the following
Invoke-GenericFolderConnect -MailboxName gscales@datarumble.com -FolderPath \Inbox -Credentials $cred  -Recurse | Where-Object{$_.FolderSize -gt 10mb} | select FolderPath,FolderSize
The above examples uses the -Recurse switch parameter of the script to recurse Subfolders of the pass in folder Path you connected to and then makes use of those promoted properties using the pipeline and Where-Object in PowerShell.

One other thing I've added to the Standard EWS FolderObject is the GetLastItem ScriptMethod which does what is says by getting the last item in a folder. For example if I wanted to get the Last Item in My Inbox I could use the following


I could use this method in a recursion as well to show me all the folders in my mailbox that have received a Mail in the last week eg

Invoke-GenericFolderConnect -MailboxName gscales@datarumble.com -RootFolder -Credentials $cred -Recurse | Where-Object{$_.GetLastItem().DateTimeReceived -gt (Get-Date).AddDays(-7)} | Select-Object FolderPath,FolderSize,@{Name="DateTimeReceived"; Expression = {$_.L
astItem.DateTimeReceived}},@{Name="Subject"; Expression = {$_.LastItem.Subject}})}



Enumerating FolderItems

As I've show above getting the Last Item in a folder can be useful but a lot of the time you will want to enumerate all the Items with a folder (or a least the Top X) to do particular reporting or investigation tasks. To do you use the following generic function which will give you back all the items in the Inbox.


Invoke-GenericFolderItemEnum -MailboxName gscales@datarumble.com -FolderPath \Inbox -Credentials $creds

To  limit the results to just the top 10 items in the Folder use the -MaxCount switch eg

Invoke-GenericFolderItemEnum -MailboxName gscales@datarumble.com -FolderPath \Inbox -Credentials $creds -MaxCount 10
EWS by default only returns certain properties while doing an item enumeration (using findItems) so things like the Recipients and the Message body wont be returned by default for performance reasons. If you wanted to view these properties on a Message you could use the Load() method on the Message itself or you can use the -FullDetails Switch which will batch these operations which will make it perform better if you have a large number of items that you wish to do this on. Eg to show the last 10 messages in the Inbox with FullDetails


Invoke-GenericFolderItemEnum -MailboxName gscales@datarumble.com -FolderPath \Inbox -Credentials $creds -MaxCount 10 -FullDetails
If you want to recurse though Subfolders eg to show the top 5 messages for the Inbox and its subfolders use something like 

Invoke-GenericFolderItemEnum -MailboxName gscales@datarumble.com -FolderPath \Inbox -Credentials $creds -MaxCount 5 -Recurse | Select FolderPath,Subject
Like the Generic EWS Folder Object I've added some properties and methods that I've found useful. The first is the FolderPath which is useful when doing a recursion and reporting and I've also added one script method on objects called DownloadAttachments that will allow you to download all the attachments on an Item to the directory you pass in. eg  To download the attachments from the last item in the Inbox use


Updating your tools

Unlike like a normal spanner which is literally forged in steel this tool can be updated as you go but adding in extra properties or methods that you find useful as you go. If you find the script useful and what to share any of you updates please submit them to the GitHub repo https://github.com/gscales/Powershell-Scripts/issues 

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 Gr...

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 ...

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 ...
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.