Back to script library
Entra / Microsoft 365 · Teams

Report user membership of teams

Use the Get-AssociatedTeam cmdlet to fetch and report team membership for individual user accounts.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-MgGraph -Scopes User.Read.All, Directory.Read.All

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

param(
[string] $TenantId = "$Tenant.Id"
)
$Modules = @( "MicrosoftTeams", "Microsoft.Graph" )
# Requires -Modules $Modules
$ModulesLoaded = Get-Module | Select Name
If (!($ModulesLoaded -match "MicrosoftTeams")) {Write-Host "Please connect to the Microsoft Teams module and then restart the script"; break}
Connect-MgGraph -Scopes User.Read.All, Directory.Read.All
Select-MgProfile Beta
$Tenant = (Get-MgOrganization)
$TenantName = $Tenant.DisplayName
# Find user accounts with licenses
[array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All
If (!($Users)) { Write-Host "No user accounts found - exiting" ; break }
$Users = $Users | Sort-Object DisplayName
[int]$i = 0
$UserTeamInfo = [System.Collections.Generic.List[Object]]::new()
ForEach ($User in $Users) {
$i++
Write-Host ("Processing team membership for {0} ({1}/{2})..." -f $User.DisplayName, $i, $Users.Count)
[array]$TeamInfo = Get-AssociatedTeam -User $User.UserPrincipalName
ForEach ($Team in $TeamInfo) {
If ($Team.TenantId -eq $TenantId) { # Resolve the tenant identifier to a name
$Name = $TenantName }
Else {
$LookUpId = $Team.TenantId.toString()
$Uri = "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$LookUpId')"
$ExternalTenantData = Invoke-MgGraphRequest -Uri $Uri -Method Get
$Name = $ExternalTenantData.DisplayName
}
$TeamData = [PSCustomObject][Ordered]@{ # Write out details of the team
Id = $User.Id
DisplayName = $User.DisplayName
UPN = $User.UserPrincipalName
Team = $Team.DisplayName
TeamId = $Team.GroupId
Tenant = $Name
TenantId = $Team.TenantId}
$UserTeamInfo.Add($TeamData)
} #End ForEach Team
} # End ForEach User
[array]$ExternalTeams = $UserTeamInfo | Where-Object {$_.TenantId -ne $TenantId} | Sort-Object TeamId -Unique
$ExternalPeople = $UserTeamInfo | Where-Object {$_.TenantId -ne $TenantId} | Sort-Object UPN -Unique
$ExternalPeople = $ExternalPeople.DisplayName -Join ", "
$ExternalTenants = $ExternalTeams.Tenant | Sort-Object -Unique
$AvgTeams = [math]::round(($UserTeamInfo.Count/$Users.Count),2)
Write-Host ""
Write-Host ("Each of the {0} users belongs to an average of {1} teams" -f $Users.Count, $AvgTeams)
Write-Host ("Membership of {0} teams found in {1} external tenant(s)" -f $ExternalTeams.Count, $ExternalTenants.Count)
Write-Host ("These accounts have membership of external teams: {0}" -f $ExternalPeople)
$UserTeamInfo | Out-GridView
# Code to generate a PDF report using the PSWriteHTML module
Import-Module PSWriteHTML.psd1 -Force
$UserTeamInfo | Out-HtmlView -HideFooter -Title "User Membership in Teams Report"

Parameters

ParameterDefaultNotes
-TenantId$Tenant.IdMicrosoft Entra tenant ID for app-only Graph authentication.
Attribution