Schedule PowerShell Scripts to Manage Azure Virtual Machines


How to schedule a script that scales an Azure Virtual Machine up or down at specific times? This question was raised by a participant of the Global Azure Bootcamp who had some very heavy processing to do on an Azure Virtual Machine (VM) at a specific point in time and wanted to upscale the VM each week at the same point in time. Also, the user wanted another script to run some hours later to downscale the VM.


The above problem can be solved using Microsoft Azure Automation, which provides a way for users to automate the manual, long-running, error-prone, and frequently repeated tasks that are commonly performed in a cloud and enterprise environment. It saves time and increases the reliability of regular administrative tasks and even schedules them to be automatically performed at regular intervals. You can automate processes using Runbooks or automate configuration management using Desired State Configuration. 


To be able to schedule scripts, you first need to create an Azure Active Directory (AD) User whose credentials will be used to call the scripts.

To create the user, go to, Active Directory > Users > Create User. Set type of user to “New user in your organization”.

Set the role of user and do not enable two factor authentication. 

Create a temporary password that will be used for the user to login the first time. After this step, log out and login with the newly created user to change the password. 


The next step is to add the user as Administrator. To do so, go to settings and add the email created above as co-administrator. 


Microsoft Azure Automation

Now that everything is setup, you can create an Azure Automation Account. Just go to Azure Automation and click on create.

In the Account, as in most Azure Services, you will see the Quick Create and Dashboards menu. But what is important here, is the Runbooks and Assets menus. 


Runbooks in Azure Automation are based on Windows PowerShell or Windows PowerShell Workflow, so they do anything that PowerShell can do. If an application or service has an API, then a runbook can work with it. If you have a PowerShell module for the application, then you can load that module into Azure Automation and include those cmdlets in your runbook. Azure Automation runbooks run in the Azure cloud and can access any cloud resources or external resources that can be accessed from the cloud. 


The Assets page in Automation displays the various resources (also called “settings”) that are globally available to be used in or associated with a runbook, plus commands to import an integration module, add a new asset, or delete an asset. Assets include variables, schedules, credentials, and connections. 

Create a credential

To schedule a script, you first need to create a credential that will be used to execute it.

Credentials are either a username and password combination that can be used with Windows PowerShell commands or a certificate that is uploaded to Azure Automation. The properties for a credential are stored securely in Automation, and can be accessed in the runbook with either the Get-AutomationPSCredential or Get-AutomationCertificate activity.

To create a credential, in assets, click on add setting, then select Add Credential. 


Then, select “Windows PowerShell Credential” and add a name for the credential.

Then, add the AD Account created above and click on OK. 

Scale Azure VMs Using PowerShell

Follow the following steps to scale VMs using PowerShell,

  1. Select the Azure VM
  2. Set its size
  3. Update the VM
This process translates into PowerShell as follows,
  1. $Cred = Get-AutomationPSCredential -Name "automationuser"  
  2. Add-AzureAccount -Credential $Cred  
The Get-AzureAutomationCredential cmdlet gets one or more Microsoft Azure Automation credentials. By default, all credentials are returned. To get a specific credential, specify its name.

Notice that it references the credential created above.
  1. Get-AzureVM -ServiceName "ubuntusvrcb" -Name "ubuntusvrcb" |  
  2. Set-AzureVMSize "A7" |  
  3. Update-AzureVM  
The Set-AzureVMSize cmdlet updates the size of a Virtual Machine. It has two parameters: "InstanceSize", which is the new size of the virtual machine, and "VM", which is a virtual machine object retrieved by using the Get-AzureVM cmdlet. The result of Set-AzureVMSize can be piped to the Update-AzureVM cmdlet or stored in a variable for later use. No actual change is made until you run Update-AzureVM.

  1. Ubuntusvrcb = the name of the VM
  2. A7 = the size of the VM
Set-AzureVMSize can accept the following values:
  1. ExtraSmall
  2. Small
  3. Medium
  4. Large
  5. ExtraLarge
  6. A6
  7. A7
Hands on the Automation Runbook

Now that your PowerShell script is ready, it can be imported in the Azure Runbook. 

Click on import, browse for the file and click on OK.


From here, you can open the script and view/ test it in the “Author” menu. 

To test the script, click on Run! 

Meanwhile, you will notice that your VM will be restarted and the size of the VM will be increased to A7.



Since the requirement is to scale down the VM later, it does not make sense to write two runbooks, instead, only one can be used, by parametizing the size of the VM.

To do so, add a Size parameter.
  1. param(  
  2.    [parameter(Mandatory=$true)]  
  3.    [string] $VMSize  
  4. )  
And change the Powershell as follows,
  1. Get-AzureVM -ServiceName "ubuntusvrcb" -Name "ubuntusvrcb" |  
  2. Set-AzureVMSize $Using:VMSize | #Use the parameter here  
  3. Update-AzureVM  
Then, when running the Job, it will ask you for the parameter to be used.

Scheduling the Runbook

Before scheduling the runbook, it needs to be published. Click on Publish at the bottom of the runbook. 

Once published, go to the schedule tab and click on link to a new schedule.

Add the name of the schedule and a description.

Add the schedule details.


Here, it will run every seven days starting from  2016-04-04 at 16:00.

Next, specify the Parameters to be passed along with this schedule.

The same steps can be done to scale down the VM, the only difference would be to set the parameter to “Small”.

Complete PowerShell Script,
  1. <#  
  2.    This PowerShell script was automatically converted to PowerShell Workflow so it can be run as a runbook.  
  3.    Specific changes that have been made are marked with a comment starting with “Converter:”  
  4. #>  
  5. workflow powershell_automation {  
  6.    param(  
  7.       [parameter(Mandatory=$true)]  
  8.       [string] $VMSize  
  9.    )  
  10.    # Converter: Wrapping initial script in an InlineScript activity, and passing any parameters for use within the InlineScript  
  11.    # Converter: If you want this InlineScript to execute on another host rather than the Automation worker, simply add some combination o   f -PSComputerName, -PSCredential, -PSConnectionURI, or other workflow common parameters (  129719.aspx) as parameters of the InlineScript  
  12.    inlineScript {  
  13.       $Cred = Get-AutomationPSCredential -Name "automationuser"  
  14.       Add-AzureAccount -Credential $Cred  
  15.       Get-AzureVM -ServiceName "ubuntusvrcb" -Name "ubuntusvrcb" |  
  16.       Set-AzureVMSize $Using:VMSize |  
  17.       Update-AzureVM  
  18.    }  
  19. }