Situation: You want to connect to Azure using a certificate file (typically a PFX file) in a PowerShell script, especially in an unattended scenario or a multi-tenant environment.
Problem: Connect-AzAccount doesn't yet allow the use of x509 certificate objects, only a CertificatePath that you must specify to a local store OR a CertificateThumbprint that indicates that you installed the certificate on the local computer.
Resolution: You can use PowerShell commands to perform the following steps to make it work -
- Get the Certificate file and a credential of some sort (usually a service principal involved in the process anyway)
- Export the password-encoded certificate PFX file to a temp folder on the local machine
- Connect to AzAccounts using the temp path and the password.
You can view my commands below as they aren't a full script and thus not in my github. My scenario is to use Azure Automation's Certificates and its Credentials section to store a service principal account password securely, the Cert securely, and leverage the Credential password to secure the file, disconnect from the automatic Automation Az connection, and connect with the certificate. This is all done within a Runbook. If you needed to do this from a KeyVault, then you would need to obtain the Certificate from the Vault and include the private key in the particular x509 object you retrieve:
$Credential = Get-AutomationPSCredential -Name "MyServicePrincipal"
$Tenant = "YOURTENANTGUIDGOESHERE"
$ApplicationId = "YOURAPPLICATIONIDGOESHERE"
#Prep azure connection by getting cert, exporting to local temp file securely, then using for Az connection
$Cert = Get-AutomationCertificate -Name 'MyAppCertificate'
$CertTempPath = "$env:TEMP\temp.pfx" #You can name it dynamically if you like
try {
$PfxCert = $Cert.Export(3,$($Credential.GetNetworkCredential().Password))
} catch {
$Msg = "Error exporting cert - $_"
Write-Error -Message $Msg
Disconnect-AzAccount *> $null
throw $Msg
}
if (Test-Path $CertTempPath) {
Remove-Item -Path $CertTempPath
}
try {
Set-Content -Value $PfxCert -Path $CertTempPath -Encoding Byte #<-- PS 5.1
#Set-Content -Value $pfxCert -Path $certTempPath -AsByteStream #<-- PS 6+
} catch {
$Msg = "Error setting content - $_"
Write-Error -Message $Msg
Disconnect-AzAccount *> $null
throw $Msg
}
try {
$CertArgs = @{
CertificatePath = $certTempPath
CertificatePassword = $Credential.Password
Tenant = $Tenant
ApplicationId = $ApplicationId
}
} catch {
Write-Error -Message "Unable to get Automation Cert info - $($_.exception.message)";
Disconnect-AzAccount *> $null
throw
}
try {
Disconnect-AzAccount *> Out-Null
Write-Output -InputObject "Disconnected from Az. Connecting using $($Credential.UserName)..."
$context = Connect-AzAccount @CertArgs -ErrorAction Stop
Write-Output -InputObject "Done"
} catch {
Disconnect-AzAccount *> Out-Null
throw "Unable to connect to AzAccount using supplied Credential"
}
#DO STUFF HERE LIKE GET-AZADUSER OR SOMETHING
Disconnect-AzAccount *> Out-Null #Always close out your sessions properly
Remove-Item -Path $CertTempPath #Remove the PFX file so it is unobtainable
No comments:
Post a Comment