Enterprise applications (service principals) are usually created for SaaS access, automation, and integrations across Microsoft 365. Over time, tenants collect apps from pilots, third-party deployments, and legacy projects. A common governance gap is enterprise apps that have no owners assigned.
Apps without owners create real operational and security pain points:
This Graph PowerShell script finds all enterprise applications with zero owners, generates a clean report, exports an Excel-safe CSV, and emails it automatically to administrators or stakeholders.
Try the M365Corner Microsoft 365 Reporting Tool — your DIY pack with 20+ out-of-the-box M365 reports for Users, Groups, and Teams.
$SenderUPN = "admin@yourtenant.onmicrosoft.com"
$Recipients = @(
"admin@yourtenant.onmicrosoft.com",
"securityteam@yourtenant.onmicrosoft.com"
)
Connect-MgGraph -Scopes "Application.Read.All","Directory.Read.All","Mail.Send"
$ServicePrincipals = Get-MgServicePrincipal -All -Property Id,DisplayName,AppId,ServicePrincipalType,AccountEnabled
$Report = @()
foreach ($sp in $ServicePrincipals) {
try {
$Owners = Get-MgServicePrincipalOwner -ServicePrincipalId $sp.Id -All -ErrorAction Stop
} catch {
$Owners = @()
}
if (-not $Owners -or $Owners.Count -eq 0) {
$Report += [PSCustomObject]@{
"Enterprise App Name" = $sp.DisplayName
"AppId" = $sp.AppId
"ServicePrincipalId" = $sp.Id
"ServicePrincipalType" = $sp.ServicePrincipalType
"Account Enabled" = if ($sp.AccountEnabled) { "Enabled" } else { "Disabled" }
"Owner Count" = 0
}
}
}
$ReportPath = "$env:TEMP\EnterpriseApps_WithoutOwners.csv"
if ($Report.Count -gt 0) {
$Report | Sort-Object "Enterprise App Name" |
Export-Csv -Path $ReportPath -NoTypeInformation -Encoding utf8
} else {
"No enterprise applications without owners were found." |
Set-Content -Path $ReportPath -Encoding utf8
}
$Bytes = [System.IO.File]::ReadAllBytes($ReportPath)
$Utf8Bom = New-Object System.Text.UTF8Encoding($true)
[System.IO.File]::WriteAllText($ReportPath, [System.Text.Encoding]::UTF8.GetString($Bytes), $Utf8Bom)
$Count = $Report.Count
$Subject = "Enterprise Applications Without Owners — $(Get-Date -Format 'yyyy-MM-dd')"
$Body = @"
Hello Team,<br><br>
Attached is the <b>Enterprise Applications Without Owners</b> report.<br>
These service principals have zero assigned owners and should be reviewed for governance.<br><br>
Total unowned enterprise apps found: <b>$Count</b><br><br>
Regards,<br>
Graph PowerShell Automation
"@
$AttachmentContent = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($ReportPath))
$Attachments = @(
@{
"@odata.type" = "#microsoft.graph.fileAttachment"
Name = "EnterpriseApps_WithoutOwners.csv"
ContentBytes = $AttachmentContent
}
)
$ToRecipients = $Recipients | ForEach-Object {
@{ EmailAddress = @{ Address = $_ } }
}
$Message = @{
Message = @{
Subject = $Subject
Body = @{
ContentType = "HTML"
Content = $Body
}
ToRecipients = $ToRecipients
Attachments = $Attachments
}
SaveToSentItems = "true"
}
Send-MgUserMail -UserId $SenderUPN -BodyParameter $Message
Write-Host "Unowned enterprise applications report emailed successfully." -ForegroundColor Green
If the result is empty, the app is treated as “unowned.”
| Error | Cause | Solution |
|---|---|---|
| Authorization_RequestDenied / 403 | Missing Graph permissions. | Grant admin consent and reconnect with:
|
| Report is empty | Every enterprise app has at least one owner. | Valid scenario; script writes a friendly message instead. |
| Throttling in large tenants | Many apps → many owner calls. | Rerun later or batch requests if needed. |
| Owner lookup warnings | Some objects may not allow ownership retrieval. | Script handles this by treating lookup failures as “no owners” and continuing. |
Enterprise applications without owners are a governance blind spot. They can remain enabled indefinitely without accountability, increasing security and operational risk.
This Graph PowerShell script provides a simple automated way to detect unowned enterprise apps, generate an Excel-friendly report, and email it to administrators. Running it regularly keeps enterprise app ownership transparent and audit-ready.
© m365corner.com. All Rights Reserved. Design by HTML Codex