Shutting down Azure VMs based on Resource Group tags

2016, May 20    

Shutting down your non-production VM’s when you’re not using them in a great way to save money. There’s a couple of good Powershell scripts that make this easy to do by Resource Group – but when you want to be a little more granular, and actually automate across resource groups you need a smarter script – this is where Resource tagging comes in.

This script in basically my v1, simple powershell script designed to be run on demand manually. I’ll be publishing the more fully featured version in the Azure Automation Runbook Gallery shortly. That script has had to have a few workarounds put in to deal with issues arising from being a Powershell Workflow and running in Parallel, so I thought it worthwhile to share the simpler version here.

#Set variables
    $tagName = "Environment"
    $tagValue = "Demo"
    $Shutdown = $true

    #Login
    Login-AzureRmAccount

    #Shutdown machines
    $taggedResources = Find-AzureRmResource -TagName $tagName -TagValue $tagValue 

    $targetVms = $taggedResources | Where-Object{$_.ResourceType -eq "Microsoft.Compute/virtualMachines"} | select resourcegroupname, name | Get-AzureRmVM -status

    ForEach ($vm in $targetVms)
    {
        $currentpowerstatus = $vm |select -ExpandProperty Statuses | Where-Object{ $_.Code -match "PowerState" } | select Code, DisplayStatus
        Write-Verbose $currentpowerstatus

        if($Shutdown -and $currentpowerstatus -eq "PowerState/running"){
		    Write-Output "Stopping $($vm.Name)";		
		    Stop-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force;
	}
	elseif($Shutdown -eq $false -and $currentpowerstatus -ne "PowerState/running"){
		    Write-Output "Starting $($vm.Name)";		
		    Start-AzureRmVm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName;
	}
        else {
            Write-Output "VM $($vm.Name) is already in desired state : $($currentpowerstatus.DisplayStatus)";
        }
    }