Table of Contents
Inactive Channels Clutter Up Teams But No One Does Anything About Them
After the recent completion of the migration of private channels to a new infrastructure (which encountered some hiccups), I started to think about the set of standard, shared, and private channels that exist in Microsoft 365 tenants. I’ve been using Teams since its preview in late 2016 and have created many channels in that time, including creating 1,000 channels to test the limit for a team. I’ve also participated in many teams and channels in other tenants.
In many cases, I’ve seen how channels fall into disuse once their purpose is served. When this happens, team owners often ignore the underused channels and seldom take the option to archive channels or clean up by deleting unwanted channels. Users don’t care because the inactive channels eventually drop off their horizon when Teams or the user hides the channels from view.
Copilot Didn’t Help
There’s no out-of-the-box usage report that can identify inactive channels. The Teams usage report has an active channels column that’s interesting but doesn’t help because it doesn’t reveal which are the active channels in a team. I asked Copilot for help, and it pointed me to the inactive teams card under the Collaboration tab in the Teams admin center. Alas, the results were disappointing (Figure 1).
Using PowerShell to Identify Inactive Channels
PowerShell can normally help by examining data to find answers. In this case, I decided that I needed to use the Microsoft Graph PowerShell SDK to:
- Use the Get-MgTeam cmdlet to find all teams.
- Use the Get-MgTeamChannel cmdlet to find the channels in each team.
- Use the Get-MgTeamChannelMessage cmdlet to find the latest message posted to the channel. If the message is older than a threshold (I used 180 days), the channel is deemed to be inactive.
To make everything work, an app-only session is required with consent for the following Graph permissions: Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All, ChannelMember.Read.All. A delegated session won’t work unless the signed-in account is a member of every team, private, and shared channel, which is unlikely.
The code is simple enough and the only real issue is that the last message posted to a channel might not be sent by a human user. Many system messages are posted to channels, such as when a new member joins. A filter is therefore needed to remove the system messages to find the latest message sent by a human.
All that’s left to do is to generate a report file containing details of channels and the last message posted together with some other information like the team owners. I included code to generate email with the report attached as an Excel or CSV file (Figure 2). As you can see, the channel that’s been inactive the longest in my tenant is very old (in Teams time). It goes back to preparing for a session at the Ignite 2016 conference.
You can download the full script from the Office 365 for IT Pros GitHub repository. Be sure to flag any bugs that you find – and feel free to fix them too!
A Regular Process
Leaving inactive channels dangling with no attention might seem that it does little harm. However, channel conversations are indexed and do appear in searches, and the longer a channel is inactive, the less valuable those conversations are likely to be. This is especially important for tenants using Microsoft 365 Copilot where the information from old and obsolete channel conversations might be recycled in AI-generated responses.
Checking for inactive channels is probably something that should be done on a regular basis, and this kind of procedure is well suited to execute as a scheduled Azure Automation runbook. Once you know about the inactive channels, you can decide what to do with them. The easiest thing is to archive the inactive channels using the Invoke-MgArchiveTeamChannel cmdlet:
Invoke-MgArchiveTeamChannel -TeamId $Team.Id -ChannelId $Channel.Id
The alternative is to delete the inactive channels with the Remove-MgTeamChannel cmdlet:
Remove-MgTeamChannel -TeamId $Team.Id -ChannelId $Channel.Id
Over to you!
The nice thing about generative AI tools is that they can generate information based on what’s gone before. The bad thing about generative AI tools is that they can’t create new thinking or insights about how technology works (or doesn’t). When we write the Office 365 for IT Pros and Automating Microsoft 365 with PowerShell eBooks, we depend on hundreds of years of real-world experience, knowledge, and intuition to analyze and explain how Microsoft 365 really works. If you understand the basic principles about Entra ID, Exchange Online, SharePoint Online, Teams, the Microsoft Graph, and more, you’ll be able to figure out the value of new features as Microsoft adds them to the platform. All for less than ten copies of black coffee.

