Abstract
I searched through many, many, many…articles written
about Azure VM stop(de-allocate) to save cost. Every article only targets
single Azure VM to shutdown (de-allocate). None of the articles target start
and Shutdown of multiple Azure VMs using automation. I am going to address this
using Azure powershell in this article.
What all Cool features of azure VM start/ stop my script offers?
If you have multiple Azure VMs present in your azure
subscription; and you want to start or stop few of them on schedule then you
can use below azure PowerShell scripts. It will have below features –
è Add/
remove the VM names from the list of start/ stop schedule easily. [You don’t
need to have PowerShell knowledge]
è Use
same script in multiple different Azure runbooks, with different Azure VM names
to start and stop; that too with different schedules.
è In
case any wrong/ nonexistent VM name added to the list, script takes care of
giving relative user-friendly message and do not throw error. It continues with
other remaining set of Azure VMs and perform start or stop.
è Can
be used with single VM as well if required.
è You
start and stop azure VMs based on schedule hence obviously you optimize or save
Azure cost.
è Script
is available for download; hence you can own it to change in future. [that’s
cool 😊]
I can say all above feature are nothing but the “Key
differentiator” or “Value Proposition” from other Azure VM shut down/ start
automation blogs/ scripts. [These marketing terms; I hear them a lot 😊]
Fundamentals of Azure VM cost optimization
Azure VM are made of Compute and Storage. Compute is
nothing but Core (number of cores/ CPUs) and RAM you get when you provision
Azure VM. Storage is nothing but the C drive or other letter drives; except D
drive for windows and Sdb drive for Linux]. These drives are nothing but disks
or .vhd files present in Azure storage account [if VM is unmanaged] else disks
or .vhd files will be part of your subscription [if VM is created using managed
disks].
When we say you stop Azure VM from portal or using
PowerShell command “Stop-AzureRMVm” basically Compute part of VM is released
(or de-allocated). It is worth to mention here that “STORAGE PART REMAINS”.
So, when you think that if VM is in de-allocated state
then I am not charged, YOU ARE WRONG. You are not charged for compute/Cores
part; for storage capacity you are charged. However that is too cheap, so don’t
worry. Cores are costly and that is where you save cost.
Also if you shutdown Azure VM after taking RDP/ SSH,
compute is not released so you are charged for compute and storage both in that
case. Therefore, it is recommended that you stop azure vm either using portal
or PowerShell command. Refer the FAQ section from link
for more details.
Let’s go back to script part now.
Stop multiple Azure VMs script
#define the VM names which are required to be shutdown
$vmNamesToBeShutDown = "vm1", "vm2", "vm3"
foreach($vmName
in $vmNamesToBeShutDown)
{
$resource
= Find-AzureRmResource
-ResourceNameEquals $vmName
-ResourceType "Microsoft.Compute/virtualMachines"
if($resource -ne
$null)
{
Write-Output
"Stopping virtual machine..." + $vmName
Stop-AzureRmVM
-ResourceGroupName $resource.ResourceGroupName -Name
$vmName -Force
}
else
{
Write-output
"Virtual machine not found:" + $vmName
}
}
The variable $vmNamesToBeShutDown is very important. This is
where you can add as many VMs as you want to de-allocate them. The only
requirement is to add VM name in double quotes and comma separated.
The code then traverse through each of the VM names,
checks its existence and if found then fires command to de-allocate the azure
vm.
Start multiple Azure VMs script
#define the VM names which are required to be shutdown
$vmNamesToBeStarted = "vm1","vm2", "vm3", "vm4"
foreach($vmName
in $vmNamesToBeStarted)
{
$resource
= Find-AzureRmResource
-ResourceNameEquals $vmName
-ResourceType "Microsoft.Compute/virtualMachines"
if($resource -ne
$null)
{
Write-Output
"Starting virtual machine..." + $vmName
Start-AzureRmVM
-ResourceGroupName $resource.ResourceGroupName -Name
$vmName
}
else
{
Write-output
"Virtual machine not found:" + $vmName
}
}
The structure of the start Azure VM script is same as
that of Stop except the command used here to start VM is Start-AzureRmVM.
Here also you will only add VM names comma separated and
they will get automatically started once you schedule script running.
Automate and schedule the start/stop Azure VM scripts
Azure automation allows you to create PowerShell script
based runbook which can run automatically on pre-defined schedule.
The guidance here is copy paste above scripts in a
runbook in PowerShell. When you plan to run the PowerShell as runbook make sure
that you are using service principal authentication code at the start of
runbook as depicted in this link – http://sanganakauthority.blogspot.in/2017/05/run-login-azurermaccount-to-login.html.
The authentication code should be added before any other PowerShell code in
runbook. After creating runbook, publish it. Without publish runbook will not
execute.
Then create schedule in automation account as per
desired schedule. Screenshot below –
Once schedule is created, attach to runbook as below –
Similarly you can create as many as runbook and schedule
them at your will and it should work.
Hope this helps.
Happy automating!!
Nice script. You could also drive it using Tags (Key Value Pairs) added on a particular VM. For instance I've added a tag "AutoSet" = "A" and then using the following PowerShell command will populate a list of VMs from the particular set. You can obviously tweak as required.
ReplyDeleteGet-AzureRmVM | Where-Object {$_.Tags.AutoSet -ieq "A"}
Cheers
Christiaan
Thanks Christiaan. That's also a good idea.
DeleteI use tags for my runbook that automates snapshots. Works well. Thanks
Deletegreat information.
ReplyDeletethank you for posting.
keep sharing.
I tried to run this script in Automation runbook but didn't work for me after changing the Vm names as mentioned. Cant understand the error since I'm very new to scripting.
ReplyDeleteNice Post...Thanks for sharing the information...Keep Updating
ReplyDeleteGreat post and informative blog.it was awesome to read, thanks for sharing this great content to my vision.
ReplyDeleteThanks for providing this script. I have implemented and will try tonight.
ReplyDelete