Entra/Get-EntraPrivRemoteConfig.ps1
|
<# .SYNOPSIS Evaluates whether PIM is configured for privileged roles to restrict remote execution of privileged commands. .DESCRIPTION Checks whether Privileged Identity Management (PIM) is used for critical admin roles so that permanent standing access is eliminated. Users must activate roles with justification and approval rather than holding persistent assignments. Verifies that Global Administrator and other critical roles have minimal or zero permanent active assignments. Requires an active Microsoft Graph connection with RoleManagement.Read.Directory and PrivilegedAccess.Read.AzureAD permissions. .PARAMETER OutputPath Optional path to export results as CSV. If not specified, results are returned to the pipeline. .EXAMPLE PS> .\Entra\Get-EntraPrivRemoteConfig.ps1 Displays PIM privileged remote access evaluation results. .EXAMPLE PS> .\Entra\Get-EntraPrivRemoteConfig.ps1 -OutputPath '.\entra-privremote-config.csv' Exports the evaluation to CSV. .NOTES Author: Daren9m CMMC: AC.L2-3.1.15 — Authorize Remote Execution of Privileged Commands #> [CmdletBinding()] param( [Parameter()] [ValidateNotNullOrEmpty()] [string]$OutputPath ) $ErrorActionPreference = 'Stop' $_scriptDir = if ($MyInvocation.MyCommand.Path) { Split-Path -Parent $MyInvocation.MyCommand.Path } else { $PSScriptRoot } . (Join-Path -Path $_scriptDir -ChildPath '..\Common\SecurityConfigHelper.ps1') $ctx = Initialize-SecurityConfig $settings = $ctx.Settings $checkIdCounter = $ctx.CheckIdCounter function Add-Setting { param( [string]$Category, [string]$Setting, [string]$CurrentValue, [string]$RecommendedValue, [string]$Status, [string]$CheckId = '', [string]$Remediation = '' ) $p = @{ Settings = $settings CheckIdCounter = $checkIdCounter Category = $Category Setting = $Setting CurrentValue = $CurrentValue RecommendedValue = $RecommendedValue Status = $Status CheckId = $CheckId Remediation = $Remediation } Add-SecuritySetting @p } # ------------------------------------------------------------------ # Well-known role template IDs for critical roles # ------------------------------------------------------------------ $globalAdminRoleId = '62e90394-69f5-4237-9190-012177145e10' # ------------------------------------------------------------------ # 1. Check for permanent vs eligible Global Admin assignments # ------------------------------------------------------------------ try { Write-Verbose 'Checking Global Admin role assignments for PIM usage...' # Get active (permanent) assignments $activeParams = @{ Method = 'GET' Uri = "/v1.0/roleManagement/directory/roleAssignments?`$filter=roleDefinitionId eq '$globalAdminRoleId'" ErrorAction = 'Stop' } $activeAssignments = Invoke-MgGraphRequest @activeParams $permanentCount = 0 if ($activeAssignments -and $activeAssignments['value']) { $permanentCount = @($activeAssignments['value']).Count } # Try to get eligible (PIM) assignments via v1.0 endpoint $eligibleCount = 0 $eligibleNote = $null try { $eligibleParams = @{ Method = 'GET' Uri = "/v1.0/roleManagement/directory/roleEligibilityScheduleInstances?`$filter=roleDefinitionId eq '$globalAdminRoleId'" ErrorAction = 'Stop' } $eligibleAssignments = Invoke-MgGraphRequest @eligibleParams if ($eligibleAssignments -and $eligibleAssignments['value']) { $eligibleCount = @($eligibleAssignments['value']).Count } } catch { # Silent degradation replaced with Review status $eligibleNote = 'PIM eligible assignments not available (requires Entra ID P2)' Write-Verbose "Could not query PIM eligible assignments: $_" } $pimInUse = $eligibleCount -gt 0 $currentValue = if ($null -ne $eligibleNote) { "Permanent: $permanentCount, Eligible (PIM): $eligibleNote" } else { "Permanent: $permanentCount, Eligible (PIM): $eligibleCount" } # Pass if PIM eligible assignments exist and permanent assignments are minimal (break-glass only) $passCondition = $pimInUse -and ($permanentCount -le 2) $privStatus = if ($null -ne $eligibleNote) { 'Review' } elseif ($passCondition) { 'Pass' } elseif ($pimInUse) { 'Warning' } else { 'Fail' } $settingParams = @{ Category = 'Privileged Remote Access' Setting = 'PIM Required for Global Admin Activation' CurrentValue = $currentValue RecommendedValue = 'PIM enabled with eligible assignments; max 2 permanent (break-glass)' Status = $privStatus CheckId = 'ENTRA-PRIVREMOTE-001' Remediation = 'Enable Entra ID PIM. Convert permanent role assignments to eligible. Configure activation to require justification and MFA. Entra admin center > Identity Governance > Privileged Identity Management > Entra ID roles.' } Add-Setting @settingParams } catch { if ($_.Exception.Message -match '403|Forbidden|Authorization') { $settingParams = @{ Category = 'Privileged Remote Access' Setting = 'PIM Required for Global Admin Activation' CurrentValue = 'Insufficient permissions' RecommendedValue = 'PIM enabled with eligible assignments; max 2 permanent (break-glass)' Status = 'Review' CheckId = 'ENTRA-PRIVREMOTE-001' Remediation = 'Requires RoleManagement.Read.Directory permission. Entra ID P2 license required for PIM.' } Add-Setting @settingParams } else { Write-Warning "Could not check PIM configuration: $_" } } # ------------------------------------------------------------------ # Output results # ------------------------------------------------------------------ Export-SecurityConfigReport -Settings $settings -OutputPath $OutputPath -ServiceLabel 'Entra Priv Remote' |