Find Obsolete Groups and Teams
May 11: Microsoft is deprecating the TechNet Gallery in June 2020. The script can now be downloaded from GitHub.
Oct 14: Microsoft updated the location of the Teams compliance records used to check how active a team is. Version 4.7 of the script handles this issue.
I wrote the first version of a script to analyze the activity in Office 365 Groups and Teams to identify obsolete groups in 2017. The script is described in this Petri.com article and is reasonably popular. I keep an eye on the feedback from people who run the script and update the script as time goes by. You can download the latest version from GitHub. The latest version is V4.8 dated 16 December 2020.
Update: A Graph-based version of the script is available in GitHub (5.0). This version is much faster at processing Microsoft 365 Groups and Teams and is therefore the preferred code.
The basic idea is to analyze the Microsoft 365 Groups in a tenant to find underused groups or simply understand the level of activity across groups. The script looks at the level of activity in:
- Conversations stored in the Inbox of group mailboxes (for Outlook Groups).
- Documents (in SharePoint document libraries belonging to the groups)
- Chats (for Teams-enabled Groups). In fact, the script checks the compliance records logged in the group mailbox for conversations in channels belonging to the Teams.
Checking different aspects of individual groups isn’t fast. One tenant tells me that it takes 17 hours to process 5,300 groups… but this isn’t a report that you’ll run daily. It’s more like a monthly or quarterly activity.
The script records the data for each group in a PowerShell list. Eventually, after processing all the groups, the script outputs an HTML report and a CSV file. The script also assigns a status of Pass, Warning, or Fail to each group depending on the level of detected activity. The determination of the status is entirely arbitrary and should be adjusted to meet the needs of your organization.
At the bottom of the report you’ll see a summary like this:
Report created for: tenant.onmicrosoft.com Number of groups scanned: 182 Number of potentially obsolete groups (based on document library activity): 120 Number of potentially obsolete groups (based on conversation activity): 129 Number of Teams-enabled groups : 65 Percentage of Teams-enabled groups: 35.71% ----------------------------------------------------------------------------
Reviewing the report should help you find the Microsoft 365 Groups and Teams that are not being used. These groups are candidates for removal or archival.
You can view a screen capture video showing how to run the script here.
Scripts that evolve over time can often do with a rewrite from scratch. However, I don’t have the time for that. but I do make changes that I think are useful. Here are some recent changes.
- New tests to see if the SharePoint Online and Teams modules are loaded. In particular, the Teams check took far too long because the cmdlets in this module are slow. In fact, the Get-Team module is so slow that we don’t use it from V4.3 onwards. Using Get-UnifiedGroup with a filter is about twice as fast. We might revisit this point as new versions of the Teams PowerShell module appear. See note above about the Graph-based version of the script.
- Use a PowerShell list object to store the report data. This is much faster than an array, especially when you might want to store data for thousands of groups. This was one of the performance tips received after publishing a post about how we write PowerShell and it makes a real difference.
- Use Get-Recipient instead of Get-UnifiedGroup to create a set of group objects to process. Get-Recipient is much faster than Get-UnifiedGroup when you need to create a list of mail-enabled objects like Office 365 Groups.
- Output the storage consumed by the SharePoint site belonging to each group.
- Handle groups that have no conversations in the group mailbox more elegantly. Groups used by Teams are often in this situation.
The new Exchange Online REST-based cmdlets are not used (yet). It would be easy to replace Get-Recipient with Get-ExoRecipient and Get-MailboxFolderStatistics with Get-ExoMailboxFolderStatistics. I decided to stay with the standard cmdlets because not everyone has yet moved to the new cmdlets. However, a large environment, you might get some extra performance by using Get-ExoRecipient. There is no REST-based version of Get-UnifiedGroup.
Those who manage groups in large environments could also improve processing by using the techniques explained in this EHLO blog post.
Test Before Deployment
As always, test any PowerShell code downloaded from the web, even from sources like GitHub, before introducing it to a production system. The code as written needs some extra error handling to make it as robust as it could be, but I’ve left that to the professionals as people tend to have their own way of approaching this issue.
The Office 365 for IT Pros eBook includes many valuable tips for writing PowerShell scripts to interact with Office 365 Groups and Teams. Subscribe to gain benefit from all that knowledge!