A long time ago Jim Martin wrote an excellent article how Exchange maps folder IDs for ActiveSync:
MVP Glen Scales wrote a script, which uses Exchange Web Service, to query a mailbox and export the information into a CSV file. Glen’s post could be found here.
Lately I had to troubleshoot Exchange ActiveSync devices and had also the need of mapping IDs to folder as the IIS logs contain only the folder IDs. Glen’s script was doing a good job, but wasn’t too user-friendly. Therefore I improved the usability and extended the ability of gathering data.
With this I was able to easily troubleshoot my devices by parsing the IIS logs with my script Get-IISStats.ps1 and the new one: Get-EASFolderMapping.ps1
Pre-requisites
In order to run the script successful, you need the following:
- You need to have Microsoft Exchange Web Services (EWS) installed
- You should have the role ApplicationImpersonation or you will need FullAccess on the mailboxes you want to scan
- the script itself, which can be downloaded here
The script
The script supports the following parameters:
Parameter |
Description |
---|---|
EmailAddress | The e-mail address of the mailbox, which will be queried. |
Credentials | Credentials you want to use. If omitted current user context will be used. |
Impersonate | Use this switch, when you want to impersonate. |
Server | By default the script tries to retrieve the EWS endpoint via Autodiscover. If you want to run the script against a specific server or endpoint, just provide the name in this parameter. Not the URL! |
TrustAnySSL | Switch to trust any certificate. |
WebServicesDLL | Path to DLL, if copied instead of installed. |
DeviceID | A string, which could be used for filtering. |
The output is similar to Glen’s script and contains the following fields:
Output |
Description |
---|---|
Mailbox | The mailbox, which was queried. |
Device | The name of the folder of the device underneath ExchangeSyncData
Note: This name is used in the parameter DeviceID for filtering. |
AsFolderPath | Use this switch, when you want to impersonate. |
AsFolderID | ActiveSync folder ID as it’s logged in the IIS logs. |
MailboxFolderPath | Absolute folder path. |
AirSyncLastSyncTimeUTC | Last time in UTC when the device synced the folder. |
AirSyncLocalCommitTimeMaxUTC | This property has the same value as PR_LOCAL_COMMIT_TIME_MAX of the synced folder |
How does it work?
As described in Jim’s article, for every Exchange ActiveSync device a folder is created in the folder ExchangeSyncData like in this example:
Each of this folders contains for each for syncing marked folder a subfolder with a number (the folder ID logged in the IIS logs) and additional system folders:
- Autod
- FolderIdMapping
- Policy
- Root
- SyncStatus
Now comes the interesting part:
Each folder contains an item with a messageclass Exchange.ContentsSyncData. We are looking for the following properties:
- AirSync:AirSyncLastSyncTime (0x81BC0014)
This property is stamped with the latest timestamp the device synced this specific folder
- AirSync:AirSyncLocalCommitTimeMax (0x81BD0014)
This property has the same value as the folder’s property PR_LOCAL_COMMIT_TIME_MAX, which contains the time of the most recent message change within the synced folder.
Now when you run the script it looks like this:
Does it work in Exchange Online?
Yes, the script supports also Exchange Online. But here things are a bit different:
There is still the folder ExchangeSyncData, which contains for each device a folder, but there are no subfolders for each synced folder. The properties are now part of items in device’s folder.
Conclusion
I would like to thank Jim and Glen for their articles, which made mine possible.
I hope this post helps you for future troubleshooting. At least for me it was a huge help gathering these information easily and within a short time.