Informing Tenants About Feature Updates

I recently wrote about the transition of the Office 365 Service Communications API to become a Microsoft Graph API and how to use the API to fetch details of service incidents. As I pointed out then, the API includes the ability to retrieve information about the service update messages Microsoft posts to inform tenants about the delivery or retirement of features. These messages show up in the message center in the Microsoft 365 admin center (Figure 1) and are a great source of information about future change.

Service update messages in the Microsoft 365 admin center
Figure 1: Service update messages in the Microsoft 365 admin center

Microsoft has done a lot of work over the last few years to improve communication with tenants. They’ve:

  • Built an integration between the Message Center and Planner to synchronize updates to Planner. Tenants can then use the tasks created in Planner to assign responsibility for managing the introduction of new features or phasing out of old features. We recommend that all tenants consider using this integration to help manage change.
  • Added extra information to the messages to highlight the affected services (like Exchange Online, SharePoint Online, and Teams).
  • Introduced better filtering capability in the Message Center.

Even so, challenges still exist in dealing with the volume of updates Microsoft introduces annually. It’s not just reading about the changes as they appear to understand how a new feature will affect users and the business, or how to manage something like the retirement Skype for Business Online on July 31, 2021. Not everyone has the time or opportunity to keep tabs on new posts in the message center, and when they do, it can be challenging to understand some of the text created by Microsoft development groups to describe what they’re doing (intelligent people aren’t necessarily great writers). Another problem is tracking the frequent slippage in dates when Microsoft predicts features will be available. While Teams is notable for the high percentage of missed dates, no workload hits all its commitments.

Custom Message Processing

Good as the Message Center is, it’s always good when you can do things your own way, and that’s why the Office 365 Service Communications API is valuable. My last article covers the basics of connecting to the API and fetching data. Here we focus on the Messages API and how to extract and manipulate service update messages with PowerShell.

I like to think of practical examples to illustrate how something works. In this case, my example is a report of the service update messages flagged for tenants to act by a certain date. For instance, Teams ceased support for IE11 after November 30, 2020. That date is long gone now but a message to remind administrators of the fact remains. You could argue that this is an example of something Microsoft should clean up; equally, you could say that it’s a prompt for tenants to move off IE11 to Edge, which is why Microsoft might have left the message in place. In any case, it’s a message with an act-by date. Looking at the message center as I write, of the 256 messages, 31 have act-by dates.

I discovered this fact by running a simple Graph query using a registered app with consent to use the ServiceMessage.Read.All permission:

$DaysRange = (Get-Date).AddDays(180)
$DaysRangeZ = Get-Date($DaysRange) -format s
$Uri = "https://graph.microsoft.com/beta/admin/serviceAnnouncement/messages?`$filter=actionRequiredByDateTime le $DaysRangeZ" + "Z"
[array]$Messages = Invoke-RestMethod -Headers $Headers -Uri $Uri -UseBasicParsing -Method "GET" -ContentType "application/json"
$Messages = $Messages.Value
Write-Host “Messages with action required by dates:” $Messages.Count

This code sets a date range to check service update messages against (I chose 180 days in the future) and sets up a query to find messages with an action required date less than the date. The code then runs the query and extracts the message data from the information the API returns. An individual message looks like:

