Tips for Working with the Graph Usage Reports API

Understanding What the Graph Usage Reports API Generates

Last month, I discussed a new version of the Microsoft 365 user activity report based on the 180-day lookback period now supported by the Graph usage reports API. This provoked some questions about the API that are worth clarifying.

Single Point of Reference for Reports

Microsoft 365 administrative interfaces (like the Teams admin center) generate their usage reports from the data retrieved via the API. The API is a single point of contact for any usage report found inside Microsoft 365. This used not to be the case, but it is now. The Teams admin center currently limits reports to the previous 90 days while the Microsoft 365 admin center supports 180 days.

Concealing Display Names

Because the API is used everywhere, the setting to conceal user, group, and site display names available in the Reports section of Org Settings in the Microsoft 365 admin center controls all data retrieved with the API, including any reports that you create. If you want to see display names in usage data, the setting to obfuscate this information must be turned off (Figure 1).

Setting the concealed display names option for the Graph usage report API
Figure 1: Setting the concealed display names option for the Graph usage reports API

Teams was the last workload to apply concealment to usage data. All workloads that generate usage data now support this feature.

Switching Concealment On and Off

In a script, you can check if concealment is active and disable it temporarily to allow display names to be fetched using the Graph Usage Reports API. For example:

# first, find if the data is obscured
$Display = Invoke-MgGraphRequest -Method Get -Uri 'https://graph.microsoft.com/beta/admin/reportSettings'
If ($Display['displayConcealedNames'] -eq $True) { # data is obscured, so let's reset it to allow the report to run
   $ObscureFlag = $True
   Write-Host "Setting tenant data concealment for reports to False" -foregroundcolor red
   Invoke-MgGraphRequest -Method PATCH -Uri 'https://graph.microsoft.com/beta/admin/reportSettings' -Body (@{"displayConcealedNames"= $false} | ConvertTo-Json) }

To reverse the process, update the setting to True:

# And reset obscured data if necessary
If ($ObscureFlag -eq $True) {
   Write-Host "Resetting tenant data concealment for reports to True" -foregroundcolor red
   Invoke-MgGraphRequest -Method PATCH -Uri 'https://graph.microsoft.com/beta/admin/reportSettings' -Body (@{"displayConcealedNames"= $true} | ConvertTo-Json) }

Teams Data Needs Interpretation

If you look at the information returned by the Graph Usage Reports API for Teams usage, the activity level reported for teams needs some interpretation. For instance, here’s some information I extracted for the team we use to manage the Office 365 for IT Pros eBook. I used a 180-day lookback to extract the data with this script.

Name            : Ultimate Guide to Office 365
LastActivity    : 2022-09-06
AccessType      : Private
Id              : 33b07753-efc6-47f5-90b5-13bef01e25a6
IsDeleted       : False
ActiveUsers     : 17
ActiveExtUsers  : 7
Guests          : 8
ActiveChannels  : 11
SharedChannels  : 1
Posts           : 51
Replies         : 511
Channelmessages : 674
Reactions       : 241
Mentions        : 185
UrgentMessages  : 0
Meetings        : 0

The report data shows that:

  • The last activity noted for the team was September 6, 2022. The usage report data is always a couple of days behind.
  • The team has private membership and is not deleted. Usage data includes deleted teams that have logged some activity within the lookback period.
  • The number of active users is 17. However, the team has 2 owners and 9 members, so this figure is odd.
  • The number of active external users is 7. This matches the 7 guest members in the team.
  • The number of guest accounts is 8. Currently, the team has only 7 guests, but a team owner or administrator could have removed a guest account during the lookback period. The shortest lookback period is 7 days. When I use this to query the usage data, it reports 7 guests.
  • The number of active channels is 11. There are currently 10 channels in the team plus one deleted channel. Deleted channels remain available for restore for a 21-day period. In this case, the deleted channel is a shared channel that I deleted many months ago, so that’s worth investigating. The Graph API for channels doesn’t list deleted channels, so I can’t check its deletion status or deletion date. What’s also weird is that no audit records exist for the deletion of this channel…
  • There is one other shared channel in the team.

Message Counts are Even More Confusing

The data reported for message volume within a team is where things get interesting. The numbers of reactions and mentions are easy to understand (and you can validate the reactions number through audit records). Things are less clear with posts, replies, and channel messages. The Microsoft 365 admin center avoids confusion by only reporting the count of channel messages (674). The Teams admin center reports posts (51), replies (511), and channel messages.

According to Microsoft documentation, “Channel messages is the number of unique messages that the user posted in a team channel during the specified time period.” I think the reference to “the user” should be “users” as this makes more sense. However, adding posts and replies only gets me to 562, which is 122 less than the channel message count. Reactions could be considered as a form of reply, but 241 reactions is more than the 122 gap, so there’s a mystery as to how Microsoft calculates the number of channel messages.

The counted messages include only those posted by users. They don’t include messages posted by applications or those that come through the inbound webhook connector.

The Groups and Teams activity report script reads the usage data for a team to know if it is active or potentially obsolete. In that instance, a precise measurement of message activity isn’t a real problem because we accept that if a team has some messaging activity it’s not obsolete. However, if you’re interested in tracking the exact number of messages generated per team, it’s best to use the total of posts and replies.

Seeking Understanding from the Graph Usage Reports API

The old rule applies of not accepting data until you understand its meaning. It’s nice that Teams usage data is available for tenants to browse and download. It would be even nicer if the meaning of the data was clearer.


Learn how to exploit the data available to Microsoft 365 tenant administrators through the Office 365 for IT Pros eBook. We love figuring out how things work.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.