Public/Discovery/Get-AppRolePermission.ps1
|
using namespace System.Management.Automation function Get-AppRolePermission { [cmdletbinding()] param ( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [ValidatePattern('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$', ErrorMessage = "It does not match expected GUID pattern")] [string]$appRoleId, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string]$appRoleName, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [ValidateSet( 'Application', 'Delegated' )] [string]$Type = 'Application' ) begin { Write-Verbose " Starting function $($MyInvocation.MyCommand.Name)" # Validate appRoleName parameter against available permissions if ($appRoleName -and $script:SessionVariables -and $script:SessionVariables.appRoleIds) { $availablePermissions = $script:SessionVariables.appRoleIds | Where-Object Type -eq $Type | Select-Object -ExpandProperty Permission Write-Verbose "Available app role permissions loaded: $($availablePermissions.Count) total permissions for type '$Type'" if ($appRoleName -notin $availablePermissions) { $errorMessage = "Invalid appRoleName '$appRoleName' for type '$Type'. Valid values are: $($availablePermissions -join ', ')" throw [System.ArgumentException]::new($errorMessage, 'appRoleName') } } elseif ($appRoleName) { Write-Warning "SessionVariables not available for validation. Proceeding without validation." } } process { try { Write-Verbose " Searching for App Role permissions" if ($appRoleName) { Write-Host " Looking up App Role by name: '$appRoleName' (Type: $Type)" -ForegroundColor Cyan $object = ($script:SessionVariables.appRoleIds | Where-Object Permission -eq $appRoleName | Where-Object Type -eq $Type) if ($object) { Write-Host " Found App Role permission: $($object.Permission)" -ForegroundColor Green } else { Write-Host " No App Role found with name '$appRoleName' and type '$Type'" -ForegroundColor Red } } else { Write-Host " Looking up App Role by ID: $appRoleId" -ForegroundColor Cyan $object = ($script:SessionVariables.appRoleIds | Where-Object appRoleId -eq $appRoleId) if ($object) { Write-Host " Found App Role permission: $($object.Permission)" -ForegroundColor Green } else { Write-Host " No App Role found with ID '$appRoleId'" -ForegroundColor Red } } if ($object) { Write-Host " Permission: $($object.Permission)" -ForegroundColor Yellow Write-Host " Type: $($object.Type)" -ForegroundColor Yellow Write-Host " 🆔 App Role ID: $($object.appRoleId)" -ForegroundColor Yellow } return $object } catch { Write-Host " Error retrieving App Role permission: $($_.Exception.Message)" -ForegroundColor Red Write-Message -FunctionName $($MyInvocation.MyCommand.Name) -Message $($_.Exception.Message) -Severity 'Error' } } <# .SYNOPSIS Retrieves the permissions for a specified Microsoft App Role. .DESCRIPTION Retrieves permissions associated with a specified Microsoft App Role. This function queries the session variables to look up the specific permissions granted by an app role, supporting both application and delegated permission types. Helpful for understanding what capabilities are granted by specific app roles in Azure AD. .PARAMETER appRoleId The unique identifier (GUID) of the App Role. Must match the expected GUID pattern. .PARAMETER appRoleName The name of the App Role. Valid values are auto-generated from the session variables. .PARAMETER Type The type of the App Role. Valid values are 'Application' and 'Delegated'. Default is 'Application'. .EXAMPLE Get-AppRolePermission -appRoleId "12345678-1234-1234-1234-1234567890ab" .EXAMPLE Get-AppRolePermission -appRoleName "User.Read" -Type "Delegated" .EXAMPLE Get-MsServicePrincipalsPermissions | Get-AppRolePermission .NOTES This function uses session variables to retrieve the App Role permissions. Ensure that the session variables are properly initialized before calling this function. .LINK MITRE ATT&CK Tactic: TA0007 - Discovery https://attack.mitre.org/tactics/TA0007/ .LINK MITRE ATT&CK Technique: T1069.003 - Permission Groups Discovery: Cloud Groups https://attack.mitre.org/techniques/T1069/003/ #> } # Register argument completer for appRoleName parameter Register-ArgumentCompleter -CommandName Get-AppRolePermission -ParameterName appRoleName -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # Get the Type parameter from bound parameters or use default $type = if ($fakeBoundParameters.ContainsKey('Type')) { $fakeBoundParameters['Type'] } else { 'Application' } if ($script:SessionVariables -and $script:SessionVariables.appRoleIds) { $availablePermissions = $script:SessionVariables.appRoleIds | Where-Object Type -eq $type | Select-Object -ExpandProperty Permission $availablePermissions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } else { # Fallback to common permissions if SessionVariables not available $commonPermissions = @( 'Application.Read.All', 'Application.ReadWrite.All', 'AppRoleAssignment.ReadWrite.All', 'Directory.Read.All', 'Directory.ReadWrite.All', 'User.Read.All', 'User.ReadWrite.All', 'Group.Read.All', 'Group.ReadWrite.All' ) $commonPermissions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } } |