Wednesday, February 21, 2018

Looking into the Microsoft Team's TeamChat folder in an Office365 Mailbox using EWS

If you looked at the folder structure in an Office365 Mailbox (or older Exchange Mailbox) using a MAPI editor so you could see all the Non_IPM_Subtree and hidden folders around 5 years ago it was a relatively simple picture. Today with the rapid pace of the change in Office365 its a little bit of minefield on new folders and hidden data that is stored and used by various applications in your Mailbox. A good case in point is the Files Hidden folder which Tony explains about in . Microsoft Teams is the new kid on the block in terms of collaboration applications that integrate into Mailboxes and other Office365 workloads. As you chat using the Microsoft Teams client as part of it compliance/discoverability process associated with Microsoft Teams a cloud-based process creates conversation items in a Hidden folder in your Office365 Mailbox called TeamChat (this is a Subfolder of the Conversation history). Because its a hidden folder users won't be able to see the content but the data stored is searchable (at the time of writing this there is very little official documentation that I can find Tony's post and a few other forum posts give the best guide to what this is and how it works).

So because this is a hidden folder using the new Graph API won't work (although you can actually get to the Items using the Graph API by searching) so using EWS is the best approach for now as it gives the most flexibility if you want to start playing around with this data programmatically.

Binding to the folder in EWS

You could use a few different ways to get the TeamChat folder the approach I've used is to make use of the Extended Property TeamChatFolderEntryId which is set on the Root Folder of a Mailbox. This contains the PR_EntryId of the Folder in question so once you convert this to an EWSId using the CovertId operation in EWS you can then bind directly to the folder. eg here's what the code looks like

$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)   $TeamChatFolderEntryId = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([System.Guid]::Parse("{E49D64DA-9F3B-41AC-9684-C6E01F30CDFA}"), "TeamChatFolderEntryId", [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary); $psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties) $psPropset.Add($TeamChatFolderEntryId) $RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid,$psPropset) $FolderIdVal = $null
if ($RootFolder.TryGetProperty($TeamChatFolderEntryId,[ref]$FolderIdVal))  {    $TeamChatFolderId= new-object Microsoft.Exchange.WebServices.Data.FolderId((ConvertId -HexId ([System.BitConverter]::ToString($FolderIdVal).Replace("-","")) -service $service))    $TeamChatFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$TeamChatFolderId);   } }
Once you have access to the Folder you can start pulling basic folder statistics like the Number of Items, Sizes, AttachmentCounts etc (or more interestingly things you won't be able to do using Get-MailboxFolderstatitistics). But the more interesting thing to do is to look at the data stored on the conversation items, because these aren't your normal email Messages extended properties are used to hold the different data from Teams/Skype (also the normal Attachment and recipients collections of a message are also used). There are a few properties in use (which generally aren't documented either so if your interested I would suggest taking a look yourself with a MAPI editor at a few items). But the one that is of most interest to me anyway is the SkypeMessagePropertyBag which contains a lot the Metadata from the chat message. This is a string property that contain JSON so accessing and decoding it into something usable in Powershell is pretty easy using ConvertFrom-Json.

I've put together a sample script module for accessing this folder using EWS that has a couple of different functions. The first Get-TeamChatStats accesses the folder and does some simple aggregation of folder and items properties including the ConversationId from the SkypeMessagePropertyBag  to aggregated the number of conversations.

Get-TeamChatSkypeMessagePropertyBag enumerates all the Items in the TeamChat Folder and then outputs the SkypeMessagePropertyBag to the pipeline so you can then do any of you own aggregation or investigation etc eg

My current TeamChat data is pretty simple so there could be a few bugs in these scripts due to the limited data I had to run against. I've put the code up for these script on GitHub at so fell free to log an issue you experience and I'll path the code.