Wednesday, June 13, 2018

Using the Office 365 Management Activity API from Powershell to audit Exchange and Office365

The Office 365 Management Activity API is a REST endpoint that can be used to access audit events from user, admin, system, and policy actions and events in Azure and Office365 workloads (its been around for a while first appeared in 2015 in preview). Within Office365 there are many ways of accessing this type of information the Primary UI these days for looking at auditing is the Unified Audit logs available in the Office365 Portal

The advantage of using the Management Activity API over the portal is that  allows you to create more tailored reporting by accessing the raw data over a period of time (so writing your own user trend reporting) using a scalable API like REST (which if you have a lot of data to query is superior to using WinRM solutions using something like the Exchange Management Shell cmdlets). It also includes WebHooks interfaces that can be used to trigger other workloads to process particular Audit events on a continuing basis. (Although you should note the documentation states that this API isn't meant to be used for real time alerting as there are other Microsoft provided endpoint and services to provide this functionality).
How it works

The Management Activity API uses a subscription based approach, the mechanics are relatively simple eg 

  • You create a Subscription for the Workload you want to access the Audit event for.(eg Exchange)
  • The backend then produces contentblobs which are aggregates of those audit logs and then makes them available to access. If you have registered a WebHook for your subscription then your endpoint will be notified that there is a new ContentBlob available for you to process.
  • Once you no longer require the subscription you can then Stop that subscription.

One point to note is that the Management Activity API doesn't actually enable auditing for any of the workloads it just make available data from the Auditing that is already enabled. Eg for instance Exchange Mailbox Auditing isn't turned on by default so if you did the above process to create a subscription for Exchange you would never see any ContentBlobs generated for Mailbox Auditing events unless you first went and enabled auditing on the Mailboxes you wish to audit and then these events would be available within your subscription. This is the same for other workload as well, some workloads like AzureAD have some auditing enabled by default but you should always check your auditing configuration to make sure you have turned on the particular auditing setting for the particular workload your interested in before using this API.


With the Management Activity API the subscription mechanism has the ability to send a WebHook notification to any Webhook endpoint you configure. One easy to use webhook example is Azure RunBooks so using something like this your subscription could trigger a RunBook which would then process the ContentBlob that has just been made available and apply any Logic or custom report you need. The good thing with RunBooks is all the underlying service parts of the code are done for you and you can just plug in your custom script to do what you need.


The prerequisites for this API is that you need to have an Application registration see created that has been  given the oAuth Grants to access the API. You need to generate your access tokens for the resource url (so for example you can't use a token you have generated against the Graph endpoint you need to specifically request this ResourceURL). The last thing is the Account you then use to the access the API needs to have rights to the Audit data. (If you choose to use certificate authentication and a daemon type app this would get the rights through the different oAuth Grants for applications).

Putting it to use

A really straight forward way of using this API from PowerShell is to make use of Invoke-WebRequest and there is a good document here on doing this . Another easier and more functional approach is to use my Exch-REST module which is available from the PowerShell Gallery and GitHub which now has some cmdlets and plumbing to enable use of this API. The module can now handle caching tokens from multiple resources (eg the Graph and Management API) so you can then combine operations from both API's which is where you can then start to build more powerful tailored reports. Eg if your processing the Content Blobs for particular Mailboxes and you want more information about that mailbox to include in a report you can use the Graph to easily access that. Or if you wanted to check on a Message that was deleted by a user to see if it had any attachments that could contain sensitive content you could use the Graph API to reach into the Mailbox and access the deleted message from the Recoverable Items folders etc.

Using Exch-REST to create and access subscription content

Connecting and Generating the Access Token 

To Connect and generate an Accesstoken to use against the Management API use Connect-EXRManagementAPI

I've created a default app registration that you can use for testing (number 5) that just has access to the Management API Oauth Grants but would recommend as usually that you create your own App registration  see so you control what rights the code will have. One other important thing to note is the subscription are per appid, so if you create a subscription with say the above AppId and then create your own ApplicationId at a later point and use that you won't be able to see/view/stop the subscriptions you created with the pervious appId unless your login using that pervious ApplicationId.

Once you have a token you can then use the Management API cmdlets for example to show the current subscriptions use Get-EXRMSubscriptions

If this is the first time you are using this API it will just show a blank list. To create a new subscription use the New-EXRMSubscription cmdlet with the switch for the workload you want to use eg to create a New AzureADSubscription use the -AzureAd switch

other workload switch are

-General (other workloads like Teams are included here)

If you want to use WebHooks there are specific parameters for this that allows you to specify the necessary Webhook details.

Once you have created the subscription the content blobs don't get created straight away the documentation say that this will take about 6-24 hours for content to start to become available. Once they are available you can access them using the Get-EXRMSubscriptionContent cmdlet eg to get the Exchange content for the last 24 hours

Get-EXRMSubscriptionContent -Exchange -StartTime (Get-Date).AddDays(-1) -EndTime (Get-Date)

The data you get back for this operation contains the contenturi of the blob that you can then access using the SubscriptionContentBlob operation. I have a separate cmdlet that can be used to retrieve the blob eg

Get-EXRMSubscriptionContentBlob -ContentURI
However I found the useability of doing it this way to not be so great so I included a switch in the Get-EXRMSubscriptionContent cmdlet so you can specify to return the contentblobs eg

Get-EXRMSubscriptionContent -Exchange -StartTime (Get-Date).AddDays(-1) -EndTime (Get-Date) -returnContentBlobs
eg this will the return the contentblob with each content entry

You can then process the Contentblob property and the data within anyway you like, here is one example that produces a Client report using the client agent data for the last 24hours

$Last24Results = Get-EXRMSubscriptionContent -Exchange -StartTime (Get-Date).AddDays(-1) -EndTime (Get-Date) -returnContentBlobs
$BlobEntries = foreach($ContentEntry in $Last24Results){$ContentEntry.ContentBlob}
$BlobEntries | Where-Object{$_.ClientInfoString -ne $null} | select  CreationTime,Operation,ClientInfoString,Use rId | fl

Or you could just look at things like the MoveToDeletedItems events and get more information

Once your finished with a Subscription and you no longer want to process content blobs you can stop the subscription using Invoke-EXRMStopSubscription eg to stop the Exchange Subscription use

Invoke-EXRMStopSubscription  -Exchange

The combinations of what you can do are just limited to your own imagination or particular audit bucket you need to fill. If you have need for a developer/scripter or just someone for to help out for anything exchange/office365 related I'm available to take on work at the moment so please contact me at (nothing too big or small). I'd also be interested in hearing from any companies that want to sponsor open source projects around Exchange and Office365 development.

The Exch-REST module is available from the PowerShell Gallery and GitHub