EASYENTRA Blog

News & Updates

How to Export Shared Channel Membership Report in Microsoft Teams

How to Export Shared Channel Membership Report in Microsoft Teams

Shared channels in Microsoft Teams allow users to collaborate without adding everyone to the parent team. A shared channel can include individuals from the host organization, external participants through Microsoft Entra B2B direct connect, or members of another team with which the channel has been shared.

This flexibility makes shared channels useful for cross-team and cross-organization collaboration. However, it also makes membership more difficult to track. Reviewing only the parent team does not provide a complete picture because users can access a shared channel without being members of that team. This guide explains how to review and export shared channel membership details in Microsoft Teams.

How Shared Channel Membership Works in Microsoft Teams

Unlike standard channels, shared channels maintain their own membership. A shared channel can provide access through:

  • Direct membership: A user is added directly to the shared channel.
  • Team-based membership: The channel is shared with another team, allowing eligible members of that team to access it.
  • External membership: A user from another Microsoft 365 organization is added through B2B direct connect.

External participants in shared channels do not appear as guest accounts in the host tenant. This is one reason shared-channel access can be difficult to review through regular team or guest-user reports.

How to Export Private Channel Membership in Microsoft Teams

Administrators can review private channel membership through the Teams admin center or use PowerShell to generate a consolidated report across the tenant.

Get a List of Shared Channel Members Using Teams Admin Center

The Microsoft Teams admin center allows administrators to identify shared channels within a team and review their membership without using PowerShell. It is useful for checking members, owners, and outdated access.

  1. Sign in to the Microsoft Teams admin center.  
  2. Go to Teams > Manage teams.  
  3. Select the team you want to review.  
  4. Open the Channels tab.  
  5. Filter the Type column by Shared.  
  6. Select a shared channel and open its membership details to review its owners and directly added members. 

Export Shared Channel Membership Report Using PowerShell

The following script scans every team, identifies its shared channels, retrieves their membership, and exports the results to a CSV file. 

