PowerShell scripts

Find inactive teams in Microsoft 365 with PowerShell

Listen up, tech enthusiasts! Are you tired of searching through endless pages of inactive teams? Look no further because we have just the thing for you.

Microsoft Teams had around 280 million active users in 2023. So, it’s no wonder that finding inactive teams in Microsoft Teams is an important challenge. Left unchecked, inactive teams can lead to multiple problems that will leave several blind spots in your Microsoft 365 security and governance:

  • They take up unnecessary space in your M365 environment.
  • Having a large number of inactive teams can bog down your IT team.
  • And most importantly, inactive teams can hold sensitive information and content, potentially impacting the security of your Microsoft 365 environment.

Find inactive teams PowerShell script: details

We created a PowerShell script that will save you the trouble and find inactive teams without breaking a sweat. The script’s purpose is to search for teams that have been inactive for a specific period and defaults to 30 days. What’s more, it doesn’t just stop there – it also scans Teams chat activity for each team. And, if file activity in a team-related SharePoint site and Outlook conversations is what you’re after, try out our Syskit Point for free.

Want more flexibility? No problem! With the -InactivityPeriod parameter, you can modify the number of days of inactivity and customize your results to your liking. You’ll get a comprehensive output highlighting all the teams that have been inactive for the specified period.

So why waste your time searching when you have the solution right at your fingertips? Get ready to increase your productivity and efficiency with our PowerShell script and save time on team management headaches.

Example: Get-InactiveTeams.ps1 -InactivityPeriod 120  

By default, the script outputs the result only to the screen. There are optional flags available to export the result to CSV  

-ExportCSV (if set, this will automatically export the result to a CSV file. If you do not set an export path, it will export the file to %temp% folder)  

Example: Get-InactiveTeams.ps1 -InactivityPeriod 60 -ExportCSV  

-ExportFilePath  

Example: Get-InactiveTeams.ps1 -ExportCSV -ExportFilePath “C:Tempreport.csv” 

Find inactive teams: the script

# Set script parameters [CmdletBinding()] param ( [int]$InactivityPeriod = 30, [switch]$ExportCSV, [string]$ExportFilePath = "$env:TEMP\$(Get-Date -Format "yyyy_MM_dd")InactiveTeams.csv" ) # Check or install Microsoft Graph Reports module if ($null -eq (Get-Module -ListAvailable Microsoft.Graph.Reports)) { try { Write-Output "Microsoft Graph Reports module not found. Trying to install" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force | Out-Null Install-Module Microsoft.Graph.Reports -Force | Out-Null Write-Output "Microsoft Graph Reports module installed" } catch { Write-Output "Unable to install Microsoft Graph Reports module. $($Error[0].Exception.Message)" Return } } # Connect to M365 try { Write-Output "Connecting Microsoft Graph" Select-MgProfile -Name "beta" Connect-MgGraph -Scopes Reports.Read.All | Out-Null } catch { Write-Output "Unable to connect to M365. $($Error[0].Exception.Message)" Return } # Get activity report try { Get-MgReportTeamActivityDetail -Period 'ALL' -OutFile "$env:Temp\teamsactivityreport.json" } catch { Write-Output "Unable to get activity report. $($Error[0].Exception.Message)" Return } # Read the report for filtering $AllTeamActivity = (Get-Content -Raw "$env:Temp\teamsactivityreport.json" | ConvertFrom-Json).Value # Check each team and build a report $FinalReport = @() foreach ($SingleTeamActivity in $AllTeamActivity) { if ($SingleTeamActivity.lastActivityDate) { $lastActivityDate = Get-Date -Date $SingleTeamActivity.lastActivityDate if ($lastActivityDate -le $((Get-Date).AddDays(-$InactivityPeriod))) { $TeamActivityObject = [PSCustomObject]@{ TeamId = $SingleTeamActivity.teamId TeamName = $SingleTeamActivity.teamName LastActivityDate = $SingleTeamActivity.lastActivityDate } $FinalReport += $TeamActivityObject } } else { $TeamActivityObject = [PSCustomObject]@{ TeamId = $SingleTeamActivity.teamId TeamName = $SingleTeamActivity.teamName LastActivityDate = "No activity found" } $FinalReport += $TeamActivityObject } } # Print result to the screen Write-Output $FinalReport | Format-Table # Export result to CSV file if needed if ($ExportCSV) { $FinalReport | Export-Csv -Path $ExportFilePath -NoTypeInformation Write-Output "Report saved to $ExportFilePath" } # Stop before closing powershell window Read-Host "Script completed. Press 'Enter' to finish"

User-friendly visibility of all teams in Microsoft 365

To get complete visibility of all teams and team activity in your Microsoft 365 environment, you need to manually identify and filter out inactive teams using usage reports in the admin center. Or, like this blog post shows, you can use PowerShell to do it.

But at the end of the day, all of this isn’t very easy and will take a toll on your IT team’s time and resources.

Get a list of inactive teams quickly with Syskit Point

Syskit Point is a Microsoft 365 governance and management platform that really nails the task of identifying inactive teams. Its streamlined approach provides comprehensive information in mere seconds, all without complex PowerShell scripts.

What’s more, Syskit Point goes the extra mile by delivering real-time, easily accessible reports online. You can quickly share these informative reports with colleagues and managers using nothing more than a simple link.

And the cherry on top? Syskit Point lets you execute a whole range of actions directly within the report. That’s right, you can work with Project Server sites, security and database information, operational policies, time and task management, project permission, and the project list with effortless ease. With Syskit Point, it’s never been easier to manage and maximize your productivity.

Subscribe to our Newsletter

Related Posts