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.