Azure: Schedule PowerShell Scripts to Manage Virtual Machines
Background
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 this point in time. Also, the user also wanted another script to run some hours later to downscale the VM.
Introduction
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.
Pre-Requisite
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 create 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 most Azure Services, you will see the Quick Create and Dashboards menu. But what is important here, is the Runbooks and Assets menus.
Runbooks
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.
Assets
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 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:
$Cred = Get-AutomationPSCredential -Name "automationuser"
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.
Get-AzureVM -ServiceName "ubuntusvrcb" -Name "ubuntusvrcb" |
Set-AzureVMSize "A7" |
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.
Note:
1. Ubuntusvrcb = the name of the VM
2. A7 = the size of the VM
Set-AzureVMSize can accept the following values:
- ExtraSmall
- Small
- Medium
- Large
- ExtraLarge
- A6
- 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 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.
Meanwhile, you will notice that your VM will be restarted and the size of the VM will be increased to A7.
Parameters
Since the requirement is to scale down the VM later, it does not make sense to write 2 runbooks, instead, only one can be used, by parametrizing the size of the VM.
To do so, add a Size parameter.
param(
[parameter(Mandatory=$true)]
[string] $VMSize
)
And change the PowerShell as follows
Get-AzureVM -ServiceName "ubuntusvrcb" -Name "ubuntusvrcb" |
Set-AzureVMSize $Using:VMSize | #Use the parameter here
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 Link to a new schedule.
Add the name of the schedule and a description.
Add the schedule details
Here, it will run every 7 days as from the 2016-04-04 at 16:00. Next, specify the Parameters to be passed along with this schedule.
Same steps can be done to scale down the VM, the only difference would be to set the parameter to "Small".
Complete PowerShell Script
<#
This PowerShell script was automatically converted to PowerShell Workflow so it can be run as a runbook.
Specific changes that have been made are marked with a comment starting with "Converter:"
#>
workflow powershell_automation {
param(
[parameter(Mandatory=$true)]
[string] $VMSize
)
# Converter: Wrapping initial script in an InlineScript activity, and passing any parameters for use within the InlineScript
# Converter: If you want this InlineScript to execute on another host rather than the Automation worker, simply add some combination of -PSComputerName, -PSCredential, -PSConnectionURI, or other workflow common parameters (http://technet.microsoft.com/en-us/library/jj129719.aspx) as parameters of the InlineScript
inlineScript {
$Cred = Get-AutomationPSCredential -Name "automationuser"
Add-AzureAccount -Credential $Cred
Get-AzureVM -ServiceName "ubuntusvrcb" -Name "ubuntusvrcb" |
Set-AzureVMSize $Using:VMSize |
Update-AzureVM
}
}
References
- Automation documentation
- Getting Started with Azure Automation: Automation Assets
- Set-AzureVMSize
- How to: Change the Size of a Windows Azure Virtual Machine