Azure Runbook to enable Auto-Shutdown for New VMs

I have an azure lab subscription (as do you, I am sure). In this lab, I am always provisioning and deleting and scaling VMs. In order to keep my costs down, I want to enable the AutoShutdown feature on all new VMs. I can do that easily with an ARM template. But for machines that aren’t provisioned by one of my templates, I always forget to enable the Auto-Shutdown.

Here is code to loop through all of your machines and enable the Auto-Shutdown setting. I know there other ways to do this, but I wanted it to be visible when looking at the VM (in the Auto-Shutdown section).

Take this code and put it in an Azure Automation RunBook, and it will run every night (I run it an hour before the AutoShutdow time!)

Also, I have never used runbooks before, so I learned that you need lines 1 & 2 to connect to Azure as the Azure Automation RunAs account (no passwords in code!)

Here is the code:

$connection = Get-AutomationConnection -Name AzureRunAsConnection
$loginresults=Login-AzureRmAccount -ServicePrincipal -Tenant $connection.TenantID `
-ApplicationId $connection.ApplicationID -CertificateThumbprint $connection.CertificateThumbprint

foreach ($rg in $((Get-AzureRmResourceGroup).ResourceGroupName)){
foreach ($vm in $(Get-AzureRmVM -ResourceGroupName $rg)){
$shutdown_time = "22:00"
$shutdown_timezone = "Eastern Standard Time"
$properties = @{
    "status" = "Enabled";
    "taskType" = "ComputeVmShutdownTask";
    "dailyRecurrence" = @{"time" = $shutdown_time };
    "timeZoneId" = $shutdown_timezone;
    "notificationSettings" = @{
        "status" = "Disabled";
        "timeInMinutes" = 30
    }
    "targetResourceId" = $VM.Id
}
try{
$Status=(Get-AzureRmResource -ResourceId ("/subscriptions/{0}/resourceGroups/{1}/providers/microsoft.devtestlab/schedules/shutdown-computevm-{2}" -f (Get-AzureRmContext).Subscription.Id, $rg, $vm.Name) -ErrorAction stop).Properties.Status
}
Catch{
write-output "Setting $($vm.Name) to auto shutdown @ $shutdown_time (was never enabled)"
New-AzureRmResource -ResourceId ("/subscriptions/{0}/resourceGroups/{1}/providers/microsoft.devtestlab/schedules/shutdown-computevm-{2}" -f (Get-AzureRmContext).Subscription.Id, $rg, $vm.Name) -Location $vm.Location -Properties $properties -Force
}
if ($Status -eq "Disabled"){
write-output "Setting $($vm.Name) to auto shutdown @ $shutdown_time (was disbaled)"
New-AzureRmResource -ResourceId ("/subscriptions/{0}/resourceGroups/{1}/providers/microsoft.devtestlab/schedules/shutdown-computevm-{2}" -f (Get-AzureRmContext).Subscription.Id, $rg, $vm.Name) -Location $vm.Location -Properties $properties -Force
}
else {
    write-output "$($vm.Name) is already set to auto shutdown"
}
}
}

As you can see I am using some “write-output”s in the code. How can I see them with our having to naviagate to the histroy of the job? Log Analytics! To enable Auzre Automation to write to Log Analytics:

https://docs.microsoft.com/en-us/azure/automation/automation-manage-send-joblogs-log-analytics

And here is a Kusto query to see the output of the Automation Job

AzureDiagnostics 
| where ResourceProvider == "MICROSOFT.AUTOMATION"
| where RunbookName_s == "MyJobName" 
| where Category == "JobLogs" or  Category == "JobStreams" 
| order by TimeGenerated 
| project TimeGenerated,CorrelationId,RunbookName_s,ResultDescription,ResultType
| where TimeGenerated > now() - 1d

Now you can setup an Logic App too run the Kusto query and email you the results!

Note: This will set all your VMs to Auto-Shutdown. Make sure you don’t run this against your production environment!

Hope that helps someone.

, ,

Trackbacks/Pingbacks

  1. Connecting to the Azure REST API from an Azure Automation RunBook | jbmurphy.com - February 14, 2019

    […] stuck with the basic problem of how do I query the Azure REST endpoints from a RunBook. In my last post, I just learned that you can use the RunAs account for the AutomationAccount in an […]

Leave a Reply