Orchestrator/Test-GraphPermissions.ps1
|
<# .SYNOPSIS Validates Graph API scopes after connection against required scopes. .DESCRIPTION Compares granted scopes from Get-MgContext against the scopes required by selected assessment sections. Warns about missing scopes before collectors run. #> function Test-GraphPermissions { <# .SYNOPSIS Validates Graph API scopes after connection. .DESCRIPTION Compares the scopes granted by Get-MgContext against the scopes required by the selected assessment sections (from sectionScopeMap). Warns about missing scopes before collectors run, so users know which sections may produce incomplete results. With app-only auth (certificate/managed identity), scopes are determined by app registration and Get-MgContext.Scopes may show '.default' only. In this case the check is skipped with an informational message. .PARAMETER RequiredScopes Array of Graph scope strings required for the selected sections. .PARAMETER SectionScopeMap Hashtable mapping section names to their required scope arrays. .PARAMETER ActiveSections Array of section names the user selected. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string[]]$RequiredScopes, [Parameter(Mandatory)] [hashtable]$SectionScopeMap, [Parameter(Mandatory)] [string[]]$ActiveSections ) $context = Get-MgContext -ErrorAction SilentlyContinue if (-not $context) { Write-AssessmentLog -Level WARN -Message 'Graph context not available -- skipping scope validation' -Section 'Setup' return } $grantedScopes = @($context.Scopes) # App-only auth: scopes may be empty or contain only '.default' if ($grantedScopes.Count -eq 0 -or ($grantedScopes.Count -eq 1 -and $grantedScopes[0] -eq '.default')) { Write-Host ' i App-only auth detected -- scope validation not available (permissions set in app registration)' -ForegroundColor DarkGray Write-AssessmentLog -Level INFO -Message 'App-only auth: scope validation skipped (permissions defined in Entra app registration)' -Section 'Setup' return } # Compare required vs granted (case-insensitive) $grantedLower = $grantedScopes | ForEach-Object { $_.ToLower() } $missingScopes = @($RequiredScopes | Where-Object { $_.ToLower() -notin $grantedLower }) if ($missingScopes.Count -eq 0) { Write-Host " $([char]0x2714) All $($RequiredScopes.Count) required Graph scopes granted" -ForegroundColor Green Write-AssessmentLog -Level INFO -Message "Graph scope validation passed ($($RequiredScopes.Count) scopes)" -Section 'Setup' return } # Map missing scopes back to affected sections $affectedSections = @{} foreach ($scope in $missingScopes) { foreach ($section in $ActiveSections) { if (-not $SectionScopeMap.ContainsKey($section)) { continue } $sectionScopes = $SectionScopeMap[$section] | ForEach-Object { $_.ToLower() } if ($scope.ToLower() -in $sectionScopes) { if (-not $affectedSections.ContainsKey($section)) { $affectedSections[$section] = [System.Collections.Generic.List[string]]::new() } $affectedSections[$section].Add($scope) } } } # Display warnings Write-Host '' Write-Host " $([char]0x26A0) $($missingScopes.Count) Graph scope(s) not consented -- some checks may fail:" -ForegroundColor Yellow foreach ($section in $affectedSections.Keys | Sort-Object) { $scopeList = ($affectedSections[$section] | Sort-Object) -join ', ' Write-Host " ${section}: $scopeList" -ForegroundColor Yellow } if ($context.AuthType -eq 'AppOnly') { Write-Host " To fix: add the missing permission(s) to your app registration, then grant admin consent." -ForegroundColor DarkGray Write-Host " Entra ID > App registrations > [your app] > API permissions >" -ForegroundColor DarkGray Write-Host " Add a permission > Microsoft Graph > Application permissions" -ForegroundColor DarkGray Write-Host " Then click 'Grant admin consent for [tenant]' and re-run." -ForegroundColor DarkGray } else { $scopeArg = ($missingScopes | Sort-Object) -join ',' Write-Host " To fix: close this session and re-run the assessment. When the browser opens," -ForegroundColor DarkGray Write-Host " sign in as a Global Admin and click 'Accept' to grant the missing permission(s)." -ForegroundColor DarkGray Write-Host " If consent was already granted by an admin, run in a new PowerShell session:" -ForegroundColor DarkGray Write-Host " Disconnect-MgGraph; Connect-MgGraph -Scopes '$scopeArg'" -ForegroundColor Cyan } Write-Host '' Write-AssessmentLog -Level WARN -Message "Missing Graph scopes: $($missingScopes -join ', ')" -Section 'Setup' } |