startDateTime            : 2020-09-22T19:25:50Z
endDateTime              : 2021-09-30T07:00:00Z
lastModifiedDateTime     : 2021-05-26T19:14:18.47Z
title                    : (Updated) Microsoft Teams: meeting recordings saved to OneDrive and SharePoint
id                       : MC222640
category                 : planForChange
severity                 : normal
tags                     : {Updated message, New feature, User impact, Admin impact}
isMajorChange            : True
actionRequiredByDateTime : 2021-08-16T00:00:00Z
services                 : {Microsoft Teams}
expiryDateTime           :
viewPoint                :
details                  : {@{name=ExternalLink;
value=https://docs.microsoft.com/en-us/MicrosoftTeams/tmr-meeting-recording-change}}
body                     : @{contentType=text; content=<p>Updated May 26, 2021: To ensure the best possible experience for our users, we are delaying the mandatory move of Teams meeting recordings on OneDrive and SharePoint from July 7th to August 16th in order to ensure availability of transcript driven captions and the ability to block downloads. Please see the updated timeline below.</p>

So far, so good. We have some data, and the nice thing about having some data to play with is that we can decide how to slice and dice the information to make it more digestible for the target audience.

Let’s assume that we need to convince managers of the need to do some up-front preparatory work before Microsoft delivers new software to the tenant. Asking managers to go to the Microsoft 365 admin center isn’t feasible. In my experience, busy managers are more likely to review information if given a spreadsheet or report.

The next task is therefore to create code to loop through the message data retrieved from the Graph and generate suitable outputs. Apart from removing all the HTML formatting instructions from the descriptive text for a message, there’s no great challenge in this code. To make things interesting, I computed the time remaining between the current time and the action by date and flagged overdue items. You can download the complete script from GitHub. Figure 2 shows the HTML version of the report. The script also generates a CSV file.

Service update message data reported in HTML file
Figure 2: Service update message data reported in HTML file

Generating a Word Document

Given the flexibility of PowerShell, you could even create Word documents using message data in an approved form. Here’s some code to generate a Word document containing details of a message center notification.

$OutputWordFile = “c:\temp\” + $Message.Id + “.docx”
Write-Host (“Writing information about {0} to {1}” -f $Message.Id, $OutputWordfile)
# Define variables to use in document
$Title = $Message.Title
$Header = "Microsoft 365 Message Center Notification Requiring Action (" + $Message.Id + ")"
$Services = $Message.Services
$Description = $Message.Description
$ActionBy = $Message.ActionBy
$WebLink = $Message.Weblink

#Create a new Word document
$Word = New-Object -ComObject Word.Application
$Document = $Word.Documents.Add()
$Selection = $Word.Selection
#   $Word.Visible = $True # Uncomment if you want to see the Word document on screen

#   Format the document and set margins
$Selection.PageSetup.LeftMargin = 36
$Selection.PageSetup.RightMargin = 36
$Selection.PageSetup.TopMargin = 36
$Selection.PageSetup.BottomMargin = 36

# Insert Title
$Selection.Style = 'Title'
$Selection.ParagraphFormat.Alignment = 1
$Selection.Borders.OutsideLineStyle = 1
$Selection.TypeText("$Header")
$Selection.TypeParagraph()
 
#   Insert action by date
$Selection.Font.Size = 11
$Selection.ParagraphFormat.Alignment = 0
$Selection.TypeText("Action by date:")
$Selection.TypeText("$ActionBy")
$Selection.TypeParagraph()

#   Insert numbered list of information about the message center post
$Selection.Style = 'List Number'
$Selection.Font.Size = 11
$Selection.TypeText("Title: ")
$Selection.Font.Bold = 1
$Selection.TypeText("$Title")
$Selection.Font.Bold = 0
$Selection.TypeParagraph()
$Selection.TypeText("Affected Services: ")
$Selection.Font.Bold = 1
$Selection.TypeText("$Services")
$Selection.Font.Bold = 0
$Selection.TypeParagraph()
$Selection.TypeText("WebLink: ")
$Selection.Font.Bold = 1
$Selection.TypeText("$Weblink")
$Selection.Font.Bold = 0
$Selection.TypeParagraph()
$Selection.Style = 'No Spacing'
$Selection.ParagraphFormat.Alignment = 0
$Selection.Font.Bold = 1
$Selection.TypeText("Description: ")
$Selection.Font.Bold = 0
$Selection.TypeText("$Description")
$Selection.TypeParagraph()

#   Save the document
$Document.SaveAs([ref]$OutputWordFile,[ref]$SaveFormat::wdFormatDocument)
$Word.Quit()

Figure 3 shows an example of a Word document generated using the code.

A Word document generated by PowerShell using service message data
Figure 3: A Word document generated by PowerShell using service message data

Access Drives Innovation

The nice thing about having access to data is that innovative people will do interesting things with the data. Being able to process Microsoft 365 service update messages to extract whatever value you see in the information is goodness. The only question is how best to make use of the opportunity…

Using the Service Communications API to Report Service Update Messages

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to Practical365.com, Tony also writes at Office365itpros.com to support the development of the eBook. He has been a Microsoft MVP since 2004.

Leave a Reply