-
Notifications
You must be signed in to change notification settings - Fork 0
Get EnterpriseAppUsage
Get-EnterpriseAppUsage.ps1 reports usage and ownership of all Azure AD Enterprise Applications (App Registrations) in a tenant. It retrieves each app's sign-in activity for a configurable timeframe, identifies application owners, and surfaces which apps are active vs. potentially stale. Results can be exported to JSON for further analysis.
- Full App Inventory - Retrieves all app registrations across the tenant
- Sign-In Activity - Correlates each app with audit sign-in events for a configurable number of days
- Owner Identification - Lists owner UPN, name, and Object ID for each app
- Unowned App Detection - Flags apps with no registered owners
- Throttle Handling - Implements automatic retry with back-off on 429 rate limit responses
-
JSON Export - Optional export of all data to
EnterpriseAppUsage.json - Client or Interactive Auth - Supports both app-only and interactive authentication
- PowerShell 5.1 or later
-
Microsoft.Graph(auto-installed if missing) -
MSAL.PS(installed by Get-GraphToken)
-
Get-GraphToken- Token acquisition -
Get-GraphHeaders- Authorization headers -
Get-AzureResourcePaging- Paginated app retrieval
| Permission | Type | Purpose |
|---|---|---|
AuditLog.Read.All |
Application | Read sign-in activity |
Directory.Read.All |
Application | Read app registrations and owners |
Type: String
Required: Yes
Description: The Azure AD tenant ID to authenticate against.
Type: String
Required: No
Description: The app registration client ID. Omit to use interactive authentication.
Type: String
Required: No
Description: Client secret for app-only authentication. Omit for interactive flow.
Type: Integer
Required: No
Default: 30
Description: Number of days to look back for sign-in activity. Larger values increase execution time.
Type: Switch
Required: No
Description: If specified, exports all app data to EnterpriseAppUsage.json in the current directory.
Get-EnterpriseAppUsage `
-TenantId "12345678-1234-1234-1234-123456789012" `
-ClientId "abcdefab-1234-1234-1234-abcdefabcdef" `
-ClientSecret "your-secret"Get-EnterpriseAppUsage `
-TenantId "12345678-1234-1234-1234-123456789012" `
-ClientId "abcdefab-1234-1234-1234-abcdefabcdef" `
-ClientSecret "your-secret" `
-TimeFrame 60 `
-exportGet-EnterpriseAppUsage `
-TenantId "12345678-1234-1234-1234-123456789012"# Get results and filter locally
Get-EnterpriseAppUsage `
-TenantId "12345678-1234-1234-1234-123456789012" `
-ClientId "<client-id>" `
-ClientSecret "<secret>" `
-TimeFrame 90 `
-export
# After export, analyze the JSON to identify stale apps
$data = Get-Content "EnterpriseAppUsage.json" | ConvertFrom-Json
$staleApps = $data | Where-Object { $_."Usage Count" -eq 0 -and $_."Owner UPN" -eq "NONE" }
$staleApps | Select-Object "App Name", "App AppID" | Format-TableDisplays a sorted table of apps by usage count:
App Name Owner UPN Usage Count
-------- --------- -----------
Contoso-Sales-App john.smith@contoso.com 247
Power BI Service admin@contoso.com 198
Legacy-HR-System NONE 0
Full data including App ID, App AppID, Owner details, and usage counts:
[
{
"App ID": "...",
"App AppID": "...",
"App Name": "Contoso-Sales-App",
"Owner UPN": "john.smith@contoso.com",
"Owner Name": "John Smith",
"Owner ID": "...",
"Usage Count": 247
}
]Message: Required permissions: AuditLog.Read.All and Directory.Read.All
Solution: Ensure the app registration has both AuditLog.Read.All and Directory.Read.All with admin consent granted.
Cause: Rate throttling on the sign-in audit API. The script automatically handles 429 retry with back-off (up to 5 retries).
Solution:
- Reduce
TimeFrameto minimize API calls - Run during off-peak hours
-
Start-Sleep -Seconds 1is built in between each app to reduce throttling
Cause: Persistent throttling from the audit log API.
Solution: Reduce TimeFrame or split the operation across multiple runs filtering by app ID range.
Cause: Missing Directory.Read.All permission prevents reading app registrations.
Solution: Grant Directory.Read.All application permission with admin consent in Azure Portal.
- Get-GraphToken - Token acquisition
- Get-GraphHeaders - Authorization headers
- Get-AzureResourcePaging - Used internally for app paging
- v1.0 (2025-06-25) - Initial public release
- Overview
- Start-LyncCsvExporter
- Get-ComprehensiveLyncReport
- Get-LyncHealthReport
- Get-LyncInfrastructureReport
- Get-LyncServiceStatus
- Get-LyncUserRegistrationReport
- Export-ADLyncTeamsMigrationData
- New-Office365Accounts
- Sync-ContactsFromCsv
- Set-EmailToSharedAccount
- Set-SMTPForward
- Invoke-UserSignOutAndBlock
- Security Assessment Scripts (coming soon)
- Azure Automation (documentation pending)
- Get-GraphToken
- Get-GraphHeaders
- Get-AzureResourcePaging
- Get-EnterpriseAppUsage
- Get-ExchangeErrorsGraph
- Get-PBIWorkspaceUsageReport
- Intune Management (documentation pending)