Get Latest Office 365 Service Status with Flow or PowerShell

With the recent high-profile outages within Office 365 and the ever reliance on Office 365, it’s always good to stay up-to-date with any potential issues.

There are lots of ways to check the status of Office 365 - the Office 365 portal, Twitter accounts etc. However, what I was after was an automated way of checking for issues and letting me and the team at Symity know about them ASAP (so we can look to mitigate impact) - rather than happening to come across it, or worse users noticing and informing us.

Doing a quick Google Bing, I came across a REST API for reporting the latest Office 365 status of a tenant - it is called the “Office 365 Service Communications API” - a bit of a mouthful.

Note: This API is in preview, so may be subject to change.

A cursery glance at the API looks like it will fit the bill. Now, at this stage I could use PowerShell or some other scripting language, but why not use Flow?

Create an Azure AD Application

As you will need to query the status of your tenant directly, you need to be able to authenticate with it. To do this, you will need to create an Azure AD application.

To create an Azure AD application login to https://portal.azure.com and navigate to Azure Active Directory. From here, select App registrations.

Select New registration and give your application a Name and Supported account type. In my case, I only want to allow accounts from my Azure AD to authenticate using the application. Leave Redirect URI blank (for now) and select Register.

The application will now get created. Make a note of the Application (client) ID and Directory (tenant) ID as these will be needed later. Next, you need to specify a Redirect URI to use for the application. Select Add a Redirect URI from the application page.

I’ve tended to select https://login.microsoftonline.com/common/oauth2/nativeclient as the Redirect URI, but any can be used I believe. Whatever you use, make a note of it for later.

The next step is to create an application secret. The secret is used when authenticating with Azure AD - it is similar to a password. From within the application page, select Certificates and secrets and select New client secret.

Give the secret a **Description **and set an **Expiry **on the secret.

IMPORTANT: Copy the secret and put it somewhere secure, as once you click away, it will be hashed out and you’ll need new one.

This application will now need some permissions assigned to it to read the Office 365 service status. Under the application, select API permissions and then select Add a permission.

To complete, permissions you need to Grant Consent for the permissions by selecting Grant admin consent.

With that done, you are ready to query using the Azure AD application.

What can you query?

Before I go into the specifics of Flow or PowerShell, I want to explain the data that can be gleaned from the REST API. Dependant on what URL you use to query depends on what data is returned. A full list including all parameters can be found here: https://docs.microsoft.com/en-us/office/office-365-management-api/office-365-service-communications-api-reference

Some examples are:

Query Description
https://manage.office.com/api/v1.0/{tenant_identifier}/ServiceComms/Services Returns the list of subscribed services
https://manage.office.com/api/v1.0/{tenant_identifier}/ServiceComms/CurrentStatus Returns the current status of the service.
https://manage.office.com/api/v1.0/{tenant_identifier}/ServiceComms/HistoricalStatus Returns the historical status of the service, by day, over a certain time range.
https://manage.office.com/api/v1.0/{tenant_identifier}/ServiceComms/Messages Returns the messages about the service over a certain time range.

Whilst it’s great you can go back and look at historical status, this post is about the latest status, so I can going to use the Current Status query.

Querying using PowerShell

The following script will return the current status of each service on Office 365 for a given tenant. You will just need to populate the Azure AD application/client id, client secret and tenant id.

This script will get an OAuth token from Azure AD and with that token query the Office 365 API for the latest servie status. You can of course tweak the script to do something with the output e.g. send an email if a service is not under “Normal service”.

Querying using Flow

PowerShell is just one of a multitude of ways of querying this API, another is Flow.

I’ve already covered flow before, in more detail, so will keep it brief here.

Create a new flow and in this case, the trigger will be a scheduled re-occurrence.

The next step is to initalise 3 variables, these are the Azure AD application client id, client secret and tenant id.

After that, you need to create an HTTP action to query the Office 365 API. Populate the same as below, making sure all 3 variables are used.

If you were to run the flow at this point it would return a big output of JSON. It’s best to use the Parse JSON action to make it easier to read. Set the Content as the Body of the previous HTTP action and the Schema below:

{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "value": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "FeatureStatus": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "FeatureDisplayName": {
                                    "type": "string"
                                },
                                "FeatureName": {
                                    "type": "string"
                                },
                                "FeatureServiceStatus": {
                                    "type": "string"
                                },
                                "FeatureServiceStatusDisplayName": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "FeatureDisplayName",
                                "FeatureName",
                                "FeatureServiceStatus",
                                "FeatureServiceStatusDisplayName"
                            ]
                        }
                    },
                    "Id": {
                        "type": "string"
                    },
                    "IncidentIds": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "Status": {
                        "type": "string"
                    },
                    "StatusDisplayName": {
                        "type": "string"
                    },
                    "StatusTime": {
                        "type": "string"
                    },
                    "Workload": {
                        "type": "string"
                    },
                    "WorkloadDisplayName": {
                        "type": "string"
                    }
                },
                "required": [
                    "FeatureStatus",
                    "Id",
                    "IncidentIds",
                    "Status",
                    "StatusDisplayName",
                    "StatusTime",
                    "Workload",
                    "WorkloadDisplayName"
                ]
            }
        }
    }
}

Once the data has been parsed, you can loop through each service and check for service status. The next action is to add an Apply to each action for the value variable.

Within the loop, add a Condition that Status is not equal to ServiceOperational.

Under the If yes condition, you can add an action because the service is not operational. To demonstrate, I’ve sent an email, but you may want to do something else.

This should then be triggered when there is a service degraded within Office 365. If you are going to use this to be alerted you may want to add some extra logic to group all affected services into one email, or perhaps only have the flow trigger on new action to avoid getting spammed with the same alerts (this would rely on persistence between flow runs, so perhaps somewhere external to store the last status and compare to current).