In a message center post sent earlier today, Microsoft is again reminding customers to stop using the good old manage.office.com endpoint to fetch information pertaining to the Service Health Dashboard or the Message center. The cutoff date is December 17th, 2021. With only a month left, there is no news about any replacement for the Management activity API, which also uses the same (root) endpoint.
Anyway, after completing my duties for spreading the message, let’s also take a quick look at how the new ednpoints, now part of the Graph API, behave. First, a reminder on how things looked like. The example below shows a query for fetching the current status of all services, along with the output returned from the old Service Communications API endpoint:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $uri = "https://manage.office.com/api/v1.0/$tenantname/ServiceComms/CurrentStatus" $result = ( Invoke-RestMethod -Uri $uri –Headers $authHeader1 –Method Get –Verbose) $result .value FeatureStatus : {@{FeatureDisplayName=Backend Data Processing; FeatureName=Backend Data Processing; FeatureServiceStatus=ServiceOperational; FeatureServiceStatusDisplayName=Normal service}, @{FeatureDisplayName=Networking Issues; FeatureName=Networking Issues; FeatureServiceStatus=ServiceOperational; FeatureServiceStatusDisplayName=Normal service}, @{FeatureDisplayName=Sign- in ; FeatureName=Signin; FeatureServiceStatus=ServiceOperational; FeatureServiceStatusDisplayName=Normal service}, @{FeatureDisplayName=E-Mail and calendar access; FeatureName=Access; FeatureServiceStatus=ServiceOperational; FeatureServiceStatusDisplayName=Normal service}...} Id : Exchange IncidentIds : {EX295761} Status : ServiceDegradation StatusDisplayName : Service degradation StatusTime : 2021-11-04T00:31:52.803Z Workload : Exchange WorkloadDisplayName : Exchange Online |
The full output will of course contain information about all the services, each returned as separate entry, but for our purposes looking only at the status of Exchange Online will do. The corresponding Graph API endpoint is /admin/serviceAnnouncement/healthOverviews and unfortunately is a bit lighter on the details. Compared to the information in the example above, that is.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | $uri = "https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/healthOverviews" $result = ( Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose) $result .value service status id ------- ------ -- Exchange Online serviceDegradation Exchange Identity Service serviceOperational OrgLiveID Microsoft 365 suite restoringService OSDPPlatform Skype for Business serviceOperational Lync SharePoint Online serviceDegradation SharePoint Dynamics 365 Apps serviceOperational DynamicsCRM Azure Information Protection serviceOperational RMS Yammer Enterprise serviceOperational yammer Mobile Device Management for Office 365 serviceOperational MobileDeviceManagement Planner serviceOperational Planner Sway serviceOperational SwayEnterprise Power BI serviceOperational PowerBIcom Microsoft Intune serviceOperational Intune OneDrive for Business serviceOperational OneDriveForBusiness Microsoft Teams serviceOperational microsoftteams Microsoft StaffHub serviceOperational StaffHub Microsoft Kaizala serviceOperational kaizalamessagingservices Microsoft Bookings serviceOperational Bookings Office for the web serviceOperational officeonline Microsoft 365 Apps serviceOperational O365Client Power Apps serviceOperational PowerApps Power Apps in Microsoft 365 serviceOperational PowerAppsM365 Microsoft Power Automate serviceOperational MicrosoftFlow Microsoft Power Automate in Microsoft 365 serviceOperational MicrosoftFlowM365 Microsoft Forms serviceOperational Forms Microsoft 365 Defender serviceOperational Microsoft365Defender Microsoft Stream serviceOperational Stream Privileged Access serviceOperational PAM Microsoft Viva serviceOperational Viva Cloud App Security serviceOperational cloudappsecurity |
The data is all there, it just takes another query to get to all the details, namely a GET request against /admin/serviceAnnouncement/issues. As by default data for all recent incidents across all services is returned, you can use the $filter operator to get the details for particular event only (few examples included below).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $uri = "https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/issues" $uri = "https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/issues?`$filter=service eq 'Exchange Online' and status eq 'serviceDegradation'" $uri = "https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/issues?`$filter=service eq 'Exchange Online' and endDateTime eq null" $result = ( Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose) $result .value #$result.value.posts | % {$_.description.content} startDateTime : 2021-10-28T01:00:00Z endDateTime : lastModifiedDateTime : 2021-11-04T00:31:52.803Z title : Admins may be unable to view or manage users in role groups id : EX295761 impactDescription : Admins may be unable to view or manage users in role groups. classification : advisory origin : microsoft status : serviceDegradation service : Exchange Online feature : Tenant Administration (Provisioning, Remote PowerShell) featureGroup : Management and Provisioning isResolved : False highImpact : details : {} posts : {@{createdDateTime=2021-11-02T18:24:35.043Z; postType=regular; description=},...} |
I’ve trimmed the output above for the sake of brevity, but overall you should be able to see the same level of detail as exposed within the Microsoft 365 Admin portal, including Post Incident review reports (via the /admin/serviceAnnouncement/issues/{serviceHealthIssueId}/incidentReport endpoint).
Apart from SHD data, the Service Communications API covers Message center post (via /admin/serviceAnnouncement/messages endpoint). The interesting part here is that apart from allowing you to list those posts, the Graph API allows you to also perform additional operations on them. Those include Mark as Read, Archive and Mark Favorite, matching the functionality we have in the M365 admin center. Only Delegate permissions are supported for such operations though, specifically you need the ServiceMessageViewpoint.Write scope.
Some examples below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $uri = "https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/messages?`$top=1" $result = ( Invoke-RestMethod -Uri $uri –Headers $authHeader –Method Get –Verbose) $result .value startDateTime : 2020-12-09T19:58:01Z endDateTime : 2022-01-02T08:00:00Z lastModifiedDateTime : 2020-12-10T18:10:27.953Z title : Update to Microsoft 365 and Outlook for Windows connectivity id : MC229143 category : planForChange severity : normal tags : {User impact, Admin impact} isMajorChange : True actionRequiredByDateTime : 2021-11-01T07:00:00Z services : {Exchange Online, Microsoft 365 Apps} expiryDateTime : viewPoint : details : {} body : ... |
where again some of the output has been trimmed. The body of the message center post can be saved locally and visualized as follows:
1 2 | $result .value.body.content | Out-File "D:\MC229143.htm" ii "D:\Downloads\MC229143.htm" |
That’s it, in a nutshell. Another service moves to using the Graph API and leaves its roots behind. All that’s left to see is when the Management Activity API will follow. Well, and Exchange Online 🙂
I m getting this error :
VERBOSE: GET https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/healthOverviews with 0-byte payload
Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
At line:1 char:12
+ $result = (Invoke-RestMethod -Uri $uri -Headers $authHeader -Method G …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
You need to pass a valid access token as part of the request, the examples above don’t cover that part. Just use your preferred method for obtaining a token and set the $authHeader variable accordingly.