Azure Automation: Shutting Down Custom Tagged Virtual Machines

UPDATE (1/10/2018): The script attached to the article has been updated to correct minor inconsistencies.


Hello everyone! Christopher Scott, Premier Field Engineer. I have recently transitioned into an automation role and like most people my first thought was to setup a scheduled task to shutdown and startup Virtual Machines (VMs) to drive down consumption costs. Now, the first thing I did, much like I am sure you are doing now, is look around to see what and how other people have accomplished this. Every solution I came across would do the job but didn’t have the granularity that I sought, most of them just shutdown the entire subscription or resource group. So, I came up with the idea of using Tags to shutdown or startup a filtered set of resources and that is what I wanted to show you all today.

Prerequisites\Automation Accounts

The first thing you will need to do is setup an Automation Account. From the Azure portal click more actions and search for Automation. By clicking the star to the right of Automation Accounts you can add it to your favorites blade. Next select Automations Accounts and click Create Automation Account.

Now you will be prompted to fill in some values required for the creation. The required fields are annotated by a red asterisk *. Now is the time to create the Azure Run as Accounts so click the Yes box in the appropriate field and click create.

Next, we want to verify the Azure Run as Accounts and the Azure Run as Connections were created successfully. From within the Automation Accounts blade select Run as Accounts. Verify both the Azure Run As Account and Azure Classic Run As Account have been created. Then select Connections and verify the AzureRunAsConnection and AzureClassicRunAsConnection are created successfully.

After the accounts and connections have been verified we want to update all the Azure Modules. From the Automation Accounts blade select Modules and then click Update Azure Modules
and confirm with Yes.

Once the updates have finished you will get a green ribbon stating “Azure modules have been updated.” And the module versions will populate in the versions column of the modules page.

We can also review the job logs to ensure no errors were encountered. From the Jobs page click on the Completed job with the Runbook Titled Update-AutomationAzureModulesForAccount and select
All Logs.

Building the Runbook

Now that the Automation Accounts have been created and modules have been updated we can start building our runbook. But before we build the runbooks I want to walk you through tagging the VMs with custom tags that can be called upon later during the runbook.

Use the Favorites section to select Virtual Machines, check the boxes that correspond to the VM’s that you will be tagging and click Assign Tags. From the Assign Tags callout blade, you can use the text boxes to assign custom a Name (known as the Key property in Powershell) and a custom Value.
If you have already used custom tags for other resources they are also available from the drop-down arrow in the same text box fields. Click Assign to accept the tags.

You can click the Columns button in the ribbon bar to add the TAGS column to the Virtual Machines resource pane.

To start building the runbook we are going to select the Runbook
option from the Automation Account Pane and click Add a Runbook. When the Runbook Creation blade comes up click Create a Runbook, In the callout blade Give the runbook a name, select Powershell from the dropdown, and finally click Create.

At this point you will brought to the script pane of the Runbook. You can paste the attached script directly into the pane and it should look something like this.

Once the script has been pasted in, click the Test Pane button on the ribbon bar to ensure operability.

You’ll notice that only BlogServer2 and BlogServer3 were Shutdown and Deallocated. That is because earlier we only assigned the Tier:2 tags to those two VM’s and left BlogServer1 without a tag. If we go back to the Virtual Machine viewing pane we can verify the results.

Since the script processed correctly and is working as intended we can proceed to publishing the runbook. To return to the Runbook go to Automation Accounts -> (AutomationAccountName) -> Runbooks -> (RunbookName) -> Edit. Click Publish and confirm with Yes.

Invoking the Runbook Automatically

We now have a runbook that successfully Deallocated VM’s based on the custom tags we have set. But what are we using to invoke the runbooks? Well we could add a webhook, or manually call the runbook from the console, we could even create a custom application with a fancy GUI (Graphical User Interface) to call the runbook, for this article we are going to simply create a schedule within our automation account and use it to initiate our runbook.

To build our schedule we select Schedules from the Automation Account then click Add a schedule.

On the Schedule Runbook blade click Link a Schedule to a runbook, click Create a Runbook. Create a Schedule Name, Give it a description, assign a Start date and Time, set the Reoccurrence schedule and expiration and click Create. Now that the schedule has been created click OK to link it to the Runbook.

Originally, I used this runbook to shutdown VMs in an order so at the end of the Tier 2 Runbook would call the Tier 1 Runbook and finally the Tier 0 runbook. For Startup I would reverse the order to ensure services came up correctly. By splitting the runbooks, I ensured the next set of services did not start or stop until the previous set had finished.

However, by utilizing the custom tags and making minor changes to the script you can customize your runbooks to perform whatever suits your needs. For example, if you wanted to shutdown just John Smiths machines every night all you would need to do is tag the VMs accordingly (Ex. Name = Owner Key = JSmith) and then adjust the script to reflect those changes.


I have also attached the startup script that was mentioned earlier in the article for your convenience.

Thank you for taking the time to read through this article, I hope you can adapt it to you found it helpful and are able to adapt it your environment with no issues. Please leave a comment if you come across any issues or just want to leave some feedback.

Christopher Scott, Microsoft PFE.

Disclaimer The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.

Azure Automation – Custom Tagged