Artifacts/windows-certificate-from-keyvault/InstallCertificate.ps1 (119 lines of code) (raw):

param( [ValidateNotNullOrEmpty()] [string]$vaultName, [ValidateNotNullOrEmpty()] [string]$secretName, [ValidateNotNullOrEmpty()] [string]$azureServicePrincipalClientId, [ValidateNotNullOrEmpty()] [string]$azureServicePrincipalKey, [ValidateNotNullOrEmpty()] [string]$azureServicePrincipalTenantId, [ValidateNotNullOrEmpty()] [string]$certificatePasswordSecretName ) ################################################################################################### # # PowerShell configurations # # NOTE: Because the $ErrorActionPreference is "Stop", this script will stop on first failure. # This is necessary to ensure we capture errors inside the try-catch-finally block. $ErrorActionPreference = 'Stop' ################################################################################################### # # Handle all errors in this script. # trap { # NOTE: This trap will handle all errors. There should be no need to use a catch below in this # script, unless you want to ignore a specific error. $message = $Error[0].Exception.Message if ($message) { Write-Host -Object "`nERROR: $message" -ForegroundColor Red } Write-Host "`nThe artifact failed to apply.`n" # IMPORTANT NOTE: Throwing a terminating error (using $ErrorActionPreference = "Stop") still # returns exit code zero from the PowerShell script when using -File. The workaround is to # NOT use -File when calling this script and leverage the try-catch-finally block and return # a non-zero exit code from the catch block. exit -1 } ################################################################################################### # # Main execution block. # $done = "Done`n" try { Write-Host "Arguments:" Write-Host "vaultName: $vaultName" Write-Host "secretName: $secretName" Write-Host "azureServicePrincipalClientId: $azureServicePrincipalClientId" Write-Host "azureServicePrincipalKey: $azureServicePrincipalKey" Write-Host "azureServicePrincipalTenantId: $azureServicePrincipalTenantId" Write-Host "certificatePasswordSecretName: $certificatePasswordSecretName`n" if (-not (Get-Module -Name "AzureRm")) { if (Get-Module -ListAvailable | Where-Object { $_.Name -eq "AzureRm"}) { } else { Write-Host "AzureRM not detected, installing" Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force Install-Module AzureRm -Force -AllowClobber Write-Host $done } } Import-Module AzureRm $azureAccountName = $azureServicePrincipalClientId $azurePassword = ConvertTo-SecureString $azureServicePrincipalKey -AsPlainText -Force $psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword) Write-Host "Logging into Azure" Add-AzureRmAccount -Credential $psCred -TenantId $azureServicePrincipalTenantId -ServicePrincipal Write-Host $done Write-Host "Getting the certificate from the vault" $secret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $secretName Write-Host $done if (!$secret) { throw "Failed to locate certificate" } Write-Host "Getting the certificate password from the vault" $passwordSecret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $certificatePasswordSecretName Write-Host $done if (!$passwordSecret) { throw "Failed to locate certificate password" } $password = $passwordSecret.SecretValueText Write-Host "Converting secret into useable object" $certBytes = [System.Convert]::FromBase64String($secret.SecretValueText) $certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection $keyFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet $keyFlags = $keyFlags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet $keyFlags = $keyFlags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable $certCollection.Import($certBytes,$null,$keyFlags) Write-Host $done Write-Host "Saving pfx to [$env:temp\cert.pfx]" $protectedCertificateBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $password) $pfxPath = "$env:temp\cert.pfx" [System.IO.File]::WriteAllBytes($pfxPath, $protectedCertificateBytes) Write-Host $done # Convert password to secure string. $securePassword = ConvertTo-SecureString -String $password -Force -AsPlainText # Install the PFX certificate into the Cert:\LocalMachine\My certificate store. Write-Host "Importing the PFX" Import-PfxCertificate -FilePath "$env:temp\cert.pfx" -CertStoreLocation cert:\localMachine\my -Password $securePassword Write-Host $done } finally { if (Test-Path "$env:temp\cert.pfx") { Write-Host "Deleting the PFX" Remove-Item "$env:temp\cert.pfx" -Force Write-Host $done } }