Public/Test-RBACAccess.ps1

function Test-RBACAccess {
    <#
    .SYNOPSIS
        Tests whether a caller holds the required role(s) on a platform at a scope.
 
    .DESCRIPTION
        Dispatches to the platform provider to evaluate the target caller's
        effective access, non-destructively:
 
          * Azure - matches Get-AzRoleAssignment against the scope and its
                      ancestors (an ancestor assignment satisfies a child scope).
          * Graph - compares required permissions to the connected identity's
                      consented scopes (Get-MgContext) or supplied -RoleAssignment.
          * Fabric - lists workspace role assignments; a higher workspace role
                      satisfies a lower requirement (Admin > Member > Contributor
                      > Viewer).
          * Purview - reads the account's metadata policies for the caller's roles.
 
        Pass -RoleAssignment to evaluate fully offline (no live calls), which is
        how the test suite and CI dry-runs operate. HasAccess is $null when the
        provider could not evaluate access (e.g. missing scope for Fabric).
 
    .PARAMETER Platform
        Platform name or alias.
 
    .PARAMETER CallerId
        The identity being evaluated (UPN, sign-in name, or object id).
 
    .PARAMETER RequiredRole
        One or more role names the caller is expected to hold.
 
    .PARAMETER Scope
        The scope to evaluate at: an ARM scope (Azure), workspace id (Fabric),
        account endpoint (Purview), or 'Tenant'/'/' (Graph).
 
    .PARAMETER RoleAssignment
        Optional pre-fetched assignments/roles for offline evaluation.
 
    .PARAMETER Options
        Optional provider hashtable (e.g. @{ WorkspaceId = '...'; Collection = '...' }).
 
    .PARAMETER TenantId
        Optional tenant id.
 
    .PARAMETER RunAsCredential
        Evaluate as a user credential rather than the ambient session.
 
    .PARAMETER RunAsServicePrincipal
        Evaluate as a service principal (with -RunAsTenantId).
 
    .PARAMETER RunAsTenantId
        Tenant for service-principal run-as.
 
    .PARAMETER RunAsManagedIdentity
        Evaluate as a managed identity.
 
    .PARAMETER RunAsManagedIdentityClientId
        Client id for a user-assigned managed identity.
 
    .EXAMPLE
        Test-RBACAccess -Platform Azure -CallerId a@b.com -RequiredRole Reader `
            -Scope /subscriptions/SUB1
 
    .OUTPUTS
        PSCustomObject (PSAutoRBAC.AccessState) per required role.
    #>

    [CmdletBinding()]
    [OutputType([pscustomobject])]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Platform,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$CallerId,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string[]]$RequiredRole,

        [Parameter()]
        [string]$Scope,

        [Parameter()]
        [object[]]$RoleAssignment,

        [Parameter()]
        [hashtable]$Options,

        [Parameter()]
        [string]$TenantId,

        [Parameter()]
        [pscredential]$RunAsCredential,

        [Parameter()]
        [pscredential]$RunAsServicePrincipal,

        [Parameter()]
        [string]$RunAsTenantId,

        [Parameter()]
        [switch]$RunAsManagedIdentity,

        [Parameter()]
        [string]$RunAsManagedIdentityClientId
    )

    Write-PSFMessage -Level Verbose -Message "Test-RBACAccess: '$CallerId' for role(s) [$(@($RequiredRole) -join ', ')] on '$Platform' at '$Scope'." -Tag 'PSAutoRBAC', 'Public'
    $provider = Get-RBACProviderInternal -Platform $Platform
    $context  = Initialize-RBACContext -BoundParameters $PSBoundParameters

    $opts = @{}
    if ($Options) { $opts = $Options.Clone() }
    if ($PSBoundParameters.ContainsKey('RoleAssignment')) { $opts['RoleAssignment'] = $RoleAssignment }

    try {
        $states = @(& $provider.TestAccess $CallerId $RequiredRole $Scope $context $opts)
        $granted = @($states | Where-Object { $_.HasAccess -eq $true }).Count
        Write-PSFMessage -Level Verbose -Message "Test-RBACAccess: $granted/$($states.Count) required role(s) held by '$CallerId'." -Tag 'PSAutoRBAC', 'Public'
        $states
    }
    finally {
        if ($context.IsRunAs) { & $context.Disconnect }
    }
}