Azure Automation – Schedule the shutdown of Azure VMs with PowerShell

If you are running Virtual Machines on Microsoft Azure and want to save some cash (or make your MSDN allowance last longer) it is possible to use Azure Automation to schedule the shutdown (and start-up) of Virtual Machines.

This is great if you are carrying out testing on Azure and like me often forget to shut your VMs down.

Until recently Azure Automation could only be configured via the portal, but in February new Azure Automation PowerShell commands were released: https://azure.microsoft.com/blog/2015/02/18/announcing-full-powershell-cmdlet-support-for-azure-automation/

Rather than having to click lots of times we can now simply run some PowerShell scripts to get everything set up to turn off our VMs when we do not need them, this also enables us to repeat the task for additional subscriptions very easily.

In the rest of this post I will outline the steps I use to configure Azure Automation using PowerShell. I’m not going to go into much detail into Azure Automation other than mention there are four few key components we need:

  • Automation Account – Contains the runbooks and associated settings.
  • Runbook(s) – The PowerShell that carries out the actions.
  • Schedule(s) – We will use a schedule to trigger the runbooks at a set time of day.
  • Credential – Allows Azure Automation to access your Azure subscription.

1. Connect to your Azure Subscription:

 
Add-AzureAccount

2. Create an Automation Account called “MyAutomationAccount”:

 
New-AzureAutomationAccount -Location "West Europe" -Name "MyAutomationAccount"

3. Create Automation Account Credentials named “AccountCredentials”:

This saves the credentials you provide for Azure Automation to use. Best practice would to set up a separate Azure AD account for the Azure Automation to use. If you are experimenting then you can just use your existing Azure credentials.

 
$cred = Get-Credential
New-AzureAutomationCredential -AutomationAccountName myautomationaccount -Name AccountCredentials -Value $cred

4. Create a Schedule called “End of Day”:

We will turn off our VMs at 19:00 each day. The PowerShell creates a schedule that runs for the first time at 19:00 “today” and then runs daily. You can adjust the number of hours past midnight as you wish.

I often work late so on my MSDN subscription set the VMs to shut down at 2am, I then start them manually as required.

 
$evening = [DateTime]::Now.Date.AddHours(19)
New-AzureAutomationSchedule -AutomationAccountName myautomationaccount -DayInterval 1 -Name "End of Day" -StartTime $evening

4. Create a script file ready to import:

To create a Runbook using PowerShell we must save the runbook as a script file (.ps1). Here is the contents of the script I am using to stop the VMs in the subscription. Please be aware it forces all VMs to be put into the “Stopped (Deallocated)” state. Replace with the name of the Azure Subscription that contains your VMs and save to a .ps1 file which is referenced in the next step.

 
workflow StopVMs
{
    $cred =  Get-AutomationPSCredential -Name "AccountCredentials"
    Add-AzureAccount -Credential $cred
    Select-AzureSubscription -Current "<subscriptionname>"

    Get-AzureVM | Stop-AzureVM -Force
}

5. Create the runbook, publish it and attach the schedule:

In the portal these couple of lines require lots of clicks! All you need to do it replace with the location that you saved the file above including the file name ending in .ps1, e.g. c:\scripts\StopVMs.ps1.

 
New-AzureAutomationRunbook -AutomationAccountName myautomationaccount -Path "<pathtoscript>" | Publish-AzureAutomationRunbook
Register-AzureAutomationScheduledRunbook -AutomationAccountName myautomationaccount -RunbookName StopVMs -ScheduleName "End of Day"

6. Test the runbook:

To test the runbook you can use the following PowerShell, be aware it will stop your VMs!

 
Start-AzureAutomationRunbook -AutomationAccountName myautomationaccount -RunbookName StopVMs

We could go one step further and start our VMs them back up in the morning ready for when we start work. You would need to create a schedule called “Start of Day” with the time you want to start the VMs and a runbook with Start-AzureVM instead of Stop-AzureVM

These  runbooks could be adapted for a production environment I you wanted to turn off selected virtual machines for certain hours of the day when they are not needed.

I hope people find that useful and it saves us all some cash!