Scale-AzureRMVMUpRunbook.ps1
<#PSScriptInfo
.VERSION 1.0.0 .GUID 54dbaefd-ef34-461a-90a6-b9481321517f .AUTHOR Arjun Bahree .COMPANYNAME .COPYRIGHT .TAGS Windows PowerShell Azure AzureAutomation Runbooks AzureManagedDisk AzureUnmanagedDisk AzureDataDisk AzureStorage .LICENSEURI https://github.com/bahreex/Bahree-PowerShell-Library/blob/master/LICENSE .PROJECTURI https://github.com/bahreex/Bahree-PowerShell-Library/tree/master/Azure%20Automation%20Runbooks .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION Lets you Scale Up any Azure RM VM from its current size to a new size within the same Family. #> <# .SYNOPSIS Lets you Scale Up any Azure RM VM from its current size to a new size within the same Family. .DESCRIPTION This Runbook lets you Scale Up any Azure RM VM from its current Size to a new size that you specify. By default the new size to scale is Immediately after the current size in the Size Table published by Microsoft, which means the SizeStep parameter with value 1. However, if you specify another value for SizeStep parameter, which should be greater than your current VM size number in the Size Table, your VM will be scaled up to that Size in the Size table corresponding to that number. If your VM is already at the last size of the VM family, you will not be able to scale up the VM any further as cross-family Scaling-Up is not allowed by Microsoft Azure. Since Microsoft does not make the VM Size Table available in a format that cna be consumed programmatically for reference, I have manually created the same and publicly shared through a Gist in my Github repository. The URL for the Gist is embedded in the Runbook code, which I will regularly update as and when Microsoft updates the VM Size table. You can find the most current VM Size table at the Gist URL (https://gist.github.com/bahreex/96a611b5ca05de2df2c3d7f45b11b75d) and within this repository as a CSV file named "Azure-VM-Sizes-29122017.csv". You need to execute this Runbook through a 'Azure Run As account (service principal)' Identity from an Azure Automation account. .Parameter ResourceGroupName Name of the Resource Group where the target VM is located .Parameter VMName Name of the target VM .Parameter SizeStep Scalar value between 1 to 8. This has a default value of 1, which will upgrade the VM to Immediately next size within same VM family within the Size Table. The value you specify in this parameter, which should be greater than the current VM size number in the Size Table, will be used to scale up your VM to that Size in the Size table corresponding to the specified number. .EXAMPLE .\Scale-AzureRMVMUp.ps1 -ResourceGroupName rg-100 -VMName vm100 -SizeStep 2 .EXAMPLE .\Scale-AzureRMVMDown.ps1 -ResourceGroupName rg-100 -VMName vm100 .Notes Author: Arjun Bahree E-mail: arjun.bahree@gmail.com Creation Date: 11/Jan/2018 Last Revision Date: 12/Jan/2018 Version: 2.0 Development Environment: Azure Automation Runbook Editor and VS Code IDE PS Version: 5.1 Platform: Windows #> param ( [Parameter(Mandatory = $true)] [string]$ResourceGroupName, [Parameter(Mandatory = $true)] [string]$VMName, [Parameter(Mandatory = $false)] [ValidateRange(1, 8)] [int]$SizeStep = 1 ) if (!(Get-AzureRmContext).Account) { $connectionName = "AzureRunAsConnection" try { # Get the connection "AzureRunAsConnection " $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName $account = Add-AzureRmAccount ` -ServicePrincipal ` -TenantId $servicePrincipalConnection.TenantId ` -ApplicationId $servicePrincipalConnection.ApplicationId ` -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint } catch { if (!$servicePrincipalConnection) { $ErrorMessage = "Connection $connectionName not found." throw $ErrorMessage } else { Write-Error -Message $_.Exception throw $_.Exception } } } # Create Stopwatch and Start the Timer $StopWatch = New-Object -TypeName System.Diagnostics.Stopwatch $StopWatch.Start() function ResizeVM ($rgName, $vmName, $newVMSize) { Write-Output "Scaling-Up $vmName to $newVMSize ... this will require a Reboot!" $vmRef = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName $vmRef.HardwareProfile.VmSize = $newVMSize $Job = Update-AzureRmVM -VM $vmRef -ResourceGroupName $rgName -AsJob Get-Job | Wait-Job | Receive-Job > $null } Write-Output "Starting the VM Scaling-Up Process." $VM = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName -ErrorAction SilentlyContinue If ($VM) { $vSize = $VM.HardwareProfile.VmSize $vmSizeURL = "https://gist.githubusercontent.com/bahreex/96a611b5ca05de2df2c3d7f45b11b75d/raw/bf2065fd27171d616b6c2373d58a387a82dff114/Azure-VM-Sizes-29122017.csv" $content = (Invoke-WebRequest -Uri $vmSizeURL -UseBasicParsing).Content $vmSizes = $content.Split("`r`n") $vmFamilyList = @() foreach ($line in $vmSizes) { $row = $line.split(','); if ($row -contains $vSize) { $index = $row.IndexOf($vSize) $count = 0 foreach ($subLine in $vmSizes) { $subRow = $subLine.split(','); if ($count -eq 0) { $vmFamily = $subRow[$index] } else { if ($subRow[$index]) { $vmFamilyList += $subRow[$index] } } $count++ } break } } $nextSizeIndex = $vmFamilyList.IndexOf($vSize) + $SizeStep if (!$vmFamilyList[$nextSizeIndex]) { # Stop the Timer $StopWatch.Stop() Write-Output "The VM $($VM.Name) is at the maximum allowed size for the $vmFamily family." } else { # Call ResizeVM function to do the resizing ResizeVM $ResourceGroupName $VMName $vmFamilyList[$nextSizeIndex] Write-Output "The Scaling-Up for VM $($VM.Name) has been completed!" # Stop the Timer $StopWatch.Stop() # Display the Elapsed Time Write-Output "Total Execution Time for Scaling Up the VM: $($StopWatch.Elapsed.ToString())" } } else { # Stop the Timer $StopWatch.Stop() Write-Output "Could not get the VM {$VMName} in the Resource Group {$ResourceGroupName}." } |