Public/Discovery/Get-PrivilegedApp.ps1
function Get-PrivilegedApp { [cmdletbinding()] param ( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $false)] [int]$ThrottleLimit = 1000 ) begin { Write-Verbose "Starting function $($MyInvocation.MyCommand.Name)" $MyInvocation.MyCommand.Name | Invoke-BlackCat -ResourceTypeName "MSGraph" $result = New-Object System.Collections.ArrayList } process { try { Write-Message -FunctionName $MyInvocation.MyCommand.Name -Message "Collecting Enterprise Applications" -Severity 'Information' $applications = Invoke-MsGraph -relativeUrl "applications" Write-Verbose "User Applications: $($applications.count)" Write-Verbose " [-] Validating [$($applications.count)] Enterprise Applications" $riskyGrants = $sessionVariables.appRoleIds | Where-Object Permission -in @( 'Directory.ReadWrite.All', 'PrivilegedAccess.ReadWrite.AzureAD', 'PrivilegedAccess.ReadWrite.AzureADGroup', 'PrivilegedAccess.ReadWrite.AzureResources', 'Policy.ReadWrite.ConditionalAccess', 'GroupMember.ReadWrite.All', 'Group.ReadWrite.All', 'RoleManagement.ReadWrite.Directory' ) $applications | ForEach-Object -Parallel { $riskyGrants = $using:riskyGrants $result = $using:result $header = $using:script:graphHeader $permissionObjects = @() foreach ($riskyGrant in $riskyGrants) { if ($_.requiredResourceAccess.resourceAccess.id -contains $riskyGrant.appRoleId) { $permissionObjects += $riskyGrant.Permission } } if ($permissionObjects.Count -gt 0) { $currentItem = [PSCustomObject]@{ Id = $_.Id DisplayName = $_.DisplayName CreatedDateTime = $_.CreatedDateTime Permission = $permissionObjects | Sort-Object -Unique Owners = (Invoke-RestMethod -Uri "https://graph.microsoft.com/beta/applications/$($_.Id)/owners" -Headers $header).value.UserPrincipalName } if ($_.PasswordCredentials.KeyId) { $currentItem | Add-Member -MemberType NoteProperty -Name Credentials -Value $_.PasswordCredentials -Force } if ($_.KeyCredentials.Value) { $currentItem | Add-Member -MemberType NoteProperty -Name KeyCredentials -Value $_.KeyCredentials -Force } [void]$result.Add($currentItem) } } -ThrottleLimit $ThrottleLimit $json = [ordered]@{} [void]$json.Add("data", $result) return $json.Values } catch { Write-Message -FunctionName $MyInvocation.MyCommand.Name -Message $_.Exception.Message -Severity 'Error' } } end { Write-Verbose "Completed function $($MyInvocation.MyCommand.Name)" } <# .SYNOPSIS Retrieves Microsoft Entra ID (Azure AD) applications with privileged permissions. .DESCRIPTION The Get-PrivilegedApp function identifies and returns Enterprise Applications that have been granted high-risk permissions in Microsoft Entra ID. It specifically looks for applications with permissions such as Directory.ReadWrite.All, PrivilegedAccess.ReadWrite.AzureAD, and other sensitive permissions that could pose security risks. .PARAMETER ThrottleLimit Specifies the maximum number of concurrent operations that can be performed in parallel. Default value is 1000. .OUTPUTS Returns an array of PSCustomObjects containing the following properties: - Id: The unique identifier of the applicationc - DisplayName: The display name of the application - CreatedDateTime: When the application was created - Permission: Array of high-risk permissions granted to the application - Credentials: (Optional) If present, contains password credentials information - KeyCredentials: (Optional) If present, contains certificate credentials information .EXAMPLE Get-PrivilegedApp Returns all applications with high-risk permissions using default throttle limit. .EXAMPLE Get-PrivilegedApp -ThrottleLimit 500 Returns all applications with high-risk permissions using a custom throttle limit of 500. .EXAMPLE Get-PrivilegedApp -Verbose Returns all applications with high-risk permissions with detailed progress information. .NOTES File: Get-PrivilegedApp.ps1 Author: Script Author Version: 1.0 Requires: PowerShell 7.0 or later Requires: Microsoft Graph API access Requires: Appropriate permissions to read application information The function checks for the following high-risk permissions: - Directory.ReadWrite.All - PrivilegedAccess.ReadWrite.AzureAD - PrivilegedAccess.ReadWrite.AzureADGroup - PrivilegedAccess.ReadWrite.AzureResources - Policy.ReadWrite.ConditionalAccess - GroupMember.ReadWrite.All - Group.ReadWrite.All - RoleManagement.ReadWrite.Directory #> } |