How to Create a Report About Teams Tags

Targeted Communications for Teams

In early 2020, Microsoft introduced Teams tags to facilitate “targeted communications.” In other words, to address subsets of the membership of a team with a @ mention when sending channel messages. The idea makes a lot of sense, especially in teams with very large memberships when @ mentioning the entire team or a channel only adds to the volume of messages that some recipients aren’t interested in or need to deal with.

The most recent change to tagging is in MC320163 (updated February 18, Microsoft 365 roadmap item 88318), which adds the option to allow team owners and members to create new tags. The update is currently rolling out.

Teams tags settings in the Team admin center
Figure 1: Teams tags settings in the Team admin center

How Much is Tagging Used?

The Office 365 for IT Pros eBook team uses Teams tags like Writers, Editors, and Guests to identify subsets of the membership. At least, we do when we remember to address messages with something like @Writers (usually the monthly reminder to get chapter updates done). Which brings me to the point that because tags are artifacts of teams, there’s no way for a tenant administrator to discover how widespread tags are across the teams in their organization.

That is, unless you use the Graph API where beta APIs are available to list the tags in a team and list the team members assigned to a tag. The latest version of the Microsoft Graph PowerShell SDK includes cmdlets to do the job (Get-MgTeamTag and Get-MgTeamTagMember), which is what I explore here.

Other cmdlets are available to create new tags or assign a tag to a team member (New-MgTeamTagMember). For example, this command adds a tag to a team member. The parameters are the group identifier, Azure AD user account identifier, and the tag identifier (as returned by Get-MgTeamTag).

New-MgTeamTagMember -TeamId $TeamId -TeamworkTagId $TagId -UserId $MemberId

Graph Permissions

As you might know, the Microsoft Graph supports two types of permission: delegated and application. Delegated permissions operate as if a user is performing the action, so the data available to that action is limited to whatever the user can access. Application permission allows access to data across the tenant. However, when you sign into an interactive Microsoft Graph PowerShell SDK session by running the Connect-MgGraph cmdlet, some applications restrict access to data as if you use delegated permission. In this instance, if you run Get-MgTeamTag against a team your account is a member of, the cmdlet returns details of the tags. However, if you run Get-MgTeamTag against a team you don’t have membership of, the cmdlet returns nothing.

The solution is to create an Azure AD registered application, assign it the necessary application permission (TeamWorkTag.Read.All), and upload a certificate to the app to use certificate-based authentication with the Microsoft Graph PowerShell SDK. The SDK recognizes that you’re not running a normal interactive session and is happy to access data in all teams.

The Code

All of which brings us to a point where we can write some PowerShell code to:

  • Connect to the Graph (the application must also have the Group.Read.All permission to read details of groups in the tenant).
  • Select the beta endpoint.
  • Find all teams.
  • Loop through the teams to discover which teams use tags.
  • Loop through the tags to find which team members are assigned to each tag.
  • Report what we find.

Here’s some simple code to illustrate what’s possible.

Write-Host "Connecting to the Microsoft Graph to report Teams tags"

Connect-MgGraph -TenantId $TenantId -AppId $AppId -CertificateThumbprint "968E33D233CB99525CC6B2AADAD05B73E2A9701C" 
Select-MgProfile Beta
Write-Host "Finding Teams..."
[array]$Groups = Get-MgGroup -All
[array]$Teams = $Groups | ? {$_.ResourceProvisioningOptions -eq "Team"} | Sort DisplayName
$Report = [System.Collections.Generic.List[Object]]::new()

ForEach ($Team in $Teams) {
  Write-Host "Processing team" $Team.DisplayName
  [array]$TeamTags = Get-MgTeamTag -TeamId $Team.Id -ErrorAction SilentlyContinue
  If ($TeamTags) { # The team has some tags
     $TagMemberNames = $Null
     ForEach ($Tag in $TeamTags) {
       $TagMembers = (Get-MgTeamTagMember -TeamId $Team.Id -TeamWorkTagId $Tag.Id) | Select -ExpandProperty DisplayName 
       $ReportLine = [PSCustomObject][Ordered]@{
          Team        = $Team.DisplayName
          TeamId      = $Team.Id
          Tag         = $Tag.DisplayName
          Description = $Tag.Description
          Members     = $TagMembers -Join ", "
          TagId       = $Tag.Id }
      } #End Foreach Tag
   } #End If TeamTags
} #End ForEach team
[array]$TeamsWithTags = $Report.TeamId | Sort -Unique
[array]$UniqueTags = $Report.TagId | Sort -Unique
Write-Host "Total teams:      " $Teams.Count
Write-Host "Teams with tags:  " $TeamsWithTags.Count
Write-Host "Total tags:       " $UniqueTags.Count

$Report | Select Team, Tag, Description, Members | Out-GridView

In my tenant, of 82 teams only 8 had tags and a total of 16 tags were in use. Figure 2 shows the results as viewed through Out-GridView.

Reporting Teams tags
Figure 2: Reporting Teams tags

Teams Tagging for All

Microsoft doesn’t have a public API to report how often people use Teams tags to address channel messages, so even though I know that there’s not all that many tags in the tenant, it could be true that they’re all heavily used. We just don’t know. In any case, approximately 10% of all teams use tags, so now I need to decide if I want to ignore the situation or help team owners understand the benefit of tagging.

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.

One Reply to “How to Create a Report About Teams Tags”

Leave a Reply

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