Private/Get-CIEMToken.ps1

function Get-CIEMToken {
    <#
    .SYNOPSIS
        Returns ARM and Graph tokens, retrieving from PSU secrets if needed.

    .DESCRIPTION
        Single source of truth for token retrieval. Checks script-scoped variables
        first, then falls back to PSU secrets if available. Populates script scope
        from PSU secrets for subsequent calls.

    .OUTPUTS
        [PSCustomObject] with ARMToken and GraphToken properties.
        Either property may be $null if the token is not available.

    .EXAMPLE
        $tokens = Get-CIEMToken
        if ($tokens.GraphToken) {
            $headers = @{ Authorization = "Bearer $($tokens.GraphToken)" }
        }
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param()

    # ARM token - check script scope, then PSU secret
    if (-not $script:ARMAccessToken) {
        $secretValue = Get-CIEMSecret 'CIEM_Azure_ARMToken'
        if ($secretValue) {
            $script:ARMAccessToken = $secretValue
            Write-Verbose "ARM token retrieved from PSU secret"
        }
    }

    # Graph token - check script scope, then PSU secret
    if (-not $script:GraphAccessToken) {
        $secretValue = Get-CIEMSecret 'CIEM_Azure_GraphToken'
        if ($secretValue) {
            $script:GraphAccessToken = $secretValue
            Write-Verbose "Graph token retrieved from PSU secret"
        }
    }

    [PSCustomObject]@{
        ARMToken   = $script:ARMAccessToken
        GraphToken = $script:GraphAccessToken
    }
}