Providers/Entra/Private/Get-EntraStoredCredential.ps1

function Get-EntraStoredCredential {
    <#
    .SYNOPSIS
        Loads the bootstrapped credential from wherever the record says it lives

    .DESCRIPTION
        Turns the credential record written by New-EntraServiceApp back into a client id and
        a usable certificate, so a caller only has to name the tenant.

        The record is the authority on where the private key is, not this function. That matters
        because the two locations behave differently and guessing wrong produces the least
        helpful possible error: a certificate store lookup that finds nothing on a machine where
        the key is sitting in a vault, reported as "no certificate with that thumbprint".

        For the vault path the PFX is reconstituted in memory and never written to disk. It is
        loaded with EphemeralKeySet where the platform supports it, so importing the credential
        does not quietly install it into the machine's certificate store as a side effect of
        being read.

    .PARAMETER TenantId
        Tenant whose record to read

    .PARAMETER VaultPassword
        Password for the vault, when the key is stored in one

    .OUTPUTS
        System.Collections.Hashtable with ClientId and Certificate.

    .EXAMPLE
        PS> Get-EntraStoredCredential -TenantId $tenant

        DESCRIPTION: Reads the record and returns the credential it names
        OUTPUT: A hashtable carrying the client id and an X509Certificate2
        USE CASE: Called by Connect-EntraEnvironment -UseSecretStore

    .NOTES
        Author: Jeffrey Stuhr
        Blog: https://www.techbyjeff.net
        LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/
    #>


    [CmdletBinding()]
    [OutputType([hashtable])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$TenantId,

        [Parameter()]
        [System.Security.SecureString]$VaultPassword
    )

    $recordPath = Get-TestCredentialPath -TenantId $TenantId
    if (-not (Test-Path -LiteralPath $recordPath)) {
        Write-Error ("No credential record for tenant $TenantId at $recordPath. Run " +
            "Connect-TestEnvironment -Provider Entra -Interactive followed by New-TestServiceApp first.") -ErrorAction Stop
        return
    }

    $record = Get-Content -LiteralPath $recordPath -Raw -Encoding UTF8 | ConvertFrom-Json

    # Records written before the vault path existed have no keyProtection, and the key is in
    # the certificate store. Defaulting keeps them readable rather than failing on a field
    # that did not exist when they were written.
    $protection = if ($record.PSObject.Properties['keyProtection'] -and $record.keyProtection) {
        $record.keyProtection
    }
    else { 'CertificateStore' }

    $certificate = switch ($protection) {
        'SecretStore' {
            $encoded = Get-TestVaultSecret -VaultName $record.vaultName -SecretName $record.secretName -VaultPassword $VaultPassword
            $password = Get-TestVaultSecret -VaultName $record.vaultName -SecretName "$($record.secretName)-password" -VaultPassword $VaultPassword

            $pfx = [Convert]::FromBase64String($encoded)
            try {
                # Ephemeral where available: reading the credential should not have the side
                # effect of installing it. PowerShell 5.1 has no such flag, so it falls back to
                # a non-persisted user key set there.
                $flags = if ($PSVersionTable.PSEdition -eq 'Desktop') {
                    [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::UserKeySet
                }
                else {
                    [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::EphemeralKeySet
                }
                [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pfx, $password, $flags)
            }
            finally {
                [Array]::Clear($pfx, 0, $pfx.Length)
            }
        }
        default {
            Get-TestCertificate -Thumbprint $record.certificateThumbprint
        }
    }

    if (-not $certificate) {
        Write-Error "The credential record names a certificate that could not be loaded." -ErrorAction Stop
        return
    }

    return @{
        ClientId      = $record.clientId
        Certificate   = $certificate
        KeyProtection = $protection
        DisplayName   = $record.displayName
    }
}