Azure Autmation Account — Powershell Start Stop VM
Today, we create a simple PowerShell script which checks a VM state and either start or deallocate the machine. In order to orchestrate the script, we use an Azure automation account. I would like to emphasize that there is a lot of ready-made more robust scripts on the Internet which do the same. This example is simpler. And a goal of the post is how to use Azure Automate, not writing advanced PowerShell scripts.
First things first. In order to authenticate to the VM we use a System Assigned Identity belonging to the automation account and…
…assigned to the VM. For the sake of brevity, a Contributor role has been used. But I recommend creating a custom role containing following actions:
"Microsoft.Compute/*/read",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/deallocate/action"
Now, it’s time to create a runbook.
Before we go to the runbook. Let’s define two variables.
Here is a code:
Param
(
[Parameter (Mandatory= $true)]
[String] $resourceGroupName,
[Parameter (Mandatory= $true)]
[String] $vmName
)
$tenantId = Get-AutomationVariable -Name 'TenantId'
$subscriptionId = Get-AutomationVariable -Name 'SubscriptionId'
$runStates = "VM running", "VM stopped"
Connect-AzAccount -Identity -TenantId $tenantId -Subscription $subscriptionId | Out-Null
$currentContext = Get-AzContext
$outputTenantSubscription = [string]::Join(' ',"Tenant:",$currentContext.Tenant.Id, "Subscription:", $currentContext.Subscription.Name)
Write-Output $outputTenantSubscription
$vmStatusInitial = (Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Status).Statuses[1].DisplayStatus
$outputInitial = [string]::Join(' ',"A first status: The VM is in a",$vmStatusInitial, "state.")
Write-Output $outputInitial
if($runStates -contains $vmStatusInitial) {
Stop-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Force
Write-Output "The VM has been deallocated."
} elseif($vmStatusInitial -eq "VM deallocated") {
Start-AzVM -ResourceGroupName $resourceGroupName -Name $vmName
Write-Output "The VM has been started."
} else {
Write-Output "The VM is not in a supported state."
}
$vmStatusAfter = (Get-AzVM -ResourceGroupName $resourceGroupName -Name $vmName -Status).Statuses[1].DisplayStatus
$outputAfter = [string]::Join(' ',"A second status: The VM is in a",$vmStatusAfter, "state.")
Write-Output $outputAfter
What is happening here.
$resourceGroupName and $vmName parameters are provided right before a script run.
$tenantId and $subscriptionId variables are values we declared at the Variables section in the previous step.
Connect-AzAccount -Identity… connects to Azure through the system assigned managed identity.
Rest of the code is self-explanatory. If the VM is deallocated, then it’s started. If it’s in a running or stopped state, then is deallocated. This script operates on these three states, but there are more. You can check them out here.
And there is a tested function down there.