Microsoft 365 Groups (also known as M365 Groups or Unified Groups) are at the heart of collaboration in Microsoft 365. They power Teams, Outlook Groups, SharePoint sites, Planner, and Yammer.
For IT admins and security researchers, it’s critical to be able to enumerate groups, review their metadata, and audit access. In this updated 2025 guide, we’ll show you how to:
We’ll cover two modern approaches:
Install the Graph PowerShell SDK:
Install-Module Microsoft.Graph -Scope CurrentUser Authenticate with MFA support:
Connect-MgGraph -Scopes "Group.Read.All","GroupMember.Read.All" Install required packages:
pip install msgraph-core azure-identity Register an Azure AD app with Group.Read.All and GroupMember.Read.All delegated permissions.
Get-MgGroup -All |
Select-Object Id, DisplayName, Description, Visibility, Mail, CreatedDateTime from msgraph.core import GraphClient
from azure.identity import DeviceCodeCredential
# Authenticate (supports MFA)
credential = DeviceCodeCredential(client_id="YOUR-APP-ID")
client = GraphClient(credential=credential)
# Fetch groups with metadata
groups = client.get("/groups?$select=id,displayName,description,visibility,mail,createdDateTime")
for g in groups.json().get('value', []):
print(f"{g['displayName']} ({g['visibility']}) - {g.get('mail')}") Get-MgGroupOwner -GroupId <GroupId>
Get-MgGroupMember -GroupId <GroupId> group_id = "<GROUP-ID>"
owners = client.get(f"/groups/{group_id}/owners")
members = client.get(f"/groups/{group_id}/members")
print("Owners:", [o["displayName"] for o in owners.json().get('value', [])])
print("Members:", [m["displayName"] for m in members.json().get('value', [])]) Get-MgGroup -All | Where-Object { -not (Get-MgGroupOwner -GroupId $_.Id) } Get-MgGroup -All | ForEach-Object {
$guests = Get-MgGroupMember -GroupId $_.Id | Where-Object {$_.UserType -eq "Guest"}
if ($guests) { Write-Output "$($_.DisplayName) has guest users" }
} for g in groups.json().get('value', []):
members = client.get(f"/groups/{g['id']}/members")
if any(m.get("userType") == "Guest" for m in members.json().get('value', [])):
print(f"Group {g['displayName']} contains guest members") Get-MgGroup -All |
Select-Object DisplayName, Visibility, Mail, CreatedDateTime |
Export-Csv GroupsReport.csv -NoTypeInformation import csv
with open("groups_report.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Name", "Visibility", "Mail"])
for g in groups.json().get('value', []):
writer.writerow([g['displayName'], g['visibility'], g.get('mail')]) Add-MgGroupToLifecyclePolicy -GroupId <GroupId> -PolicyId <PolicyId> You can call:
/reports/getOffice365GroupsActivityDetail(period='D7') to detect inactive groups.
Enumerating Microsoft 365 Groups is essential for security, compliance, and governance. Using PowerShell or Python with Microsoft Graph lets you quickly list groups, audit memberships, and detect risks like ownerless or guest-heavy groups. Always use an Azure AD app with the right permissions (Group.Read.All and GroupMember.Read.All) for secure and reliable access.
The id command prints user and group identity for any account on the system. It shows the…
sed processes input line by line, applies your commands, and writes the result to standard output.…
Linux provides two main tools for renaming directories: mv for single renames and the rename utility for batch pattern-based…
The w command in Linux shows who is currently logged in to the system and what each…
The sysctl command reads and modifies Linux kernel parameters from the command line. Changes take effect immediately…
The whereis command locates the binary, source, and manual page files for a given command. Unlike which, it…