Report team private channel membership
A script to report the membership of Teams private channels. This script is designed to be run by a tenant administrator or someone with the necessary permissions to access Teams data.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Import-Module MicrosoftTeams -Force
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
$Modules = Get-Module | Select-Object -ExpandProperty NameIf ($Modules -notcontains 'MicrosoftTeams') {Write-Host "Importing Microsoft Teams module..." -ForegroundColor YellowImport-Module MicrosoftTeams -ForceTry {Write-Host "Connecting to Microsoft Teams..." -ForegroundColor YellowConnect-MicrosoftTeams -ErrorAction Stop} Catch {Write-Host "Failed to connect to Microsoft Teams. Please ensure you have the necessary permissions and try again." -ForegroundColor RedExit}}Write-Output "Fetching teams data..." -ForegroundColor Green[array]$Teams = Get-Team$ChannelsList = [System.Collections.Generic.List[Object]]::new()[int]$i = 0ForEach ($Team in $Teams) {$i++Write-Host ("Processing {0} ({1}/{2})" -f $Team.DisplayName, $i, $Teams.Count)[array]$Channels = Get-TeamAllChannel -GroupId $Team.GroupId -MembershipType "Private"ForEach ($Channel in $Channels) {Write-Host ("Found private channel {0} in team {1}" -f $Channel.DisplayName, $Team.DisplayName)[array]$ChannelMembers = Get-TeamChannelUser -GroupId $Team.GroupId -DisplayName $Channel.DisplayNameIf ($ChannelMembers) {ForEach ($Member in $ChannelMembers) {$ChannelLine = [PSCustomObject][Ordered]@{ # Write out details of the private channel and its membersTeam = $Team.DisplayNameChannel = $Channel.DisplayNameDescription = $Channel.DescriptionMember = $Member.NameMemberUPN = $Member.UserRole = $Member.RoleHostTeam = $Channel.HostTeamIdId = $Channel.Id}$ChannelsList.Add($ChannelLine)} # End ForEach Member} Else { # Deal with private channels that have no members (which can happen if the channel is created and then all members are removed, or if the channel is created and never had any members added to it)$ChannelLine = [PSCustomObject][Ordered]@{ # Write out details of the private channel with no membersTeam = $Team.DisplayName + " (No members)"Channel = $Channel.DisplayName + " (No members)"Description = $Channel.DescriptionMember = $NullMemberUPN = $NullRole = $NullHostTeam = $Channel.HostTeamIdId = $Channel.Id}$ChannelsList.Add($ChannelLine)}}} # End ForEach Team$ChannelsList | Out-GridView -Title "Teams Private Channel Membership Report"# Set up to use the ImportExcel module to generate Excel worksheets if it is available. If not, the report will be generated in CSV format instead.If (Get-Module ImportExcel -ListAvailable) {$ExcelGenerated = $TrueImport-Module ImportExcel -ErrorAction SilentlyContinue}# Generate the attachment in either Excel worksheet or CSV format, depending on if the ImportExcel module is availableIf ($ExcelGenerated) {$OutputFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\TeamsPrivateChannelMembership.xlsx"$ChannelsList | Export-Excel -Path $OutputFile -WorksheetName "PrivateChannelMembership" -Title ("Teams Private Channel Membership {0}" -f (Get-Date -format 'dd-MMM-yyyy')) -TitleBold -TableName "PrivateChannels"} Else {$OutputFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\TeamsPrivateChannelMembership.csv"$ChannelsList | Export-Csv -Path $OutputFile -NoTypeInformation -Encoding Utf8}Write-Host "Report generated in: $OutputFile" -ForegroundColor Green