221 lines
11 KiB
PowerShell
Raw Permalink Normal View History

<#
=============================================================================================
Name: Get All Enterprise Applications with Their Permissions
Version: 1.0
Website: blog.admindroid.com
Script Highlights:
~~~~~~~~~~~~~~~~~
1. Exports all enterprise apps along with its API permissions in Microsoft Entra.
2. The script installs MS Graph PowerShell SDK (if not installed already) upon your confirmation.
3. Allows to filter applications with specific permissions (eg.,"User.Read.All") assigned.
-> Admin consented app permissions
-> Admin consented delegated permissions
-> User consented permissions
4. Fetches the list of ownerless applications in Microsoft Entra.
5. Find Entra app permissions granted thorough user consent and admin consent.
6. Generates report for sign-in enabled and disabled applications.
7. Assists in filtering based on following properties:
-> Application Name
-> Application Id
-> Object Id
-> API Name
8. Filters apps that are restricted to specific users and accessible to all users.
9. Lists applications that are hidden and visible to all users in the organization.
10. Assists in filtering home tenant and external tenant applications.
11. Allows to retrieve enterprise apps with no permissions too.
12. Exports the result to CSV.
13. The script can be executed with an MFA enabled account too.
14. It can be executed with certificate-based authentication (CBA) too.
15. The script is schedular-friendly.
For detailed Script execution: https://blog.admindroid.com/export-all-enterprise-apps-and-their-assigned-permission-in-microsoft-entra/
============================================================================================
#>
Param (
[Parameter(Mandatory = $false)]
[switch]$CreateSession,
[string]$TenantId,
[string]$ClientId,
[string]$CertificateThumbPrint,
[string]$ApplicationId,
[string]$ApplicationName,
[string]$ObjectId,
[string]$APIName,
[ValidateSet("VisibleApps","HiddenApps")]
[string]$AppVisibility,
[ValidateSet("HomeTenant","ExternalTenant")]
[string]$AppOrigin,
[ValidateSet("Enabled", "Disabled")]
[string]$UsersSignIn,
[ValidateSet("AdminConsent", "UserConsent")]
[string]$ConsentType,
[string[]]$AdminConsentApplicationPermissions,
[string[]]$AdminConsentDelegatedPermissions,
[string[]]$UserConsents,
[switch]$AccessScopeToAllUsers,
[switch]$RoleAssignmentRequiredApps,
[switch]$OwnerlessApps,
[switch]$IncludeAppsWithNoPermissions
)
function Connect_MgGraph {
$MsGraphModule = Get-Module Microsoft.Graph -ListAvailable
if ($MsGraphModule -eq $null) {
Write-Host "`nImportant: Microsoft Graph module is unavailable. It is mandatory to have this module installed in the system to run the script successfully."
$confirm = Read-Host "Are you sure you want to install Microsoft Graph module? [Y] Yes [N] No"
if ($confirm -match "[yY]") {
Write-Host "Installing Microsoft Graph Module..."
Install-Module Microsoft.Graph -Scope CurrentUser -AllowClobber -Force
}
else {
Write-Host "Microsoft Graph PowerShell module is required to run this script. Please install module using 'Install-Module Microsoft.Graph' cmdlet."
Exit
}
}
if ($CreateSession.IsPresent) {
Disconnect-MgGraph
}
Write-Host "`nConnecting to Microsoft Graph..."
if (($TenantId -ne "") -and ($ClientId -ne "") -and ($CertificateThumbPrint -ne "")) {
Connect-MgGraph -TenantId $TenantId -AppId $ClientId -CertificateThumbprint $CertificateThumbPrint -NoWelcome
}
else {
Connect-MgGraph -Scopes "Application.Read.All" -NoWelcome
}
}
Connect_MgGraph
$ExportCSV = "$(Get-Location)\EnterpriseApps_and_their_Permissions_report_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm-ss` tt).ToString()).csv"
$TenantGUID= (Get-MgOrganization).Id
Write-Host "`nRetreiving the Enterprise applications with admin consents and user consents"
$AppCount = 0
$PrintCount = 0
Get-MgServicePrincipal -All | ForEach-Object {
$Print = 1
$AppCount++
$ServicePrincipalType = $_.ServicePrincipalType
$AppName = $_.DisplayName
Write-Progress -Activity "Processed Enterprise apps: $($AppCount) $($AppName)"
$AppId = $_.AppId
$ObjId = $_.Id
$CreatedDateTime = [datetime]@($_.AdditionalProperties.Values)[0]
$AccountEnabled = if ($_.AccountEnabled) { "Enabled" } else { "Disabled" }
$Owners = (Get-MgServicePrincipalOwner -ServicePrincipalId $_.Id | ForEach-Object { $_.AdditionalProperties["displayName"] }) -join ", "
$Tags = $_.Tags
$IsRoleAssignmentRequired = $_.AppRoleAssignmentRequired
if (-not $Owners) { $Owners = "-" }
if ($Tags -contains "HideApp") { $UserVisibility="Hidden" }
else { $UserVisibility="Visible" }
if ($IsRoleAssignmentRequired -eq $true){ $AccessScope="Only assigned users can access" }
else { $AccessScope="All users can access" }
$AppOwnerOrgId=$_.AppOwnerOrganizationId
if ($AppOwnerOrgId -eq $TenantGUID){ $AppOrg="Home tenant" }
else { $AppOrg="External tenant" }
if (($ApplicationId.Length -ne 0) -and ($ApplicationId -ne $AppId)) { $Print = 0 }
if (($ApplicationName.Length -ne 0) -and ($ApplicationName -ne $AppName)) { $Print = 0 }
if (($ObjectId.Length -ne 0) -and ($ObjectId -ne $ObjId)) { $Print = 0 }
if ($UsersSignIn -eq "Enabled" -and $_.AccountEnabled -ne $true) { $Print = 0 }
if ($UsersSignIn -eq "Disabled" -and $_.AccountEnabled -ne $false) { $Print = 0 }
if (($AppVisibility -eq "VisibleApps") -and ($UserVisibility -ne "Visible")){ $Print=0 }
if (($AppVisibility -eq "HiddenApps") -and ($UserVisibility -ne "Hidden")){ $Print=0 }
if (($AccessScopeToAllUsers.IsPresent) -and ($AccessScope -eq "Only assigned users can access")){ $Print=0 }
if (($RoleAssignmentRequiredApps.IsPresent) -and ($AccessScope -eq "All users can access")){ $Print=0 }
if (($OwnerlessApps.IsPresent) -and ($Owners -ne "-")){ $Print=0 }
if ($AppOrigin -eq "HomeTenant" -and ($AppOrg -eq "External tenant")){ $Print=0 }
if ($AppOrigin -eq "ExternalTenant" -and ($AppOrg -eq "Home tenant")){ $Print=0 }
$DelegatedGrants = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $ObjId -All
$AppAssignments = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ObjId -All
$AllAPIids = @($DelegatedGrants.ResourceId; $AppAssignments.ResourceId) | Sort-Object -Unique
if (-not $AllAPIids) { $AllAPIids = @('-') }
foreach ($ResourceId in $AllAPIids) {
if ($ResourceId -eq '-') {
$ResourceName = '-'
$AdminDelegated = '-'
$UserDelegated = '-'
$AdminApps = '-'
}
else {
$ResourceSp = Get-MgServicePrincipal -ServicePrincipalId $ResourceId
$ResourceName = $ResourceSp.DisplayName
$AdminDelegated = $DelegatedGrants | Where-Object { $_.ResourceId -eq $ResourceId -and $_.ConsentType -eq "AllPrincipals" } | ForEach-Object{ $_.Scope.Trim()}
$AdminDelegated = if(-not $AdminDelegated) {"-"} else {$AdminDelegated -split "\s+" -join ", "}
$UserDelegated = $DelegatedGrants | Where-Object { $_.ResourceId -eq $ResourceId -and $_.ConsentType -eq "Principal" } | ForEach-Object {$_.Scope.Trim()}
$UserDelegated = if(-not $UserDelegated){"-"} else {$UserDelegated -split "\s+" -join ", "}
$AdminApps = $AppAssignments | Where-Object { $_.ResourceId -eq $ResourceId } |
ForEach-Object {
$role = $ResourceSp.AppRoles | Where-Object Id -eq $_.AppRoleId
if ($role) { $role.Value }
}
$AdminApps = if(-not $AdminApps){"-"} else {$AdminApps -join ", "}
}
if ((-not $IncludeAppsWithNoPermissions.IsPresent) -and ($AdminDelegated[0] -eq "-" -and $AdminApps[0] -eq "-" -and $UserDelegated[0] -eq "-")) { $Print = 0 }
if ($AdminConsentApplicationPermissions -and ((($AdminApps -split ", ") | Where-Object { $_ -in $AdminConsentApplicationPermissions }).Count -eq 0)) { $Print = 0 }
if ($AdminConsentDelegatedPermissions -and ((($AdminDelegated -split ", ") | Where-Object { $_ -in $AdminConsentDelegatedPermissions}).Count -eq 0)) { $Print = 0 }
if ($UserConsents -and ((($UserDelegated -split ", ") | Where-Object {$_ -in $UserConsents}).Count -eq 0)) { $Print = 0 }
if (($APIName.Length -ne 0) -and ($APIName -ne $ResourceName)) { $Print = 0 }
if ($ConsentType -eq "AdminConsent" -and $UserDelegated -ne '-') { $Print = 0 }
if ($ConsentType -eq "UserConsent" -and ($AdminApps -ne '-' -or $AdminDelegated -ne '-')) { $Print = 0 }
if ($Print -eq 1){
$PrintCount++
[PSCustomObject]@{
'App Name' = $AppName
'Object Id'= $ObjId
'API Name' = $ResourceName
'Admin Consented App Permissions' = $AdminApps
'Admin Consented Delegated Permissions' = $AdminDelegated
'User Consented Permissions' = $UserDelegated
'Owners' = $Owners
'Users Sign In' = $AccountEnabled
'User Visibility'= $UserVisibility
'Role Assignment Required'= $AccessScope
'Service Principal Type'= $ServicePrincipalType
'App Id' = $AppId
'App Origin'= $AppOrg
'App Org Id'= $AppOwnerOrgId
'API Id' = $ResourceId
'Created Date' = $CreatedDateTime
} | Export-Csv -Path $ExportCSV -Append -NoTypeInformation
}
}
}
Disconnect-MgGraph | Out-Null
Write-Host `nScript executed successfully.
Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green
Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to access 3,000+ reports and 450+ management actions across your Microsoft 365 environment. ~~" -ForegroundColor Green `n`n
if(((Test-Path -Path $ExportCSV) -eq "True"))
{
Write-Host `nThe script processed $AppCount enterprise apps and the output file contains $PrintCount records.
$Prompt = New-Object -ComObject wscript.shell
$UserInput = $Prompt.popup("Do you want to open output file?",` 0,"Open Output File",4)
if ($UserInput -eq 6)
{
Invoke-Item "$ExportCSV"
}
Write-Host "The generated report is available in: " -NoNewline -ForegroundColor Yellow; Write-Host "$($ExportCSV)"
}
else
{
Write-Host "No user found" -ForegroundColor Red
}