Export Tabs and Apps from All Microsoft Teams using PowerShell

Administrators can use the Microsoft Teams Admin center to generate the All Teams report and manage channels and members of a single team at a time. However, they can’t be able to view channels, members, and tabs from all teams. In this post, we will explore how to export tabs and apps from all Teams using PowerShell.

Microsoft Teams PowerShell module supports the commands Get-Team and Get-TeamChannel to retrieve the teams and channels. As of now, there is no command available to get tabs from a channel. So, we need to use the Microsoft Graph API to retrieve tabs from a Team channel.

Summary

Get Access Token and Connect Teams PowerShell module

The List tabs API from Microsoft Graph retrieves the tabs from a channel. We need an OAuth Access Token with the permission “TeamsTab.Read.All” (Application or Delegated) to call this API. 

We can use the MSAL.PS library to acquire access tokens with Delegated permissions. Run the following command in PowerShell to install this module. You can close and re-open the PowerShell once you installed the module.

Install-Module -Name MSAL.PS

Run the following commands to get Access Token on behalf of a user.

#Provide your Office 365 Tenant Domain Name or Tenant Id
$TenantId = "contoso.onmicrosoft.com"
#$TenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    
#Used the Microsoft Graph PowerShell app id. You can create and use your own Azure AD App id if needed.
$AppClientId="14d82eec-204b-4c2f-b7e8-296a70dab67e"  

$MsalParams = @{
    ClientId = $AppClientId
    TenantId = $TenantId    
    Scopes = "https://graph.microsoft.com/TeamsTab.Read.All"    
}

$MsalResponse = Get-MsalToken @MsalParams
$AccessToken  = $MsalResponse.AccessToken

Install the latest Microsoft Teams PowerShell module, and run the following command to connect to the Teams module.

Connect-MicrosoftTeams

Export all Tabs and Apps from All Microsoft Teams

The below script gets all the Teams and their channels using the Microsoft Teams PowerShell commands. The script retrieves tabs from each Team channel using Microsoft Graph API. Finally, export the result to a CSV file.

#Provide your access token. 
#$AccessToken="eyJ0eXAiOiJ......" 

#Form request headers with the acquired $AccessToken
$headers = @{'Content-Type'="application\json";'Authorization'="Bearer $AccessToken"}

$Result = @() #Result array

#Get all teams
$AllTeams= Get-Team
$TotalTeams = $AllTeams.Count
$i = 0

#Iterate teams one by one and get channels and their tabs
ForEach ($Team in $AllTeams)
{
$i++
Write-Progress -Activity "Fetching channels from $($Team.Displayname)" -Status "$i out of $TotalTeams Teams completed" -Id 1

Try
{
#Get channels
$TeamChannels = Get-TeamChannel -GroupId $Team.GroupId
$TotalChannels = $TeamChannels.Count
$ch=0
 
#Iterate channels one by one and get tabs
ForEach ($Channel in $TeamChannels)
{
$ch++
Write-Progress -Activity "Fetching tabs from $($Channel.Displayname)" -Status "$ch out of $TotalChannels Channels completed" -ParentId 1

Try
{
#This request retrieves the list of tabs in the specified channel within a team.
$ApiUrl = "https://graph.microsoft.com/v1.0/teams/$($Team.GroupId)/channels/$($Channel.Id)/tabs?`$expand=TeamsApp"

#Get tabs
$Response =  Invoke-RestMethod -Method GET -Uri $ApiUrl -ContentType "application\json" -Headers $headers
$Tabs = $Response.value

#Iterate tabs one by one and add to the result array
ForEach ($Tab in $Tabs)
{

#Add tab info to the result array
$Result += New-Object PSObject -property $([ordered]@{
TeamId = $Team.GroupId
TeamName = $Team.DisplayName
TeamVisibility = $Team.Visibility
ChannelId = $Channel.Id
ChannelName = $Channel.DisplayName
ChannelMemberShipType = $Channel.MembershipType
TabId = $Tab.id
TabName = $Tab.DisplayName
AppName = $Tab.teamsApp.displayName
AppId = $Tab.teamsApp.Id
AppSource = $Tab.teamsApp.distributionMethod
})

}
}
Catch 
{
Write-Host "Error occurred for the channel $($Channel.Displayname)" -f Yellow
Write-Host $_ -f Red
}
}
}
Catch 
{
Write-Host "Error occurred for the team $($Team.Displayname)" -f Yellow
Write-Host $_ -f Red
}
}
 
#Export the result to CSV file
$Result | Export-CSV "C:\Temp\AllTeamsTabs.CSV" -NoTypeInformation -Encoding UTF8

The above commands store the tab details in the $Result array. We can generate more reports by applying a filter in the $Result array using the available fields.

Export specific type of Tab or App (Wiki) from All Teams

The following command exports only the Wiki tabs from all the teams.

$Result | Where-Object { $_.AppName -eq "Wiki" } | Export-CSV "C:\Temp\AllWikiTabs.CSV" -NoTypeInformation -Encoding UTF8

Export the OneNote tab from all the Teams

Run the following command to export the OneNote tab from all the teams.

$Result | Where-Object { $_.AppName -eq "OneNote" } | Export-CSV "C:\Temp\AllOneNoteTabs.CSV" -NoTypeInformation -Encoding UTF8

Export Teams with a specific type of Tab or App (Wiki)

Use the following command to export only the Teams list that includes the Wiki tab.

$Result | Where-Object { $_.AppName -eq "Wiki" } | Sort-Object -Unique -Property TeamName | Select TeamName, TeamId, TeamVisibility | Export-CSV "C:\Temp\TeamsWithWikiTab.CSV" -NoTypeInformation -Encoding UTF8

Export Teams with the OneNote tab

The following command export the Teams list which has the OneNote tab in any one of the team’s channels.

$Result | Where-Object { $_.AppName -eq "OneNote" } | Sort-Object -Unique -Property TeamName | Select TeamName, TeamId, TeamVisibility | Export-CSV "C:\Temp\TeamsWithOneNoteTab.CSV" -NoTypeInformation -Encoding UTF8
Advertisement