Skip to main content

Import Certificate to Azure Key Vault via PowerShell

·2 mins·
Azure Powershell Gist
Massimiliano Donini
Author
Massimiliano Donini
🚀 Freelance Cloud Architect | Based in The Netherlands 🇳🇱 | Ready to collaborate on cutting-edge Azure & .NET projects! 💡 Let’s talk Azure, .NET, EF Core, ASP.NET Core, Terraform, GitHub, and CI/CD automation. Got a question or an exciting project? Let’s connect! 🔥

Ever found yourself scratching your head, trying to get a freshly minted PFX TLS certificate into Azure Key Vault with PowerShell? I did—and after wading through sparse documentation, I decided to share my solution so you don’t have to!

This script grabs an access token from your Windows VM using a user-assigned identity (but you can easily tweak it for managed service identity). It’s quick, practical, and gets the job done.

Ready to see how it works? Let’s dive in:

function Store-CertificateInKeyvault {
    param(
        [Parameter(Mandatory = $true)][string]$KeyVaultName,
        [Parameter(Mandatory = $true)][string]$CertificateName,
        [Parameter(Mandatory = $true)][string]$PfxFilePath,
        [Parameter(Mandatory = $true)][string]$PfxPassword,
        [Parameter(Mandatory = $true)][string]$UamiClientId
    )

    $tokenResponse = Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2019-08-01&resource=https://vault.azure.net&client_id=$UamiClientId" -Method GET -Headers @{ Metadata = "true" }
    $accessToken = $tokenResponse.access_token

    $certContent = Get-Content -Path $PfxFilePath -Raw -Encoding Byte
    $base64Cert = [Convert]::ToBase64String($certContent)

    # Create the proper JSON body structure for Key Vault certificate import
    # for a PEM format, the content type should be different
    $requestBody = @{
        value = $base64Cert
        pwd = $PfxPassword
        policy = @{
            secret_props = @{
                contentType = "application/x-pkcs12"
            }
        }
    } | ConvertTo-Json -Depth 3

    $secretUrl = "https://$KeyVaultName.vault.azure.net/certificates/$($CertificateName)/import?api-version=7.1"  # pragma: allowlist secret
    $secretResponse = Invoke-RestMethod -Uri $secretUrl -Method POST -Headers @{
        Authorization = "Bearer $accessToken"
        "Content-Type" = "application/json"
    } -Body $requestBody

    Write-Host "Stored certificate '$CertificateName' in Key Vault '$KeyVaultName'."
}

Here below you can see the invocation of such script:

$keyVaultName = 'name of the key vault instance'
$certificateName = 'name of the certificate that will be imported'
$certPath = 'path of the pfx file on the file system'
$uamiClientId = 'client id of the user assigned managed identity'


Store-CertificateInKeyvault -KeyVaultName $keyVaultName -CertificateName $certificateName -PfxFilePath $certPath -PfxPassword $pfxPassword -UamiClientId $uamiClientId

Till the next time!