Being able to change Azure VM admin password from Azure Portal easily is very convenient. This feature relies on Azure Agent and VM extension, and it allows us to reset the configuration of RDP/SSH and the local administrator password. Or even to create a new account if we don’t remember the user name. Very useful.
This also unlocks the possibility to change local administrator passwords for our Azure VMs programmatically. And that can be useful if we are not using LAPS or a similar solution. Users tend to enter the same user name and password for all VM resources in Azure. That is convenient but not safe. After changing passwords, you can save them into the Key Vault or any password manager of your choice. This is great for one-time change and changing passwords regularly based on a schedule.
This article will show you how to use Azure Automation Runbook to automatically change VM passwords and save new passwords to Azure Key Vault.
Prepare the test environment
Before we start, I will assume that you already have VMs, Automation Account, and Key Vault. If you want to build these resources quickly in a new test resource group, check out this PowerShell script that I created: Create-DemoLab.ps1.
Identify VMs for which we want to change the password
Running this script to all VMs in our tenant is not a good idea. Here are a few things to consider:
- Domain Controllers will not have a local administrator. Trying to change it via VM extension will fail.
- Migrated VMs will have a historical password from on-premises/another cloud. This account user name will not be filled up in the OS Profile of Azure VM. But if you know the user name, you can still change it via the Azure VM extension. Keep that in mind since this example is not working with that possibility.
- Changing passwords for VMs that are off will not work. The demo script will skip VMs that are not running, but you can easily change that to bring them on before changing the password.
- If you have any automation or services that depend on using a local administrator password, you will need to point them to the Key Vault
- VMs using different authentication methods or hardened VMs are also not good candidates
Now that we know which VMs we want to exclude, we can enable this for VMs based on a specific Azure Tag, Resource Group, or group membership. We can also pre-fill VM names in Key Vault as Secret names and let the script change only for VMs where KeyVault Secret names match VM names.
We are making it simple for this demo, and I will do it for all VMs with the tag VMPasswordReset = Yes.
You can use this PowerShell to assign this tag to your VMs:
Automate password rotation with PowerShell and Key Vault
Our script will be simple, and it can run from anywhere. It’s up to you if you want to use it from within your client PC or Windows or Linux Server, or from Automation Account, Azure Function, Azure DevOps, or if you want to create a GitHub workflow for it.
I will use the Azure automation account for this demo since that is free and the most straightforward to set up. If you need help setting this up in any other environment, let me know on Twitter, and I’ll do my best to help you.
Configure Automation Account
We need Automation Account with System-Assigned Managed Identity that has access to VMs (VM Contributor Role) and Key Vault (Secrets: Set).
Create PowerShell Runbook
Create a new PowerShell runbook and copy the following code. It is necessary to change Automation Account Name, Subscription Name, and Tag name variables.
Now let’s test that out.
Runbook will switch between subscriptions in your tenant and find all VMs with specified Tag and status “VM running”.
Passwords will then be saved to Key Vault, where the secret name will be in format “VMName-LocalAdminUserName” :
You can see the history of all passwords:
And the actual password:
One last step is to link this Runbook to Schedule:
What to consider before running this in production
This Key Vault will contain sensitive information. It’s a good idea to check RBAC roles and Access Policies to limit its access. You can quickly adapt this method and store passwords in your other favorite password manager.
Using this workflow based on Tags as shown in this demo can be risky. Tags can be easily lost or replaced. Targeting VMs based on Group membership or KeyVault Secrets will provide more control on who can add/remove VMs from the list.
Automation Account is pretty good at keeping logs about previous runs. I would still consider implementing logging and alerting into your PowerShell script.
That’s it. Now you don’t need to worry about having the same admin account on all Azure VMs.
Thanks for reading and keep clouding around.
Vukašin Terzić