Thursday, 9 April 2015

Stop an AzureVM using Azure Automation with a schedule


UPDATE: The script mentioned in this post is now here:

In this blog I will show you how to use Azure Automation to schedule a Powershell script to stop and deallocate a VM running in Azure. 

The reason I am blogging this is because I have spent a couple of days looking at other people's blogs and the information seems to not be quite correct. In particular, the need to use a self signed certificate from your Azure box is no longer required.

The reason you might want to do this is to save some money as when your Azure VM is stopped and deallocated, you will not be charged for it.

Firstly, I created a VM to play with called tempVMToStop as follows:

It required a username and password so I used my name. 

Once you have the VM you can remote desktop to it using the link at the bottom of the Azure portal and the username and password created in the previous step.

The next step is to add our automation script.

Now we go to automation in Azure:

Remember the goal of this blog is to automatically stop the following VM:
first we will need to create a user that is allowed to run our automation in Azure Active Directory as shown here:

Create the user to be used for automation:

Then go back into the automation section and choose Assets:

and add the automation user you just created here:

This is reasonably new as before you needed to create a self signed certificate on your VM and import the pfx file into an Asset => Credential but this is no longer needed.

Now go to the automationDemo and then choose Runbooks:

Click to create a new runbook:

Once it is created click on Author and write your script as follows:
workflow tempVMToStopRunBook

    # Specify Azure Subscription Name
    $subName = 'XXX- Base Visual Studio Premium with MSDN' 
    $cred = Get-AutomationPSCredential -Name "automationuser"
    Add-AzureAccount -Credential $cred
    Select-AzureSubscription -SubscriptionName $subName 

    $vm = Get-AzureVM -ServiceName $cloudServiceName -Name $vmName 
    Write-Output "VM NAME: $vm"
    Write-Output "vm.InstanceStatus: $vm.InstanceStatus"
    if $vm.InstanceStatus -eq 'ReadyRole' ) {
        Stop-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name -Force    


Note that the subscriptionname shown as  XXX - Base Visual Studio Premium with MSDN will need to be replaced by your subscription.

Also the workflow class name must be the same as the runbook name.

Save it and then you can choose to test it or just publish it. 
I will skip to publish as I have already tested it.

Once it is published you can click start and enter the 2 param names that the script is expecting:



Now we want to see that our VM stops so here was mine before:

Once you run it you will see some output when you click Jobs in the runbook:

And then if you look back at your VM it should be stopped:

Note that as we are totally deallocating the resources, the next time you start it up, it will get an new IP address but this will be all given to you in the VM section in your portal.

The next step is to obviously schedule what we just did and also schedule a start script so we could, for example, stop our VM at the end of a business day and start it in the morning at 8am so it is ready for us to use. 

This will save some money as the VM will not be using resources overnight.

Go back to the root of your automation and add a new asset for your schedule:

Here's one I created that will run the Power Shell script we created every day:

That's all there is to it. 

Note that I am no expert on Azure automation so all comments and constructive criticism are welcome.