# 1. Connect to Microsoft Graph
Import-Module MicrosoftTeams
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Groups)) {
    Install-Module Microsoft.Graph -Scope CurrentUser -Force
}
Connect-MicrosoftTeams
Connect-MgGraph -Scopes "GroupMember.Read.All", "Directory.Read.All", "User.Read.All"
# Setup Report Path
$OutputPath = "C:\temp\TeamsSharedChannelReport_FixedFinal.csv"
if (-not (Test-Path "C:\temp")) { New-Item -Path "C:\" -Name "temp" -ItemType Directory -Force }
$Report = [System.Collections.Generic.List[PSCustomObject]]::new()
Write-Host "Fetching all Teams..." -ForegroundColor Cyan
$AllTeams = Get-Team
foreach ($Team in $AllTeams) {
    Write-Host "Processing Team: $($Team.DisplayName)..." -ForegroundColor Yellow
      # Get only Shared Channels
    $SharedChannels = Get-TeamChannel -GroupId $Team.GroupId | Where-Object { $_.MembershipType -eq "Shared" }
     foreach ($Channel in $SharedChannels) {
        Write-Host "  -> Found Shared Channel: $($Channel.DisplayName)" -ForegroundColor Green
            try {
            $Members = Get-MgTeamChannelMember -TeamId $Team.GroupId -ChannelId $Channel.Id -ErrorAction Stop
            foreach ($Member in $Members) {
                $UserUPN = "Unknown/External"
                $AccessType = "Direct Member"
            # Check for OData mapping properties safely
                if ($null -ne $Member.AdditionalProperties) {
                    if ($Member.AdditionalProperties.containsKey("@odata.type")) {
                        $OdataType = $Member.AdditionalProperties["@odata.type"]
                        if ($OdataType -like "*sharedWithChannelTeam*") { 
                            $AccessType = "Inherited via Team" 
                        }
                    }
                }
              # In Graph ConversationMembers, the object's top-level ID can often map directly 
                # to the user's underlying Azure/Entra ID object if it's a direct user object.
                # If that fails, we fallback to finding the distinct ID inside the property bags.
                $SearchId = $Member.Id
                if ($null -ne $Member.AdditionalProperties -and $Member.AdditionalProperties.containsKey("userId")) {
                    $SearchId = $Member.AdditionalProperties["userId"]
                }
               # Clean up prefix punctuation Graph occasionally inserts into conversation member IDs
                if ($SearchId -match "([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})") {
                    $SearchId = $Matches[1]
                }
                if (-not [string]::IsNullOrEmpty($SearchId)) {
                    try {
                        # Resolve the actual UPN identity against the tenant directory
                        $EntraUser = Get-MgUser -UserId $SearchId -Property "UserPrincipalName,Mail" -ErrorAction Stop
                        $UserUPN = if ($null -ne $EntraUser.UserPrincipalName) { $EntraUser.UserPrincipalName } else { $EntraUser.Mail }
                    } catch {
                        # Fallback for external direct-connect profiles
                        if ($null -ne $Member.AdditionalProperties -and $Member.AdditionalProperties.containsKey("email")) { 
                            $UserUPN = $Member.AdditionalProperties["email"] 
                        }
                    }
                }
                $Report.Add([PSCustomObject]@{
                    "HostTeamName"    = $Team.DisplayName
                    "ChannelName"     = $Channel.DisplayName
                    "UserDisplayName" = $Member.DisplayName
                    "UserUPN"         = $UserUPN
                    "AccessType"      = $AccessType
                    "ChannelRole"     = ($Member.Roles -join ", ")
                })
            }
        } catch {
            Write-Host "    [!] Graph API retrieval failed for channel: $($Channel.DisplayName)." -ForegroundColor Red
            Write-Host "    Error Info: $($_.Exception.Message)" -ForegroundColor DarkRed
        }
    }
}
# Export Results
if ($Report.Count -gt 0) {
    $Report | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
    Write-Host "`nSuccess! Cleaned up report exported to $OutputPath" -ForegroundColor Green
} else {
    Write-Host "`nNo shared channels membership could be enumerated." -ForegroundColor Red
}

Make sure the destination folder already exists before running the script.

The output shows the host team and shared channel name, along with each user’s display name, UPN, access type, and channel role. This helps administrators see which users have direct access to each shared channel, distinguish owners from members, identify users who belong to multiple shared channels, and find channels that may not have an assigned owner.

By exporting the host team, channel, user, and role information, administrators can quickly review shared channel access, identify users with membership in several channels, distinguish owners from members, and locate channels that may no longer have an assigned owner.

Free 30-minute demo

try 30 days for free

GET EASYENTRA NEWS

Opt out at any time

“One of the best products I've used.”
Gary Shurland
Chief Information Officer, Mirick, United States
“This tool has been invaluable in streamlining our IT processes.”
Tyson Mckay
Chief Information Officer, Southwest Network, United States
“This product has been a miracle for our Help Desk. EasyEntra has completely transformed how we handle Microsoft 365 administration.”
Doug Sanders
Manager of Technical Customer Support, Junior Achievement USA, United States
“Your product is such a time saver. I love it!”
Scott Fehr
IT Infrastructure, MEC Aerial Work Platforms, United States
“It's a good product and saves us lots of time for these ongoing quick admin tasks.” 
Chris McFerran
Managing Director, CTech IT Solutions Ltd, United Kingdom
“EasyEntra has significantly streamlined our workflow, simplifying everything. It feels almost like a revolution.”
Johan Sadelius
IT-chef, Arjeplog Kommun, Sweden
I greatly appreciate your assistance and willingness to enhance the already outstanding product.”
Michael I. Wilson
Executive Director of Information Technology, Archdiocese Of Washington, United States
“It's great not having to switch back and forth between the O365 admin center and the Teams admin center to assign groups. I am sold!”
Thomas Madden
Director Information Technology, AutoPayPlus, United States
“I would highly recommend organizations use the solution as it greatly simplifies various tasks.”
S. Roger Singh
Chief Technology Officer, Prasad & Company LLP, Canada
“EasyEntra is time-saving. Love the copy/paste for user/computer groups and the copy to new user.”
Damian Nita
Associate Network Administrator, Shenandoah Valley Westminster-Canterbury, United States
“EasyEntra has transformed our daily IT operations by simplifying user management, reducing errors, and enhancing overall efficiency.”
Henrik Nefling
IT- and Digitalization Manager, Animal Protection Denmark, Denmark