Schedule start or shutdown Azure virtual machine using Azure Automation PowerShell Workflow and Tags
This is an Azure Automation Powershell Workflow based runbook which automates the scheduled startup and/or shutdown of virtual machines (ARM) in Azure subscription based on the Tags defined.
Script logic:
- The runbook implements a solution for scheduled power management of Azure virtual machines in combination with tags on virtual machines or resource groups which define a shutdown schedule.
- Each time it runs, the runbook looks for all virtual machines or resource groups with tag named “AutoShutdownSchedule” having a value defining the schedule, e.g. “10PM -> 6AM”.
- If the actionFlag parameter is set to “Startup“, the script will power-on all the virtual machines matching the criteria in parallel.
- If the actionFlag parameter is set to “Shutdown“, the script will gracefully shutdown the virtual machines (using the -StayProvisioned flag), give a pause for 120 seconds and finally Shutdown and Deallocate the virtual machine.
Pre-requisite
The following prerequisites must be met, before performing the Core capacity check steps.
- Internet connection
- Valid Azure Subscription
- The person who will perform the below steps must have one of the following roles in the Azure subscription
- Owner
- Contributor
- Some familiarity with the Azure Portal would be beneficial, although not necessary
- Latest version of Microsoft .NET Framework (download link)
- Latest version of Microsoft Windows Management Framework (download link)
- Latest version of Microsoft PowerShell (download link including detailed installation guide)
- Latest version of Azure cmdlets (installation guide), although steps are provided below
- Some familiarity with PowerShell ISE, although not necessary (documentation)
- Some familiarity with the Azure Portal would be beneficial, although not necessary
- Some familiarity with PowerShell scripting would be beneficial, although not necessary
- TAG “AutoshutdownSchedule” defined on Azure virtual machine and is not blank
PowerShell Script
<#
.SYNOPSIS
This Azure Automation Powershell Workflow based runbook automates the scheduled startup of virtual machines in an Azure subscription.
.DESCRIPTION
The runbook implements a solution for scheduled power management of Azure virtual machines in combination with tags
on virtual machines or resource groups which define a shutdown schedule. Each time it runs, the runbook looks for all
virtual machines or resource groups with a tag named “AutoShutdownSchedule” having a value defining the schedule.
If the actionFlag is set to “Startup”, the script will power-on all the virtual machines matching the criteria in parallel.
If the actionFlag is set to “Shutdown”, the script will gracefully shutdown the virtual machines (using the -StayProvisioned flag)
give a pause for 120 seconds and finally Shutdown and Deallocate the virtual machine.
.PARAMETER actionFlag
This will tell the script what action need to be performed by the script.
This parameter takes 2 values – Startup or Shutdown
By default, the runbook will use the value “startup” which will start any virtual machines which are with the ExcludefromShutdown flag set to No.
.PARAMETER Simulate
If $true, the runbook will not perform any power actions and will only simulate evaluating the tagged schedules. Use this
to test your runbook to see what it will do when run normally (Simulate = $false).
.INPUTS
None.
.OUTPUTS
Human-readable informational and error messages produced during the job. Not intended to be consumed by another runbook.
#>
Workflow Azure-Asset-AutoStartupShutdownSchedule
{
Param
(
[parameter(Mandatory=$true)]
[String] $actionFlag=”Startup”,
[parameter(Mandatory=$false)]
[bool] $Simulate = $false
)
# Refered to the credential stored in the Azure Automation account
$connectionName = “AzureRunAsConnection”
try
{
# Get the connection “AzureRunAsConnection ”
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
# “Logging in to Azure…”
Add-AzureRmAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = “Connection $connectionName not found.”
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
# Get all the VMs in the subscription (the ones the principal is able to see)
# Filter on the ones having the tag specified in the runbook parameter
$vms = Get-AzureRmVM | Where-Object {$_.Tags[‘AutoShutdownSchedule’] -ne “”} | Sort $_.Name
# Start-VMs in parallel
ForEach -Parallel ($v in $vms)
{
if ($actionFlag -eq “Startup”)
{
if($Simulate)
{
Write-Output “[$($v.Name)]: SIMULATION — Would have started VM. (No action taken)”
}
else
{
Write-Output “Starting $($v.ResourceGroupName).$($v.Name)”
$ops = Start-AzureRmVM -ResourceGroupName $v.ResourceGroupName -Name $v.Name
Write-Output $ops
}
}
elseif($actionFlag -eq “Shutdown”)
{
if($Simulate)
{
# If requested to Simulate, dont perform the action
Write-Output “[$($v.Name)]: SIMULATION — Would have stopped VM gracefully. (No action taken)”
}
else
{
Write-Output “Gracefully Stopping $($v.ResourceGroupName).$($v.Name)”
#AutoShutdown Graceful
$ops = Stop-AzureRMVM -ResourceGroupName $v.ResourceGroupName -Name $v.Name -StayProvisioned -Force
Write-Output $ops
#sleep for 120 seconds before the next command runs
Start-Sleep -Seconds 120
Write-Output “Deallocating resources $($v.ResourceGroupName).$($v.Name)”
#AutoShutdown and Deallocate resources
$ops = Stop-AzureRMVM -ResourceGroupName $v.ResourceGroupName -Name $v.Name -Force
Write-Output $ops
}
}
}
}