This post describes how to use Azure Automation Hybrid Worker in on-premises scenarios where you need to authenticate against the local resources you want to automate, all without using any Azure Automation credential/certificate, thanks to Group Managed Service Accounts and PsExec.
Azure Automation Hybrid Worker is a great solution for implementing hybrid automation scenarios, where you have on-premises assets you want to manipulate from the same control plane you use to manage your Azure resources. All your runbooks are stored and invoked in Azure Automation, but you choose whether you run them in the cloud or on-premises.
No matter the environment you are managing, secure authentication against your resources is always a critical aspect of your automation, particularly when you need to access on-premises resources. Azure Automation provides several solutions for authentication:
Looking at the authentication options available, only credentials/certificates can be used to authenticate against on-premises resources. However, some organizations may be reluctant in storing such sensitive information in Azure Automation, even more retrieving it over the Internet. Therefore, if Automation Hybrid Worker could use an on-premises identity without dealing with secrets, such as Group Managed Service Accounts (gMSA), there would be no need to store credentials/certificates. Unfortunately, Azure Automation does not natively support gMSA, but if you follow the remainder of this post, there is a way of using gMSA, thanks to the PsExec tool, which can be used to launch a process in the context of any identity, including gMSA.
This solution assumes that you have one or more Azure Automation Hybrid Workers domain-joined to an on-premises Active Directory according to gMSA requirements. The same gMSA identity can be used across multiple Hybrid Workers, as it is centrally managed by Active Directory. With the required permissions assigned to that gMSA account, Hybrid Workers can be authorized against the resources to perform automation tasks all without dealing with secrets.
As a good practice, if you plan to automate local resources in several administrative tiers or for multiple purposes requiring different permission levels, you should consider using distinct gMSA/Hybrid Workers groups for each administrative tier/permission level.
Due to the limited scenarios in which gMSAs can be used, we are left with the only option for Hybrid Workers: using the well-known PsExec tool from Microsoft Sysinternals, which can be used to launch a process in the context of any user, including gMSA. In order to use PowerShell from end to end, one can use the Invoke-PsExec wrapper module, but the PsExec executable can also be directly called from PowerShell, provided it is made available in a well-known local directory in the Hybrid Worker machine.
In order to prepare the gMSA account, you must follow these steps (a good overview of the process can be found here):
1. Create the KDS Root Key in Active Directory (AD), by running the following PowerShell command on a domain controller:
Add-KdsRootKey -EffectiveImmediately
Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))
2. Create a security group in the AD for the purpose of grouping all the computers (Hybrid Workers) that will use this gMSA. Make all the Hybrid Worker machines as members of this security group. Reboot the Hybrid Worker machines.
3. [if you chose option 1 in step 1, ensure 10 hours have elapsed] Create the gMSA, by executing the following PowerShell command:
New-ADServiceAccount -Name "<gMSA name>" -DNSHostName "<gMSA name>.yourdomain.local" -Enabled $True -PrincipalsAllowedToRetrieveManagedPassword <security group created in the previous step> -KerberosEncryptionType AES256
4. Grant all the needed privileges to the gMSA account. When looking for the gMSA in the AD, refer to it as <gMSA name>$
5. Install the gMSA in the Hybrid Worker machines using it, by running there this PowerShell command:
Install-ADServiceAccount -Identity <gMSA name>
6. Test if the gMSA was correctly installed in the Hybrid Worker:
Test-ADServiceAccount -Identity <gMSA name>
Now that the gMSA is ready to be used, we must set up Azure Automation. In many scenarios, Automation runbooks have hundreds of lines, variables, HTML code, etc. Because of this complexity, we might be obliged to run the script from the Hybrid Worker local file system, instead of just passing it inline to PsExec. However, as we don’t want to have automation code permanently stored in the Hybrid Worker local file system, we will use two Azure Automation Runbooks: the first one with the PsExec orchestration; and the other one with the actual automation we want to execute (please, note that it won’t be triggered as a normal runbook, but will rather be temporarily downloaded to the local file system to be later called by PsExec). To make this solution possible, we will need to:
<#Sample scripts provided are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.#>
Param(
[string] $RunbookName,
[string] $AutomationAccountName,
[string] $AutomationAccountResourceGroup,
[string] $gMSAName,
[string] $ParametersJson
)
$servicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection"
"Logging in to Azure..."
Add-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
Export-AzAutomationRunbook -ResourceGroupName $AutomationAccountResourceGroup -AutomationAccountName $AutomationAccountName -Name $RunbookName -Slot Published -OutputFolder .
$ScriptFilePath = (Get-Item -Path ".\").FullName + "\" + $RunbookName + ".ps1"
Write-Output "Replacing JSONParametersPlaceHolder with $ParametersJson ..."
(Get-Content $ScriptFilePath).replace('JSONParametersPlaceHolder', $ParametersJson) | Set-Content $ScriptFilePath
Write-Output "Using credential $gMSAName ..."
# we must use ~ as a password replacement for the gMSA account
$creds = New-Object System.Management.Automation.PSCredential ($gMSAName, (ConvertTo-SecureString "~" -AsPlainText -Force))
Invoke-PsExec -Credential $creds -ComputerName $env:computername -PSFile $ScriptFilePath
$ParametersJson = "JSONParametersPlaceHolder"
<#
As an example, we are going to disable a user account sent as a JSON parameter, with the schema { 'Name': 'Account Name', 'SamAccountName' : 'SAM account name' }
#>
$user = ConvertFrom-Json -InputObject $ParametersJson
Write-Output "About to disable $($user.Name)..."
Disable-ADAccount $user.SamAccountName
Write-Output "Done."
This post described how to use Azure Automation Hybrid Worker in scenarios where you need to authenticate against on-premises resources without using secrets or certificates, thanks to gMSA accounts and PsExec.
The orchestration runbook and main automation sample script above are an example of a more complex scenario, in which you need to pass parameters to the main script. However, if the command to execute in the context of the gMSA account is simple enough, you can call the PowerShell command right from the Invoke-PsExec cmdlet and you don’t even need to use Azure Automation Run As Accounts as you don’t need to export the main script to the local file system.
Thanks for reading!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.