Private/RBACProviderRegistry.ps1

function Register-RBACProvider {
    <#
    .SYNOPSIS
        Registers a platform probe provider in the module-scoped registry.
    .DESCRIPTION
        Internal. Validates that a provider object implements the PSAutoRBAC
        provider contract and indexes it by its canonical name and every alias
        (case-insensitively). Called once per provider at module load.
 
        Provider contract (PSCustomObject, PSTypeName 'PSAutoRBAC.Provider'):
          Name [string] canonical platform name
          Aliases [string[]] accepted alternative names
          SupportsLiveProbe [bool] whether ProbeLive can execute commands
          ResolveRequirement [scriptblock] param($Command,$Context,$Options) -> requirement
          TestAccess [scriptblock] param($CallerId,$RequiredRole,$Scope,$Context,$Options) -> states
          ProbeLive [scriptblock] param($Command,$ArgumentList,$Scope,$Context) -> requirement|null
          NewGrantScript [scriptblock] param($CallerId,$Role,$Scope,$Options) -> @{AddScript;RemoveScript}
          MatchScope [scriptblock] param($Assignment,$Scope) -> bool
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [psobject]$Provider
    )

    $required = @(
        'Name', 'Aliases', 'SupportsLiveProbe',
        'ResolveRequirement', 'TestAccess', 'ProbeLive', 'NewGrantScript', 'MatchScope'
    )
    foreach ($member in $required) {
        if (-not ($Provider.PSObject.Properties.Name -contains $member)) {
            Write-PSFMessage -Level Error -Message "Provider '$($Provider.Name)' is missing required member '$member'." -Tag 'PSAutoRBAC', 'Registry'
            throw "PSAutoRBAC provider '$($Provider.Name)' is missing required member '$member'."
        }
    }

    if (-not (Get-Variable -Name 'RBACProviders' -Scope Script -ErrorAction SilentlyContinue)) {
        $script:RBACProviders = @{}
    }

    foreach ($key in @($Provider.Name) + @($Provider.Aliases)) {
        if ([string]::IsNullOrWhiteSpace($key)) { continue }
        $script:RBACProviders[$key.ToLowerInvariant()] = $Provider
    }
    Write-PSFMessage -Level Verbose -Message "Registered provider '$($Provider.Name)' (aliases: $(@($Provider.Aliases) -join ', '); live probe: $($Provider.SupportsLiveProbe))." -Tag 'PSAutoRBAC', 'Registry'
}

function Get-RBACProviderInternal {
    <#
    .SYNOPSIS
        Resolves a registered provider by platform name or alias.
    .DESCRIPTION
        Internal. Case-insensitive lookup against the registry populated by
        Register-RBACProvider. Throws a helpful error listing known platforms
        when no provider matches.
    .OUTPUTS
        PSCustomObject (PSAutoRBAC.Provider)
    #>

    [CmdletBinding()]
    [OutputType([psobject])]
    param(
        [Parameter(Mandatory)]
        [string]$Platform
    )

    if (-not (Get-Variable -Name 'RBACProviders' -Scope Script -ErrorAction SilentlyContinue) -or
        $script:RBACProviders.Count -eq 0) {
        throw 'No PSAutoRBAC providers are registered. The module may have failed to load its Providers directory.'
    }

    $key = $Platform.Trim().ToLowerInvariant()
    if ($script:RBACProviders.ContainsKey($key)) {
        $provider = $script:RBACProviders[$key]
        Write-PSFMessage -Level Debug -Message "Resolved platform '$Platform' to provider '$($provider.Name)'." -Tag 'PSAutoRBAC', 'Registry'
        return $provider
    }

    $known = ($script:RBACProviders.Values | Select-Object -ExpandProperty Name -Unique | Sort-Object) -join ', '
    Write-PSFMessage -Level Error -Message "Unknown platform '$Platform'. Known platforms: $known." -Tag 'PSAutoRBAC', 'Registry'
    throw "Unknown platform '$Platform'. Known platforms: $known."
}

function Get-RBACRegisteredProvider {
    <#
    .SYNOPSIS
        Returns the distinct set of registered providers.
    .DESCRIPTION
        Internal helper backing the public Get-RBACProvider introspection cmdlet.
    .OUTPUTS
        PSCustomObject (PSAutoRBAC.Provider)
    #>

    [CmdletBinding()]
    [OutputType([psobject])]
    param()

    if (-not (Get-Variable -Name 'RBACProviders' -Scope Script -ErrorAction SilentlyContinue)) {
        return @()
    }
    $script:RBACProviders.Values | Sort-Object -Property Name -Unique
}