Getting SHD details via the Office 365 Management API in PowerShell

The Service Health Dashboard (SHD) is one of the important resources that most Office 365 administrators keep an eye on, as it should inform us about any ongoing issues with the service. Having to login to the Admin portal in order to access the SHD information is hardly convenient though, and despite numerous requests from customers, Microsoft is yet to provide any email notifications for Incidents and Advisories. Moreover, the RSS feed that was available as part of the old Admin portal has been deprecated and instead admins were advised to use the Service Communications API.

The Office 365 Service Communications API allows admins and partners to retrieve SHD and Message center information by means of querying the corresponding service, running at the following endpoint: It is fairly straightforward to use and easy enough to automate. For example, it takes just few lines of code in PowerShell to query the current information:

$cred = Get-Credential

$jsonPayload = (@{userName=$cred.username;password=$cred.GetNetworkCredential().password;} | ConvertTo-Json).tostring()

$cookie = (Invoke-RestMethod -contenttype "application/json" -method Post -uri "" -body $jsonPayload).RegistrationCookie

$jsonPayload2 = (@{lastCookie=$cookie;locale="en-US";preferredEventTypes=@(0,1,2)} | ConvertTo-Json).tostring()

$events = (Invoke-RestMethod -contenttype "application/json" -method Post -uri "" -body $jsonPayload2 -Verbose)

$events.Events | ogv

Simple enough, right? In 2016 however, Microsoft announced plans to merge the Service Communications API into the Office 365 Management APIs, in an effort to provide a single platform to get all the service communications, security, compliance, reporting, and auditing data in Office 365. The new API functions similarly to the Graph API or any of the other Microsoft services’ APIs. Without going into too much detail, in order to start using the Office 365 Management API, one needs to register an application in Azure AD, consent to the application, giving it permissions to perform various tasks in the directory, and then assign it to users or generate a client secret to use instead of users’ credentials. The process is explained in detail here:

Once you have registered the application in Azure AD, thus granting it access to read the SHD information for your tenant, you can start using it in your custom apps or PowerShell. Using a client secret is usually more convenient when automatic tasks, but let’s see how a user can query the SHD in PowerShell using the new API. Again, the example below assumes that you have already registered and consented to the application.

First of all, you will need to obtain an access token for the application and for that you will need the ADAL binaries. Every recent version of the different Office 365 PowerShell modules includes them, so you should not need any separate installs. For example, you can load the needed DLL from the Azure AD PowerShell module:

Add-Type -Path 'C:\Program Files\WindowsPowerShell\Modules\AzureAD\\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'

Now, depending on the version of the ADAL binaries used, there might be a slight variation in the method used to obtain access tokens. The following should work with the above version:

$tenantname = ""

$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList "$tenantname"

$plat = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters -ArgumentList "Auto"

$authenticationResult = $authContext.AcquireTokenAsync("", "b11e0fdc-148a-adbe-3596-ad3ab8e4db00", "http://localhost/EWShax",$plat);

In other words, we are using the AcquireTokenAsync method that will prompt for username and password: AcquireTokenAsync(string resource, string clientId, uri redirectUri, Microsoft.IdentityModel.Clients.ActiveDirectory.IPlatformParameters parameters)

Once you execute the above code, the familiar ADAL dialog should appear and allow you to enter username and password, as well as perform any form of 2FA. The important details as follows: enter your tenant’s default domain in order to build the correct authentication context object, use “” as the resource string, provide the applicationID for the Azure AD app you registered above for the clientID, and any of the returnURIs configured for the app. The $authenticationResult variable will hold the result of the method call and assuming everything worked OK, the access token we need will be contained in the $authenticationResult.Result.AccessToken property. Alternatively, you can simply obtain it from the token cache:



$cache = [Microsoft.IdentityModel.Clients.ActiveDirectory.TokenCache]::DefaultShared


Once we have the access token, we can build the authorization header which we will then pass to any calls of the Invoke-RestMethod cmdlet:

$authHeader = @{


'Authorization'="Bearer $(($authContext.TokenCache.ReadItems() | ? {$_.Resource -eq ""}).AccessToken)"


We are now ready to fetch the Management API data. There are four operations available (Get Services, Get Current Status, Get Historical Status, Get Messages), as detailed here:

For example, to get the current status, we can use:

$uri = "$tenantname/ServiceComms/CurrentStatus"

$result = (Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose)

$result.value | ogv

And that’s pretty much it, the only other thing to explore is how to properly format the output. Querying the /Messages endpoint seems to be a convenient way to get all the information in one place, as it includes all the “Service Incident”, “Planned Maintenance”, or “Message Center” messages. But if you are interested in the (current or historical) status or particular service the other endpoints come handy too. And for a fully automated solution, you might consider using the /Services endpoint to scope down the output to just services available in the current tenant.

This entry was posted in Office 365, PowerShell. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *