Private/Invoke-RBACGraphGuardProbe.ps1

function Invoke-RBACGraphGuardProbe {
    <#
    .SYNOPSIS
        Enriches advisory Microsoft Graph / Entra guardrails with live detection.
    .DESCRIPTION
        Internal. Promotes the Entra identity guardrails that can be inspected via
        Microsoft Graph - Conditional Access policies and PIM-eligible directory
        roles - from 'Potential' to 'Blocking'/'Potential'/'Clear' with concrete
        evidence. Conditional Access applicability cannot be fully evaluated
        offline (it depends on sign-in signals), so an enabled policy targeting the
        principal surfaces as 'Potential' with the policy name rather than a hard
        'Blocking'. Every probe is best-effort and StrictMode-safe: a missing
        Microsoft.Graph cmdlet or a query error leaves the guard at its advisory
        state.
    .PARAMETER Guard
        The advisory guards (PSAutoRBAC.Guard) for the Microsoft Graph platform.
    .PARAMETER CallerId
        The identity (object id) whose eligible directory roles are inspected.
    .PARAMETER Context
        Optional PSAutoRBAC.Context (unused for Graph today; reserved).
    .OUTPUTS
        PSCustomObject (PSAutoRBAC.Guard)
    #>

    [CmdletBinding()]
    [OutputType([psobject])]
    param(
        [Parameter(Mandatory)] [AllowEmptyCollection()] [psobject[]]$Guard,
        [Parameter()] [string]$CallerId,
        [Parameter()] [psobject]$Context
    )

    $get = { param($o, $n) if ($o -and ($o.PSObject.Properties.Name -contains $n)) { $o.$n } }

    $byType = @{}
    foreach ($g in $Guard) { $byType[$g.GuardType] = $g }

    # 1) Conditional Access - enabled policies are potential gates at token issuance.
    if ($byType.ContainsKey('ConditionalAccess') -and (Get-Command -Name 'Get-MgIdentityConditionalAccessPolicy' -ErrorAction SilentlyContinue)) {
        $g = $byType['ConditionalAccess']
        try {
            $enabled = @(Get-MgIdentityConditionalAccessPolicy -ErrorAction SilentlyContinue |
                Where-Object { (& $get $_ 'State') -eq 'enabled' })
            if ($enabled.Count -gt 0) {
                $g.Status = 'Potential'; $g.Source = 'Live'
                $g.Evidence = @($enabled | ForEach-Object { "CA policy '$(& $get $_ 'DisplayName')'" } | Select-Object -First 10)
                Write-PSFMessage -Level Verbose -Message "Guard(Graph): $($enabled.Count) enabled Conditional Access policy/policies may gate '$CallerId'." -Tag 'PSAutoRBAC', 'Guard', 'Graph'
            }
            else { $g.Status = 'Clear'; $g.Source = 'Live' }
        }
        catch { Write-PSFMessage -Level Verbose -Message "Guard(Graph): Conditional Access probe failed ($($_.Exception.Message)); leaving advisory." -Tag 'PSAutoRBAC', 'Guard', 'Graph' }
    }

    # 2) PIM - directory role assigned as eligible (needs activation to be effective).
    if ($byType.ContainsKey('PrivilegedIdentityManagement') -and $CallerId -and
        (Get-Command -Name 'Get-MgRoleManagementDirectoryRoleEligibilitySchedule' -ErrorAction SilentlyContinue)) {
        $g = $byType['PrivilegedIdentityManagement']
        try {
            $eligible = @(Get-MgRoleManagementDirectoryRoleEligibilitySchedule -Filter "principalId eq '$CallerId'" -ErrorAction SilentlyContinue)
            if ($eligible.Count -gt 0) {
                $g.Status = 'Potential'; $g.Source = 'Live'
                $g.Evidence = @($eligible | ForEach-Object {
                    $r = & $get $_ 'RoleDefinitionId'
                    "eligible directory role '$r' (activate before use)"
                })
                Write-PSFMessage -Level Significant -Message "Guard(Graph): '$CallerId' has $($eligible.Count) PIM-eligible directory role(s) requiring activation." -Tag 'PSAutoRBAC', 'Guard', 'Graph'
            }
            else { $g.Status = 'Clear'; $g.Source = 'Live' }
        }
        catch { Write-PSFMessage -Level Verbose -Message "Guard(Graph): PIM probe failed ($($_.Exception.Message)); leaving advisory." -Tag 'PSAutoRBAC', 'Guard', 'Graph' }
    }

    $Guard
}