Private/Invoke-RBACRestRequest.ps1

function Invoke-RBACRestRequest {
    <#
    .SYNOPSIS
        Issues an authenticated REST request for the data-plane providers.
    .DESCRIPTION
        Internal. Fabric and Purview have no PowerShell RBAC cmdlets comparable to
        Az.Resources, so their providers call REST directly. This helper acquires a
        bearer token for the target resource from the probe context and performs
        the call, returning a normalized result that distinguishes success,
        authorization failure (403/401), and other errors - without throwing on
        auth failures, which the providers interpret as "caller lacks the role".
    .PARAMETER Context
        PSAutoRBAC.Context providing GetAccessToken.
    .PARAMETER ResourceUrl
        The token audience / resource URL (e.g. 'https://api.fabric.microsoft.com').
    .PARAMETER Uri
        The full request URI.
    .PARAMETER Method
        HTTP method (default GET).
    .PARAMETER Body
        Optional request body object (serialized to JSON).
    .OUTPUTS
        PSCustomObject: Success [bool], StatusCode [int], IsAuthorizationError [bool],
        Content [object], Message [string].
    #>

    [CmdletBinding()]
    [OutputType([psobject])]
    param(
        [Parameter(Mandatory)]
        [psobject]$Context,

        [Parameter(Mandatory)]
        [string]$ResourceUrl,

        [Parameter(Mandatory)]
        [string]$Uri,

        [Parameter()]
        [ValidateSet('GET', 'POST', 'PUT', 'PATCH', 'DELETE')]
        [string]$Method = 'GET',

        [Parameter()]
        [object]$Body
    )

    Write-PSFMessage -Level Verbose -Message "REST $Method $Uri" -Tag 'PSAutoRBAC', 'Rest'
    try {
        $token = & $Context.GetAccessToken $ResourceUrl
    }
    catch {
        Write-PSFMessage -Level Warning -Message "Token acquisition for '$ResourceUrl' failed: $($_.Exception.Message)" -Tag 'PSAutoRBAC', 'Rest'
        return [pscustomobject]@{
            PSTypeName = 'PSAutoRBAC.RestResult'; Success = $false; StatusCode = 0
            IsAuthorizationError = $false; Content = $null; Message = "Token acquisition failed: $($_.Exception.Message)"
        }
    }

    $params = @{
        Uri         = $Uri
        Method      = $Method
        Headers     = @{ Authorization = "Bearer $token"; Accept = 'application/json' }
        ErrorAction = 'Stop'
    }
    if ($PSBoundParameters.ContainsKey('Body') -and $null -ne $Body) {
        $params['Body']        = ($Body | ConvertTo-Json -Depth 20)
        $params['ContentType'] = 'application/json'
    }

    try {
        $response = Invoke-RestMethod @params
        Write-PSFMessage -Level Debug -Message "REST $Method $Uri succeeded." -Tag 'PSAutoRBAC', 'Rest'
        return [pscustomobject]@{
            PSTypeName = 'PSAutoRBAC.RestResult'; Success = $true; StatusCode = 200
            IsAuthorizationError = $false; Content = $response; Message = ''
        }
    }
    catch {
        $status = 0
        $resp = $null
        if ($_.Exception.PSObject.Properties.Name -contains 'Response') { $resp = $_.Exception.Response }
        if ($resp -and ($resp.PSObject.Properties.Name -contains 'StatusCode')) {
            try { $status = [int]$resp.StatusCode } catch { $status = 0 }
        }
        $isAuth = ($status -in 401, 403) -or ($_.Exception.Message -match 'Unauthorized|Forbidden|InsufficientPrivileges|PrincipalDoesNotHaveRequiredPermissions')
        $level = if ($isAuth) { 'Verbose' } else { 'Warning' }
        Write-PSFMessage -Level $level -Message "REST $Method $Uri failed (status $status, authError=$isAuth): $($_.Exception.Message)" -Tag 'PSAutoRBAC', 'Rest'
        return [pscustomobject]@{
            PSTypeName = 'PSAutoRBAC.RestResult'; Success = $false; StatusCode = $status
            IsAuthorizationError = [bool]$isAuth; Content = $null; Message = $_.Exception.Message
        }
    }
}