internal/functions/authentication/Get-VaultSecret.ps1

function Get-VaultSecret {
    <#
    .SYNOPSIS
        Retrieve a secret from Azure Key Vault.
    
    .DESCRIPTION
        Retrieve a secret from Azure Key Vault.
        Works for both certificates and secrets.

        Requires one of ...
        - An established connection with the AzureKeyVault service.
        - An established AZ session via Az.Accounts with the Az.KeyVault module present.
    
    .PARAMETER VaultName
        Name of the Vault to query.
    
    .PARAMETER SecretName
        Name of the Secret to retrieve.
    
    .PARAMETER Cmdlet
        The $PSCmdlet object of the caller, enabling errors to happen within the scope of the caller.
        Defaults to the current command's $PSCmdlet
    
    .EXAMPLE
        PS C:\> Get-VaultSecret -VaultName myvault -SecretName mysecret
        
        Retrieves the latest enabled version of mysecret from myvault
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]
        $VaultName,
        
        [Parameter(Mandatory = $true)]
        [string]
        $SecretName,

        $Cmdlet = $PSCmdlet
    )

    process {
        #region Via EntraAuth
        if (Get-EntraToken -Service AzureKeyVault) {
            try {
                $secretVersion = Invoke-EntraRequest -Service AzureKeyVault -Path "secrets/$SecretName/versions" -VaultName $VaultName -ErrorAction Stop | Where-Object {
                    $_.attributes.enabled
                } | Sort-Object { $_.attributes.created } -Descending | Select-Object -First 1

                if (-not $secretVersion) {
                    Invoke-TerminatingException -Cmdlet $Cmdlet -ErrorRecord $_ -Message "Secret '$SecretName' does not exist in vault '$VaultName'! $_"
                }
                $secretData = Invoke-EntraRequest -Service AzureKeyVault -Path $secretVersion.id -VaultName $VaultName -ErrorAction Stop
            }
            catch {
                Invoke-TerminatingException -Cmdlet $Cmdlet -ErrorRecord $_ -Message "Failed to retrieve secret '$SecretName' from '$VaultName'! $_"
            }

            if ($secretVersion.contentType) {
                $secretBytes = [convert]::FromBase64String($secretData)
                $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($secretBytes)
                [PSCustomObject]@{
                    Type         = 'Certificate'
                    Certificate  = $certificate
                    ClientSecret = $null
                }
            }
            else {
                [PSCustomObject]@{
                    Type         = 'ClientSecret'
                    Certificate  = $null
                    ClientSecret = $secretData | ConvertTo-SecureString -AsPlainText -Force
                }
            }

            return
        }
        #endregion Via EntraAuth

        #region Via Az.KeyVault
        if ((Get-Module Az.Accounts -ListAvailable) -and (Get-AzContext) -and (Get-Module Az.KeyVault -ListAvailable)) {
            try { $secret = Get-AzKeyVaultSecret -VaultName $VaultName -Name $SecretName }
            catch { Invoke-TerminatingException -Cmdlet $Cmdlet -ErrorRecord $_ -Message "Error accessing the secret '$Secretname' from Vault '$VaultName'. $_" }

            $type = 'Certificate'
            if (-not $secret.ContentType) { $type = 'ClientSecret' }

            $certificate = $null
            $clientSecret = $secret.SecretValue

            if ($type -eq 'Certificate') {
                $certString = [PSCredential]::New("irrelevant", $secret.SecretValue).GetNetworkCredential().Password
                $bytes = [convert]::FromBase64String($certString)
                $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($bytes)
                $clientSecret = $null
            }
            
            [PSCustomObject]@{
                Type         = $type
                Certificate  = $certificate
                ClientSecret = $clientSecret
            }

            return
        }
        #endregion Via Az.KeyVault

        Invoke-TerminatingException -Cmdlet $Cmdlet -Message "Not connected to azure yet! Either use 'Connect-EntraService -Service AzureKeyVault' or 'Connect-AzAccount' before trying to connect via KeyVault!" -Category ConnectionError
    }
}