Query Office 365 Service Communication API

Recently I had the need to gather some detailed information about an ongoing service degradation.

I remebered fellow MVP Vasil Michev and his blog post here. I like the fact that we now have an insight how many users are affected.

MVP Frank Carius wrote a more detailed post about the API here.

You can find more about Office 365 Service Communications API here:

But as I’m very lazy and I don’t want to run all the steps each time, I wrote and added a function to my PowerShell $PROFILE.

As I have a PowerShell anyways open, the function is loaded automatically and I can just run it when needed.

How it works?

The function has only two parameters:

  • Credential:

The credential for your tenant

  • ClearCookie:

A switch to clear the existing cookie

I’m calling the function and store the retrieved data in the Variable $Events:

$Events=Get-ServiceHealthDashboard -Credential ingo@thecluelessguy.de -Verbose

SHD01.PNG

SHD02.PNG

You might notice the output:

“No O365cookie exist! Need credentials!”

This is because the function stores the retrieved cookie into a global variable to reuse it in this PowerShell session later. This is described in the post:

“The cookie above can be stored as an alternative in storing your username & password credentials. You can use the cookie to authenticate to the API for future requests without having to call the Register method again. The cookie is only valid for 48-hours, but a new cookie is provided every time a method is ran on the API, theoretically making it possible never to have to use the actual Office 365 credentials more than once.”

The next time you call the function it will detect it and no credentials are needed:

$Events=Get-ServiceHealthDashboard -Verbose

SHD03.PNG
By using the switch you can delete the cookie and force a prompt for credentials.

$Events=Get-ServiceHealthDashboard -Verbose -ClearCookie

On purpose I entered wrong credentials and the error will be shown as expected.
SHD04.PNG

After I entered the correct credentials, I retrieved the current status:

SHD05.PNG

And here is the function

function Get-ServiceHealthDashboard
{
  [CmdletBinding()]
  [OutputType([PSObject])]
  Param
  (
    [Parameter(Mandatory=$false,
        ValueFromPipelineByPropertyName=$false,
    Position=0)]
    [PSCredential]$Credential,

    [Parameter(Mandatory=$false,
        ValueFromPipelineByPropertyName=$false,
    Position=1)]
    [switch]$ClearCookie
  )
  Begin
  {
    If(!($PSVersionTable.PSVersion.Major -ge 3)){
      Write-Output "Sorry, PowerShell version 3.0 or above is required!"
      break
    }
    function Get-Error {
      Param(
        [Management.Automation.ErrorRecord]$e
      )
      Begin
      {}
      Process
      {
        $info = [PSCustomObject]@{
          Exception = $e.Exception.Message
          Reason    = $e.CategoryInfo.Reason
          Target    = $e.CategoryInfo.TargetName
          Script    = $e.InvocationInfo.ScriptName
          Line      = $e.InvocationInfo.ScriptLineNumber
          Column    = $e.InvocationInfo.OffsetInLine
        }
      }
      End
      {
        return $info
      }
    }
    If($ClearCookie){
      Remove-Variable -Scope global -Name O365cookie -ErrorAction SilentlyContinue
    }
  }
  Process
  {
    # check if cookie exists and prompt for credentials if not
    If(!($global:O365cookie)){
      Write-Verbose -Message "No O365cookie exist! Need credentials!"
      If(!($Credential)){
        $Credential = $host.ui.PromptForCredential('Office 365 Credentials', 'Please Enter Your Office 365 Credentials','','')
      }
      # create json payload
      $O365jsonPayload = (@{userName=$Credential.username;password=$Credential.GetNetworkCredential().password;} | convertto-json).tostring()
      # retrieve cookie
      try{
        $Registration= invoke-restmethod -contenttype "application/json" -method Post -uri "https://api.admin.microsoftonline.com/shdtenantcommunications.svc/Register" -body $O365jsonPayload -ErrorAction Stop
        $global:O365cookie = $Registration.RegistrationCookie
      }
      catch{
        # get error record
        Get-Error -e $_
        break
      }
      $O365jsonPayload = (@{lastCookie=$global:O365cookie;locale="en-US";preferredEventTypes=@(0,1,2)} | convertto-json).tostring()
    }
    Else{
      Write-Verbose -Message "O365cookie exist! Create JsonPayload"
      # insert cookie into payload
      $O365jsonPayload = (@{lastCookie=$global:O365cookie;locale="en-US";preferredEventTypes=@(0,1)} | convertto-json).tostring()
    }
    try{
      # get events
      $events = (invoke-restmethod -contenttype "application/json" -method Post -uri "https://api.admin.microsoftonline.com/shdtenantcommunications.svc/GetEvents" -body $O365jsonPayload)
    }
    catch{
      # get error record
      Get-Error -e $_
    }
  }
  End
  {
    return $events.Events
  }
}

Nothing special, but handy!

Leave a comment