Simplify user tasks like bulk creation, updates, password resets, deletions, license checks & more — all from one place.
🚀 Launch ToolkitUnused Microsoft 365 Groups can accumulate over time—especially when created automatically through Planner, SharePoint, or Outlook. This script helps you identify empty Unified Groups (M365 Groups) that have no members and aren’t linked to Teams, giving admins an easy way to declutter the tenant.
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Group.Read.All", "GroupMember.Read.All"
# Step 1: Get all Unified Groups (Microsoft 365 Groups)
$unifiedGroups = Get-MgGroup -All -Property Id, DisplayName, Mail, GroupTypes, CreatedDateTime, ResourceProvisioningOptions |
Where-Object {
$_.GroupTypes -contains "Unified" -and
($_.ResourceProvisioningOptions -notcontains "Team")
}
Write-Host "`nChecking each Microsoft 365 Group (excluding Teams) for members..." -ForegroundColor Cyan
# Step 2: Loop and filter empty groups
$emptyUnifiedGroups = foreach ($group in $unifiedGroups) {
$members = Get-MgGroupMember -GroupId $group.Id -ErrorAction SilentlyContinue
if (-not $members) {
[PSCustomObject]@{
DisplayName = $group.DisplayName
Mail = $group.Mail
GroupId = $group.Id
CreatedDate = $group.CreatedDateTime
}
}
}
# Step 3: Output result
if ($emptyUnifiedGroups) {
Write-Host "`nEmpty Unified Groups found (excluding Teams):`n" -ForegroundColor Green
$emptyUnifiedGroups | Format-Table DisplayName, Mail, GroupId, CreatedDate
} else {
Write-Host "`nNo empty unified groups found." -ForegroundColor Yellow
}
The script authenticates using the Connect-MgGraph cmdlet with delegated permissions: Group.Read.All and GroupMember.Read.All.
Only groups where GroupTypes contains "Unified" are selected. These represent Microsoft 365 Groups (created via Outlook, SharePoint, Planner, etc.).
By checking that ResourceProvisioningOptions does not contain "Team", the script skips over any group that's been provisioned as a Team.
Each group is checked for membership using Get-MgGroupMember. If the member list is empty, it’s considered an empty group.
Results are output to the console in a clean table format showing group name, email, ID, and creation date.
🔄 Graph PowerShell cannot be used for managing traditional Distribution Lists. Tasks like member additions require Exchange PowerShell.
Want to take it further? Here are some ideas:
$emptyUnifiedGroups | Export-Csv -Path "EmptyUnifiedGroups.csv" -NoTypeInformation
Add logic to include only groups older than a certain date:
Where-Object { $_.CreatedDateTime -lt (Get-Date).AddMonths(-6) }
Instead of deleting, flag empty groups for review by exporting or writing to SharePoint lists or Teams.
Set up the script to run monthly and email reports to admins via Power Automate or Azure Automation.
Error | Cause | Solution |
---|---|---|
Request_UnsupportedQuery | Using unsupported filter syntax like groupTypes/any(...) | Avoid Graph-level filters for groupTypes; filter in PowerShell instead |
Access Denied | Missing Graph permissions | Ensure Group.Read.All and GroupMember.Read.All are granted |
Empty Output | No empty unified groups or logic mismatch | Confirm group types, manually verify with Get-MgGroup |
Get-MgGroupMember: NotFound | Group is inaccessible or was recently deleted | Use -ErrorAction SilentlyContinue to skip gracefully |
This script gives Microsoft 365 administrators a simple, effective way to find unused M365 groups that are not tied to Microsoft Teams and have zero members. Keeping your directory clean not only improves manageability but also enhances security and user experience.
💡 Regularly auditing your groups ensures you’re not paying for or managing empty, unused collaboration spaces.
© m365corner.com. All Rights Reserved. Design by HTML Codex