Cloud Automation: Auto-Start Azure VM with Retry Functionality Script

Leveraging the power of Azure Runbook & Manage Identities

Shakeel Juan Calle Ghani
4 min readOct 21, 2023

In today’s rapidly evolving cloud landscape, optimising resource usage and cost efficiency are paramount concerns for businesses. One common ingenious solution to tackle this challenge involves leveraging PowerShell scripting, to automate the process of starting Azure Virtual Machines (VMs) after they have automatically shut down for the night. By creating a meticulously crafted PowerShell script, businesses can ensure that their Azure VMs automatically power down during non-operational hours, significantly reducing costs.

However, the real magic happens in the early hours of the morning when the same script seamlessly initiates the VMs, ensuring they are up and running before the start of the workday. This automated approach not only guarantees substantial cost savings by preventing unnecessary runtime but also ensures that crucial applications and services are readily available when needed.

PowerShell Script: Azure VM Auto-Start with Retry Functionality

There are 4 parameters that will need to be updated for the script to work

$Sub : Azure Subscription of where the VMs are in
$resoruceGroupName : RG group of the VMs
$maxRetries : How many times to attempt to run the retry function, default is 2 retries
$retryDelaySeconds : Delay between retry attempts, default is 50secs

# Author: Shakeel Juan Calle Ghani

# parameters
$Sub = "ENTER_SUB_HERE" # Azure Subscription of where the VMs are in
$resourceGroupName = "ENTER_RG_HERE" # RG group of the VMs
$maxRetries = 2 # How many times to attempt to run
$retryDelaySeconds = 50 # Delay between attempts

# Step 0 (Pre-Req) - Manage Identity verification
Write-Output "Verifying Managed Identity for script"

# Prvevent inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process | Out-Null

# Connect using a Managed Service Identity (system assigned)
try {
$AzureContext = (Connect-AzAccount -Identity).context
Write-Output "Using system-assigned managed identity"
}
catch {
Write-Output "There is no system-assigned user identity. Aborting.";
exit
}

# set and store script context
$AzureContext = Set-AzContext -SubscriptionName $Sub

## Main Script
Write-Output "Starting Auto-Start VM script"

# Step 1 - Creation Custom Function to start a VM in the RG groups with retry attempts
function Start-VMFunction {
param (
[string]$vmName
)

$retryCount = 0 # Setting retry count to 0
$success = $false # Setting the success to $false until the condition is met (VM is on)

# Attempt to start the VMs with retry attempts
while ($retryCount -lt $maxRetries) {
Write-Output "Starting VM: $vmName (Retry $($retryCount+1))"
Start-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -NoWait
Start-Sleep -Seconds $retryDelaySeconds

# Check the VM power state
$vmStatus = (Get-AzResource -ResourceId (Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName).Id).Properties.ProvisioningState

# IF condition checking the VM status and if running switches the Success criteria to $True

if ($vmStatus -eq "Succeeded") {
$success = $true
break
}
else {
Write-Output "Failed to start VM: $vmName (Retry $($retryCount+1))"
}

$retryCount++ # Retring if failure (3 times as set in parameter)
}
# Verifying if VM is running
if ($success) {
Write-Output "VM $vmName started successfully"
}
else {
Write-Output "Failed to start VM $vmName after $maxRetries retries"
}
}

# End of custom function

# Step 2 - Loop through VM to start using function

# Retriving the VMs in the resource group
$vmList = Get-AzVM -ResourceGroupName $resourceGroupName | Select-Object -ExpandProperty Name

# Looping through each VM and start it with retry set at 3 attempts
foreach ($vmName in $vmList) {
Start-VMFunction -vmName $vmName # Calling the function created above Start-VMFunction
}

Write-Output "Auto-Start VM script completed"

Implementation with Azure

Pre Requisites

Note: as the script uses a managed identity you need to ensure your automation account has at least the ‘Virtual Machine Contributor’ RBAC role on the RG where the VMs are located within otherwise the script won’t work.

In your Automation Account where your Runbooks are hosted, Account Settings > Identity > Azure Role Assignments and associate the RBAC role on the RG where the VMs are located within.

Implementation

  • 1 — Create a new Azure Runbook into your automation account to store and run the script above. A previous Medium article below I wrote describes this process and implementation steps 1–4.
  • 2 — Test the output in the test pane to validate if any errors.
  • 3 — Add the Runbook to a schedule to run automatically going forward.
  • 4 — Publish the Runbook.
  • 5 — Monitor the script it auto starting the VMs over a period of a few days after the above has been implemented. You may tweak the retry functionality parameters to best fit your environment.

Conclusion

By harnessing the power of automation via Azure Runbooks, businesses can strike a balance between resource optimisation and operational efficiency, making the most out of their cloud investments while minimising expenditure.

Hit the 👏 button if you found this insightful.

--

--

Shakeel Juan Calle Ghani
Shakeel Juan Calle Ghani

Written by Shakeel Juan Calle Ghani

Cloud, Automation & Platform Specialist | Cloud-Based Infrastructure Lead | 9x Microsoft Certified

No responses yet