Menu Close

Azure Automation: StartStop Virtual Machines

With my customers I often use the Azure Runbooks to stop certain virtual machines outside of business hours. Mostly non-production virtual machines that I have discussed, with the responsible teams, at what hours of the day or night these machines are not begin used, so you won’t burn compute costs. For production environment you are more likely to use reservations so the stopping of the VM’s won’t help in cutting costs.
You can use the script below within a Azure Runbook and a associated schedule to stop certain virtual machines at the time of the scheduled runbook. You will need to tag your virtual machines with “VMStartStop” and then with a certain number as a value.

#StopVM automation script to shutdown VM's according to Runbook schedule

#login to Azure
Write-Output "Logging into Azure..."
Connect-AzAccount -Identity

Select-AzSubscription -SubscriptionId $RunAsConnection.SubscriptionID  | Write-Verbose
    
## List all subs
$AllSubID = (Get-AzSubscription).SubscriptionId
Write-Output "$(Get-Date -format s) - List of Subscription below"
$AllSubID

$AllVMList = @()
Foreach ($SubID in $AllSubID) {
    Select-AzSubscription -Subscriptionid "$SubID"

    $VMs = Get-AzVM | Where-Object { $_.tags.VMStartStop -ne $null }
    Foreach ($VM in $VMs) {
        $VM = New-Object psobject -Property @{`
                "Subscriptionid" = $SubID;
            "ResourceGroupName"  = $VM.ResourceGroupName;
            "VMStartStop"        = $VM.tags.VMStartStop;
            "VMName"             = $VM.Name
        }
        $AllVMList += $VM | Select-Object Subscriptionid, ResourceGroupName, VMName, VMStartStop
    }
}

## Sort VM's on priority
$AllVMListSorted = $AllVMList | Sort-Object -Property VMStartStop
Write-Output "$(Get-Date -format s) - Sort VM's on prio"
$AllVMListSorted

##Start VMs block
Write-Output "$(Get-Date -format s) - VM's stop."

Foreach ($VM in $AllVMListSorted) {
    Write-Output "$(Get-Date -format s) - Stop VM: $($VM.VMName) in RG: $($VM.ResourceGroupName)"
    Select-AzSubscription -Subscriptionid $VM.Subscriptionid
    Stop-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.VMName -Force
    Start-Sleep -s 5
}

Write-Output "$(Get-Date -format s) All VM's stopped."

The script will iterate through all your subscriptions and list the virtual machines that have been tagged. It also sorts them after so you can setup a particular sequence in shutting down virtual machines for a specific workload for example. The script used for starting the VM’s again is the exact same script except you will use the “Start-AzVM” cmdlet at the bottom:

Start-AzVM -ResourceGroupName $VM.ResourceGroupName -Name $VM.VMName

I hope this will help you on cutting down on compute costs within your environment or with your customers!

Leave a Reply

Your email address will not be published. Required fields are marked *