Simplify user tasks like bulk creation, updates, password resets, deletions, license checks & more — all from one place.
🚀 Launch ToolkitManaging group ownership in Microsoft 365 is a critical aspect of governance and security. When users own multiple groups, it becomes challenging to track and manage ownership effectively. Without proper visibility, group ownership can become unclear, leading to risks around accountability and compliance.
Tracking users who own multiple groups makes ownership management more transparent and manageable, helping administrators ensure that groups are properly governed and not left unmanaged.
# ============================
# Config
# ============================
# Target user (UPN or ObjectId)
$UserId = "user@yourtenant.onmicrosoft.com" # <-- replace
# Admin mailbox to receive the report
$AdminUPN = "admin@yourtenant.onmicrosoft.com" # <-- replace
# Connect to Microsoft Graph
# Scopes: read user-owned objects/groups + send mail
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All","Directory.Read.All","Mail.Send"
# ============================
# 1) Fetch groups the user OWNS
# ============================
# Pull all directory objects the user owns
$ownedObjects = Get-MgUserOwnedObject -UserId $UserId -All
# Filter for groups only
$ownedGroups = $ownedObjects | Where-Object {
$_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.group'
}
# ============================
# 2) Build report rows with group details + owners count
# ============================
$ReportRows = @()
foreach ($obj in $ownedGroups) {
$groupId = $obj.Id
try {
# Get core group details
$g = Get-MgGroup -GroupId $groupId -Select DisplayName,Id,GroupTypes,MailEnabled,SecurityEnabled,Visibility,MailNickname
# Count owners (to support “Multiple Group Owners Report”)
$owners = Get-MgGroupOwner -GroupId $groupId -All -ErrorAction SilentlyContinue
$ownersCount = @($owners).Count
# Friendly group type
$groupType =
if ($g.GroupTypes -contains "Unified") { "Microsoft 365 Group" }
elseif ($g.SecurityEnabled) { "Security Group" }
elseif ($g.MailEnabled) { "Distribution Group" }
else { "Other" }
$ReportRows += [pscustomobject]@{
GroupDisplayName = $g.DisplayName
GroupId = $g.Id
GroupType = $groupType
MailEnabled = $g.MailEnabled
SecurityEnabled = $g.SecurityEnabled
Visibility = $g.Visibility
MailNickname = $g.MailNickname
OwnersCount = $ownersCount
}
}
catch {
Write-Warning "Could not retrieve details for group with ID: $groupId"
}
}
# Optional: show summary on console
$ReportRows | Sort-Object GroupDisplayName | Format-Table GroupDisplayName, GroupId, GroupType, OwnersCount -AutoSize
# ============================
# 3) Export to CSV
# ============================
$SafeUser = ($UserId -replace '[^\w\.-]', '_')
$ReportPath = "$env:TEMP\UserOwnedGroups_$SafeUser.csv"
$ReportRows |
Sort-Object GroupDisplayName |
Export-Csv -Path $ReportPath -NoTypeInformation -Encoding UTF8
# ============================
# 4) Email the report to the administrator
# ============================
$groupCount = @($ReportRows).Count
$Subject = "Groups Owned by $UserId — $(Get-Date -Format 'yyyy-MM-dd')"
$Body = @"
Hello Admin,
Attached is the report of groups owned by $UserId.
Total groups owned: $groupCount.
This report includes each group's type and the current number of owners (for Multiple Group Owners review).
Regards,
Graph PowerShell Script
"@
# Attach the CSV
$AttachmentContent = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($ReportPath))
$Attachments = @(
@{
"@odata.type" = "#microsoft.graph.fileAttachment"
Name = [System.IO.Path]::GetFileName($ReportPath)
ContentBytes = $AttachmentContent
}
)
# Build the message payload
$Message = @{
Message = @{
Subject = $Subject
Body = @{
ContentType = "HTML"
Content = $Body
}
ToRecipients = @(
@{ EmailAddress = @{ Address = $AdminUPN } }
)
Attachments = $Attachments
}
SaveToSentItems = "true"
}
# Send the email from admin's mailbox
Send-MgUserMail -UserId $AdminUPN -BodyParameter $Message
Write-Host "Owned-groups report for $UserId emailed successfully to $AdminUPN"
| Error | Cause | Solution |
|---|---|---|
| Insufficient privileges to complete the operation | The account lacks required Graph API permissions. | Connect with User.Read.All, Group.Read.All, Directory.Read.All, and Mail.Send. |
| Send-MgUserMail : Resource not found | $AdminUPN is not a valid mailbox. | Replace with a valid admin mailbox in your tenant. |
| Empty CSV File | The user is not an owner of any groups. | Verify user ownership. The script will still generate a valid empty file. |
| Could not retrieve details for group with ID | Object retrieval error or permissions issue. | This warning can be ignored if the object isn’t a group. Ensure proper permissions otherwise. |
This Graph PowerShell script offers administrators an efficient way to track groups owned by a specific user, making it easier to identify when individuals own multiple groups. By automatically exporting and emailing a detailed ownership report, it brings transparency into group ownership, helps highlight potential risks of concentrated ownership, and ensures better compliance and accountability.
With enhancements such as scheduling, multi-user reporting, or deeper ownership insights, this script can evolve into a powerful tool for proactive group ownership management across Microsoft 365.
© m365corner.com. All Rights Reserved. Design by HTML Codex