Thror
Thror

Reputation: 253

What's the powershell command to upload certificate to AAD application?

In Azure portal, I can create an application under AAD, navigate to "Home (myTenant) -> App registrations -> (myApp) -> Settings -> Keys", upload public key which is a certificate to the application keys. This is easy using portal UI. But how can I do the certificate upload using Powershell command?

Thanks,

Upvotes: 4

Views: 6120

Answers (4)

Brian Hinchey
Brian Hinchey

Reputation: 3691

Building on sam256's answer, this is my version using PowerShell v7 and reading the certificate from the installed certificates on the current machine. I would love to know if there was a way to do this with fewer steps, but this is what I managed to get working.

The basic steps are:

  1. Retrieve the certificate from the current machine's certificate store.

This step requires a password that is used to protect the certificate file. But Azure AD will reject a certificate that is password protected. I could not find a way to export the certificate without a password in PowerShell, even though it is possible using the Certificates UI when you don't export the private key.

  1. Use the openssl command line utility to extract the certificate in pem format without a password.

  2. Upload the PEM format of the certificate to Azure AD

Here is the code I used:

Write-Host "Finding the right certficate to export"
$serviceCertificates = Get-ChildItem -Path Cert:\LocalMachine\My\ | Where-Object { $_.Subject -eq "CN=$certificateName" }
$latestServiceCertificate = $serviceCertificates | Sort-Object NotAfter -desc | Select-Object -First 1

Write-Host "Exporting latest certificate with thumbprint $($latestServiceCertificate.Thumbprint)"
$plaintextPassword = "..." #TODO: Add your own plaintext password here. It is just used temporarily so you don't need to store it anywhere.
$securePassword = ConvertTo-SecureString -String $plaintextPassword -Force -AsPlainText
$serviceCertificateFilePath = Join-Path $certificatesPath "$certificateName.cer"
Export-PfxCertificate -Cert $latestServiceCertificate -FilePath $serviceCertificateFilePath -Password $securePassword

Write-Host 'Extracting PEM file from latest certificate'
$servicePemCertificateFilePath = Join-Path $certificatesPath "$certificateName.pem"
openssl pkcs12 -in $serviceCertificateFilePath -clcerts -nokeys -password "pass:$plaintextPassword" -out $servicePemCertificateFilePath

Write-Host 'Uploading PEM file to Azure AD'
$servicePemCertificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate($servicePemCertificateFilePath)
$keyCredential = @{
    startDateTime = [System.DateTime]::UtcNow
    type = 'AsymmetricX509Cert'
    usage = 'Verify'
    key = $servicePemCertificate.GetRawCertData()
    displayName = "CN=$certificateName"
}
Connect-MgGraph
Update-MgApplication -ApplicationId $azureAdApplicationId -KeyCredentials @($keyCredential)

Upvotes: 0

sam256
sam256

Reputation: 1421

2023 Update

For anyone reading now, when the recommended approach in Powershell is to use the Microsoft Graph modules over Azure AD modules, the relevant commands are Update-MgApplication with the -KeyCredentials param for a new certificate or Add-MgApplicationKey to update an existing certificate. (Yes, the language is confusing. Update the app to add a key. Add a key to update a key. And "key" actually means "public cert to validate a private key" in this case.)

Here's an example of function that pulls a cert from a keyvault and adds it to a registered AAD app:

function Set-AppCredential
{
    Param(
        [Parameter(Mandatory)]
        [string]$AppName,
        [Parameter(Mandatory)]
        [string]$KeyVaultName,
        [Parameter(Mandatory)]
        [string]$CertificateName
    )

    $Application = Get-MgApplication -Filter "DisplayName eq '$($AppName)'"

    $KeyVaultCertificate = Get-AzKeyVaultCertificate -VaultName $KeyVaultName -Name $CertificateName

    $CertCredential = @{
        Type = "AsymmetricX509Cert"
        Usage = "Verify"
        Key = $KeyVaultCertificate.Certificate.RawData
    }

    Update-MgApplication -ApplicationId $Application.Id -KeyCredentials @($CertCredential)

}

Upvotes: 1

Sa Yang
Sa Yang

Reputation: 9411

You can use New-AzureRmADAppCredential to Adds a credential to an existing Azure AD application.

Login-AzureRmAccount
$cert = New-Object    System.Security.Cryptography.X509Certificates.X509Certificate("PATH_TO_CER_FILE")
$key = [System.Convert]::ToBase64String($cert.GetRawCertData())
New-AzureRmADAppCredential -ApplicationId d3fdf244-xxxx-xxxx-8faa-4a22b9739374  -CertValue $key

enter image description here

Upvotes: 0

Jarnstrom
Jarnstrom

Reputation: 477

You are looking for the command New-AzureRmADAppCredential https://learn.microsoft.com/en-us/powershell/module/azurerm.resources/new-azurermadappcredential?view=azurermps-5.0.0

Example 2 in the article should work for you

----------------8<--------------------

$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate 
$cer.Import("C:\myapp.cer") 
$binCert = $cer.GetRawCertData() 
$credValue = [System.Convert]::ToBase64String($binCert)

New-AzureRmADAppCredential -ApplicationId 4589cd6b-3d79-4bb4-93b8-a0b99f3bfc58 -CertValue $credValue -StartDate $cer.GetEffectiveDateString() -EndDate $cer.GetExpirationDateString()

Upvotes: 5

Related Questions