Freddy Mora Silva is Senior Technical Consultant at Infront Consulting. Connect with him on LinkedIn.
When you work with Azure Automation — and especially if you use Hybrid Worker machines — sometimes you need to use the certificates that are part of the connections created by the automation account on a local VM or server.
Runbooks that use these kinds of certificates work fine in the Azure environment, but if you need to run it in your local environment, using Hybrid Worker machines, this represents a challenge.
You might need to use an Azure Automation certificate locally regardless, but the use of Hybrid Worker machines almost necessitates it. Hybrid Workers are servers that enable Azure Automation Runbooks to run in a local context at the OS/server level, by using Azure Log Analytics, Monitoring Agent, and runbooks.
This allows you to manage all of your scripts from a single server, across your entire environment. You can execute your Runbook scripts with Schedules, Web Hooks, or Logic Apps. They also help keep costs down so you can right-size your Runbook server (AKA make it super small or even shut it down depending on when you need your automation).
If you decide to implement a local Azure Hybrid Worker box, you might need that server to have access to connection certificates from your Azure environment.
# Define main variables
$connectionName = "AzureRunAsConnection"
# Get the connection "AzureRunAsConnection "
$Conn = Get-AutomationConnection -Name $connectionName
# Connect to Azure AD using the connection Certificate
Connect-AzureAD -ApplicationId $Conn.ApplicationId -TenantId $Conn.TenantId -CertificateThumbprint
If we run it in Azure, there are no problems with this script:
If we run it in a Hybrid Worker, then we get this error:
I found myself digging around ways to resolve this apparent limitation, until I found a simple way to export the desire certificate to the local machine. Here is a code that you can run to accomplish it, as found on the PS Gallery. Be sure to replace the relevant names and passwords with unique ones for your environment!
# Set the password used for this certificate
$Password = "YourStrongPasswordForTheCert"
# Stop on errors
$ErrorActionPreference = 'stop'
# Get the management certificate that will be used to make calls into Azure Service Management resources
$RunAsCert = Get-AutomationCertificate -Name "AzureRunAsCertificate"
# location to store temporary certificate in the Automation service host
$CertPath = Join-Path $env:temp "AzureRunAsCertificate.pfx"
# Save the certificate
$Cert = $RunAsCert.Export("pfx",$Password)
Set-Content -Value $Cert -Path $CertPath -Force -Encoding Byte | Write-Verbose
Write-Output ("Importing certificate into local machine root store from " + $CertPath)
$SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
Import-PfxCertificate -FilePath $CertPath -CertStoreLocation Cert:\LocalMachine\My -Password $SecurePassword -Exportable | Write-Verbose
# Test that authentication to Azure ARM is working
$RunAsConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
-TenantId $RunAsConnection.TenantId `
-ApplicationId $RunAsConnection.ApplicationId `
-CertificateThumbprint $RunAsConnection.CertificateThumbprint | Write-Verbose
Select-AzureRmSubscription -SubscriptionId $RunAsConnection.SubscriptionID | Write-Verbose
# List automation accounts to confirm ARM calls are working
Get-AzureRmAutomationAccount | Select AutomationAccountName
So, after running this PS script, we try again the same sample runbook in Hybrid Worker. All now works as expected, and your certificates can be accessed from your Hybrid Worker machine.