All scripts
Governance 640

Teams Shared Channel Inventory Report

Scans every team in the tenant and lists all shared channels, with member counts, so you can see channel level access without clicking through each team by hand.

Get-TeamsSharedChannelReport.ps1
<#
.SYNOPSIS
    Reports on all shared channels across Microsoft Teams in the tenant.

.DESCRIPTION
    Connects to Microsoft Graph and walks every team in the tenant, checking
    each channel's membership type. Any channel marked as shared gets
    exported to a CSV, along with the owning team name, the channel name,
    and how many members are on that channel. Shared channels can quietly
    give another team, or another organization, access to content, so most
    admins want one place to see all of them instead of clicking through
    every team by hand.

.PARAMETER OutputPath
    Path to the CSV file that gets created. Defaults to a file in the
    current folder named SharedChannelReport.csv.

.EXAMPLE
    .\Get-TeamsSharedChannelReport.ps1 -OutputPath "C:\Reports\SharedChannels.csv"

    Runs the report and writes the results to the given CSV path.

.AUTHOR
    Shehryar Hassan
#>

[CmdletBinding()]
param(
    [string]$OutputPath = ".\SharedChannelReport.csv"
)

$requiredScopes = @("Team.ReadBasic.All", "Channel.ReadBasic.All", "ChannelMember.Read.All")
Connect-MgGraph -Scopes $requiredScopes -NoWelcome

$results = @()

Write-Host "Getting the list of teams in the tenant..."
$teams = Get-MgTeam -All

$teamCount = $teams.Count
$current = 0

foreach ($team in $teams) {
    $current++
    Write-Progress -Activity "Scanning teams for shared channels" -Status "$($team.DisplayName)" -PercentComplete (($current / $teamCount) * 100)

    try {
        $channels = Get-MgTeamChannel -TeamId $team.Id -All
    }
    catch {
        Write-Warning "Could not read channels for team '$($team.DisplayName)': $($_.Exception.Message)"
        continue
    }

    $sharedChannels = $channels | Where-Object { $_.MembershipType -eq "shared" }

    foreach ($channel in $sharedChannels) {
        $memberCount = 0
        try {
            $members = Get-MgTeamChannelMember -TeamId $team.Id -ChannelId $channel.Id -All
            $memberCount = $members.Count
        }
        catch {
            $memberCount = -1
        }

        $results += [PSCustomObject]@{
            TeamName       = $team.DisplayName
            TeamId         = $team.Id
            ChannelName    = $channel.DisplayName
            ChannelId      = $channel.Id
            MembershipType = $channel.MembershipType
            MemberCount    = $memberCount
        }
    }
}

if ($results.Count -eq 0) {
    Write-Host "No shared channels found in this tenant."
}
else {
    $results | Sort-Object TeamName, ChannelName | Export-Csv -Path $OutputPath -NoTypeInformation
    Write-Host "Found $($results.Count) shared channel(s). Report saved to $OutputPath"
}

Disconnect-MgGraph | Out-Null

Read it before you run it, and test in a safe tenant first.