Forum Discussion
Using PowerShell to talk to the Office 365 Service Communications API
I want to use PowerShell to export the most recent week's worth of Admin Message Center Messages to a spreadsheet because I want to annotate each item with what I am planning to do about each announcement. #Governance
I have an account for this purpose that is a global tenant admin and that does not use MFA.
I believe I need to use the O365 Service Communication API (Preview) as described at https://msdn.microsoft.com/office-365/office-365-service-communications-api-reference, in particular with this REST URI: https://manage.office.com/api/v1.0/contoso.com/ServiceComms/Messages
In PowerShell, there is the Invoke-RestMethod command.
I'm passing the above URI (except with contoso.com replaced) for the value of the -URI parameter.
However, for authentication, passing a Credential doesn't work. I need to create an Authorization Header with a value of Bearer and an AAD_Bearer_JWT_Token.
I'm lost when it comes to creating that.
Do I really need to set up an Application listing in Azure Ad for my PowerShell script, per https://msdn.microsoft.com/en-us/office-365/get-started-with-office-365-management-apis ?
If so, beside the UI of the management portal having been redone, I don't see the Service Communication APIs being listed as an option when I am supposed to grant the application permission to access them.
Can anyone shed some light on this?
paulschaeflein Dean_Gross Anna Chu Todd Klindt Anne Michels Peter Walke
19 Replies
- Josh BiddleCopper Contributor
I created a script to query the old API (before I knew there was a new one). It works for the most part. I send 22 variables back to my RMM (N-Central) to use as an alerting tool. I haven't turned alerting on for it yet because I've still been testing it for the most part. The one thing I have noticed is that sometimes the messagetext does not always show what it should. It should show messagetext[0] which would correspond to the last message posted for the service, but sometimes it get skewed. I'm leaning towards this being an anomaly in the method Microsoft uses to post the messages. I've spent all night tonight (8+ hours) and an equal amount of time other nights trying to figure out how to port this to the new API but I keep coming up short. So far the closest I have come is by using the Exch-REST module and using the Get-EXRMSubscriptionContentBlob cmdlet. See below.
$tenantGUID = "YOURTENANTID"
$test = Get-EXRMSubscriptionContentBlob -ContentURI "https://manage.office.com/api/v1.0/$tenantGUID/ServiceComms/Messages"
# This will net you almost what $Events will from the O365ServiceCommunications module$test.value | ? {$_.WorkloadDisplayName -ne $null} | FT ID,WorkloadDisplayName,StartTime,EndTime,LastUpdatedTime,Status
$test.value.messages.messagetextHere is the code for the script for the previous API. Let's keep this thread going. I'd really like to crack the mystery of API v2. :)
PS: To get the pertinent data from the script you'll want to return $service and $servicemsg for each of the services - these are the variables I am sending back to my RMM.
Cheers,
Josh
PSS: Here are some notes on how to create the Azure App and obtain the oAuth token.
https://docs.microsoft.com/en-us/office/office-365-management-api/
Follow instructions here to create Azure App for Certificate Secret key: https://docs.microsoft.com/en-us/office/office-365-management-api/get-started-with-office-365-management-apis
Here's a video outlining some of the process: https://www.youtube.com/watch?v=WygwzN9FfMQ
# Create certificate, then Export .cer via MMC > Certificates Snap-In > My User Account
$cert = New-SelfSignedCertificate -Type CodeSigningCert -KeySpec Signature `
-Subject "E=my@email.com,CN=My Name" -KeyExportPolicy Exportable `
-HashAlgorithm sha256 -KeyLength 2048 -NotAfter ((Get-Date).AddYears(10)) `
-FriendlyName "Company Name Office 365 Service Communications API" `
-CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign# Get values to create oAuth token
$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import("C:\Users\xxxx\xxxx\O365CommAPI.cer")
$bin = $cer.GetRawCertData()
$base64Value = [System.Convert]::ToBase64String($bin)
$bin = $cer.GetCertHash()
$base64Thumbprint = [System.Convert]::ToBase64String($bin)
$keyid = [System.Guid]::NewGuid().ToString()
Error updating manifest?:
"Failed to save manifest. Error details: KeyValueMustBeNull"
https://social.msdn.microsoft.com/Forums/en-US/0e88e784-5e5b-496f-b554-0935ab34b440/cannot-update-keycredential-value-in-azure-application-manifest?forum=WindowsAzureAD
"because the key is already stored. If you go to "Settings -> Keys" and remove the public key stored here it is possible to update it again."
# Create app of type Web app / API in Azure AD, generate a Client Secret, and update the client id and client secret here
$ClientID = "xxxx"
$ClientSecret = "xxxx"
$loginURL = "https://login.microsoftonline.com/"
$tenantdomain = "xxxx"
# Get the tenant GUID from Properties | Directory ID under the Azure Active Directory section
# https://docs.microsoft.com/en-us/onedrive/find-your-office-365-tenant-id
$TenantGUID = "xxxx"
$resource = "https://manage.office.com"
# auth
$body = @{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-version=1.0 -Body $body
$headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}I'm not exactly sure what to do once you have the token, but this is where I left off - also using the Exch-REST module I was able to somewhat replicate the data obtained from the O365ServiceCommunications module. Was anyone able to make it any further?
- Sirbuland_KhanCopper Contributor
Hello Everyone
I'm new to the community. But if you are still looking for something production ready. I just pushed a solution for this to my Git repo. You can find it here https://github.com/KDebugMan/O365ServiceHealthStatusAlert
Open for feedback and comments.
Cheers,
Khan
- Anne Michels
Microsoft
Hi Michael,
The v2 API (preview) requires that you register the script/app. One immediate term option is to use the non-preview v1 API. Sample code may be found here (download the zip file and look inside the Word document). Also follow along with this blog series for additional code samples that are forthcoming.
Thanks,
Anne
- Brian TeerlynckCopper Contributor
Hello Anne,
I'm using powershell to contact the service communication API's (connecting via the azure app)
Now i am able to get data from the API's but i want to set a filter that returns only data from a specific time. Do you have an idea how this filter should be built?
Get Messages
Description:
Returns the messages about the service over a certain time range. Use the type filter to filter for "Service Incident", "Planned Maintenance", or "Message Center" messages.
Service DescriptionPath /Messages Filters StartTime Filter by Start Time (DateTimeOffset, default: ge CurrentTime - 7 days). I'm trying to create this uri with above filter:
"https://manage.office.com/api/v1.0/$tenant/ServiceComms/Messages?$filter=StartTime ge 'CurrentTime - 2 days'"
Source:
https://msdn.microsoft.com/en-us/office-365/office-365-service-communications-api-reference
Thanks in advance!
Brian
- Dean_GrossSilver Contributor
Brian Teerlynckdid you ever figure out how to get this type of filter to work? or how to get just the messages from the Message Center?
There's a working example here: https://blogs.technet.microsoft.com/cammurray/2014/09/23/using-powershell-to-obtain-your-tenants-office365-health-dashboard/
To get the message center events, use event type 2.
Vasil, thanks for pointing me to that. One thing that concerns me about that example is that it is using the old version of the API. Note the command to get the cookie:
$cookie = (invoke-restmethod -contenttype "application/json" -method Post -uri "https://api.admin.microsoftonline.com/shdtenantcommunications.svc/Register" -body $jsonPayload).RegistrationCookie
It uses the old URI. The documentation for the old API is at https://msdn.microsoft.com/en-us/library/office/dn776043(v=office.15).aspx and says "A new version of the Office 365 Service Communications API has been released in preview mode. It is recommended that new applications be built using this version. For more information, see Office 365 Service Communications API reference (preview)."
How would I do the registration step with the new API? I don't see a Register method listed for the new API.
Michael
- cammurray
Microsoft
I wrote the article that was originally referenced. It hasn't been updated for sometime.
The new Service Communications API appears to be in preview at this stage, but it's probably a good idea for me to get my article updated, i'll endevour to do that this week some time.
All the information on the new API appears here: https://msdn.microsoft.com/office-365/office-365-service-communications-api-reference
I would probably suggest using MSAL libraries this time around to simplify the obtainment of a token.