Automating Azure VM Management with Azure Automation Account
5 min read

Introduction
Managing Azure Virtual Machines (VMs) manually can be time-consuming, especially for tasks like shutting down idle resources to save costs. Azure Automation Account allows you to automate these operations using Runbooks.
In this guide, we will:
✅ Create an Azure Automation Account
✅ Set up a User Assigned Managed Identity (UMI)
✅ Assign VM Contributor role to the identity
✅ Write and execute a Runbook to stop VMs
✅ Schedule the Runbook for automatic execution
We will use PowerShell in the Runbook and leverage Azure CLI for setup.
1️⃣ Create an Azure Automation Account
An Automation Account is required to manage and run scripts in Azure.
Steps:
Go to the Azure Portal → Search for Automation Accounts.
Click Create and provide the following details:
Subscription: Select your subscription
Resource Group: Create or select an existing one
Automation Account Name: e.g.,
MyAutomationAccount
Region: Choose the preferred region
Managed Identity: Select None (we’ll create a separate UMI later)
Click Review + Create → Create.
Please find the screenshot of the Azure Automation Account I created.
2️⃣ Create a User-Assigned Managed Identity (UMI)
A User Assigned Managed Identity (UMI) allows our Automation Account to authenticate and execute actions without storing credentials.
Steps:
Go to Azure Portal → Search for Managed Identities.
Click Create and enter:
Subscription & Resource Group: Select same as Automation Account
Name: e.g.,
MyAutomationIdentity
Region: Choose the same as Automation Account
Click Review + Create → Create.
3️⃣ Assign "VM Contributor" Role to the Managed Identity
The VM Contributor role allows our Runbook to manage VMs (start, stop, deallocate, etc.).
Steps:
Go to Azure Portal → Open the Managed Identity created earlier.
Navigate to Access control (IAM) → Click Add role assignment.
Select:
Role: Virtual Machine Contributor
Scope: Subscription (or specific resource group if needed)
Assign access to: Managed Identity
Identity: Select autoreizeum
Click Save.
You can see in the image below that created User Managed Identity has VM contributor role assigned.
4️⃣ Create and Publish a Runbook to Stop VMs
Now, we’ll create a PowerShell Runbook that will connect to Azure using the Managed Identity and stop all VMs.
Steps:
Open Azure Portal → Go to your Automation Account.
Click Runbooks → Create a runbook.
Provide:
Name:
Stop-All-VMs
Runbook Type: PowerShell
Runtime Version: Latest
Click Create.
Edit the Runbook → Paste the following PowerShell script:
Find the script below.
### this is final runbook script which will stop VMs. Only those VMs with autostop = true
# Input parameters
param(
[Parameter(Mandatory = $true)]
[string]$SubscriptionId = "Enter your sunscriptionID",
[Parameter(Mandatory = $true)]
[string]$UserAssignedIdentityClientId = "Enter your user managed Identity"
)
try {
# Ensures you do not inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process
# Connect using user-assigned managed identity
Write-Output "Connecting to Azure using User-Assigned Managed Identity..."
Connect-AzAccount -Identity -AccountId $UserAssignedIdentityClientId
# Set context to your subscription
Write-Output "Setting context to subscription: $SubscriptionId"
Set-AzContext -SubscriptionId $SubscriptionId
# Get all VMs in the subscription
Write-Output "Getting all VMs in the subscription..."
$vms = Get-AzVM
# Check if any VMs were found
if ($null -eq $vms -or $vms.Count -eq 0) {
Write-Output "No VMs found."
return
}
Write-Output "Found $($vms.Count) VMs"
# Stop VMs with autostop = true tag
foreach ($vm in $vms) {
try {
# Check for autostop tag
$autostop = $vm.Tags["autostop"]
if ($autostop -eq "true") { # Case-insensitive comparison
Write-Output "Stopping VM: $($vm.Name) in resource group: $($vm.ResourceGroupName) (autostop tag present)"
$stopResult = Stop-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Force
if ($stopResult.Status -eq "Succeeded") {
Write-Output "Successfully stopped VM: $($vm.Name)"
} else {
Write-Error "Failed to stop VM: $($vm.Name). Status: $($stopResult.Status)"
}
} else {
Write-Output "Skipping VM: $($vm.Name) in resource group: $($vm.ResourceGroupName) (autostop tag NOT present or not 'true')"
}
} catch {
Write-Error "Error processing VM $($vm.Name): $_"
continue # Continue to the next VM even if one fails
}
}
Write-Output "VM stop operations completed"
} catch {
Write-Error "Error in runbook execution: $_"
throw $_
} finally {
# Clean up authentication context
Write-Output "Cleaning up Azure context..."
Clear-AzContext -Force
}
🔥 Alternatively, you can get the full script from your GitHub repo:
➡️ GitHub Repo: final-runbookstop.ps1
- Click Save → Publish.
5️⃣ Create a Schedule for the Runbook
To automate the Runbook execution, we’ll create a schedule.
Steps:
Open Azure Portal → Go to your Automation Account.
Select Runbooks → Click on
Stop-All-VMs
.Click Schedules → Add a Schedule.
Select Create a new schedule, and provide:
Name:
Daily-VM-Shutdown
Recurrence: Daily
Time: Choose a suitable time (e.g., 10 PM UTC)
Click Create.
Under Parameters and run settings, ensure the default values are correct.
Click OK to save.
6️⃣ Testing and Verification
To ensure everything is working:
✅ Schedule triggers the Runbook → at specified schedule.
✅ Check VM Status → Go to Azure Portal → Open Virtual Machines and verify the VMs are stopping.
✅ Check Logs → View Job Output in the Runbook to see if any errors occurred.
Mode : Process
ContextDirectory : None
ContextFile : None
CacheDirectory : None
CacheFile : None
KeyStoreFile : None
Settings : {[InstallationId, 102b9476-d6c9-4337-870a-4149300e7a15]}
Connecting to Azure using User-Assigned Managed Identity...
Environments Context
------------ -------
{[AzureChinaCloud, AzureChinaCloud], [AzureUSGovernment, AzureUSGovernment], [AzureCloud, AzureCloud]} Microsoft.Azure.…
Setting context to subscription: 6baeb535-5ac9-402f-83c4-4aed96077df6
Getting all VMs in the subscription...
Found 2 VMs
Skipping VM: backend1-vm in resource group: RUNBOOKRG (autostop tag NOT present or not 'true')
Stopping VM: backend2-vm in resource group: RUNBOOKRG (autostop tag present)
Successfully stopped VM: backend2-vm
VM stop operations completed
Cleaning up Azure context...
Above is the output of the Job in Azure.
Conclusion
🎯 We successfully automated Azure VM shutdown using Azure Automation Account and Runbooks.
🎯 We used a User Assigned Managed Identity to authenticate securely.
🎯 We scheduled the Runbook for automatic execution.
🎯 We only shutdown the VMs with tag autoshutdown = true