Imagine you had to resize a whole bunch of VMs in Azure, rather than doing a resize one after the other in serial, you can do this in parallel with the new ForEach-Object Parallel feature in PowerShell v7. More details on this feature here - https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/
Doing this in parallel will greatly speed up the process by resizing any number of VMs all at once. To start with, you will need a CSV file with two columns, vmname,targetsize. Enter all the VM names of the VMs that you want to resize, also the correct VM size.
Sample CSV file:
vmname,targetsize
VM01,Standard_DS14_v2
VM02,Standard_DS14_v2
To get a list of Azure VM sizes and the correct format for the name, run the following:
(Get-AzVMSize -Location 'Australia East').Name
This script will loop through all the VMs in the CSV file, shutting down the VM first before the resize happens. A full shutdown of the VM ensures that all target VM sizes are on offer across all Azure clusters, not just VM sizes of the current cluster in which your VM is a member of. First the script will get the status of the Private IP Allocation Method for the VM (Static or Dynamic) and if the private IP address is Dynamic, it will change it to a Static private address temporarily to make sure that the VM's private address stays the same while it's in a shut down state. Then after the resize happens, the VM is powered back up and if the Private IP Allocation Method was changed to Static part of this process, then it changed back to Dynamic, to keep the VM the same as it was originally.
The full script can be found below and here, be sure to read the lines at the top to make sure you gave the correct version of PowerShell v7 and the correct version of the Az (Azure) PowerShell module.
<#
Written with PowerShell v7.0.1 - install available here https://github.com/PowerShell/powershell/releases
Written with version 4.2.0 of the Az PowerShell Module
available from here https://github.com/Azure/azure-powershell/releases/tag/v4.2.0-June2020 or run: Install-Module -Name Az -RequiredVersion 4.2.0 -AllowClobber
Migration instructions Azure.RM to Az - https://azure.microsoft.com/en-au/blog/how-to-migrate-from-azurerm-to-az-in-azure-powershell/
#>
##########################################################################################
############################ Logon to Microsoft Azure #############################
##########################################################################################
$AzContextPath = "$($env:TEMP)\$(Get-Date -Format yyyyMMdd)AzEnv.json"
#region Logon to Azure | @marckean
Connect-AzAccount -Tenant '72f988bf-86f1-41af-91ab-2d7cd011db47'
##################### Subscription Select #####################
$subscriptions = Get-AzSubscription
$cnt = 1
Write-Host "ID Subscription Name"
Write-Host "-----------------------"
foreach ($sub in $subscriptions){
Write-Host "$cnt $($sub.name)"
$cnt++
}
$selection = Read-Host -Prompt "Select a subscription to deploy to"
$subSelect = $subscriptions[$selection - 1] # Revert 1-index to 0-index
Select-AzSubscription $subSelect.SubscriptionId
Save-AzContext -Path $AzContextPath -Force
#endregion
##########################################################################################
################################ List of VM sizes #################################
##########################################################################################
# Get a list of VM sizes, so you know exactly the format of the name:
(Get-AzVMSize -Location 'Australia East').Name | Select-String 'DS14'
##########################################################################################
############################# List of VMs to re-size ##############################
##########################################################################################
#region List of VMs to re-size | @marckean
########### Only do one of two options here ###########
# Option 1: Pull VMs from a .CSV file - two columns, headers (vmname,targetsize) | @marckean
$VMs_to_resize = Import-Csv -Path 'W:\VMs_to_resize.csv'
# Option 2: Pull VMs from a comma separated here string - this is practically a mini CSV file anyway | @marckean
$VMs = @'
vmname,targetsize
Hadoop01,Standard_DS14_v2
Hadoop02,Standard_DS14_v2
'@
$VMs_to_resize = $VMs | ConvertFrom-Csv
#endregion
##########################################################################################
################################ Resize the VMs ###################$##############
##########################################################################################
$VMs_to_resize | ForEach-Object -Parallel {
Import-AzContext -Path $using:AzContextPath
# Set private IP address to static to not loose it
$NicID = ((Get-AzVM -Name $_.vmname).NetworkProfile.NetworkInterfaces[0].Id)
$Nic = Get-AzNetworkInterface -ResourceId $NicID
$PrivateIpAllocationMethod = $Nic.IpConfigurations[0].PrivateIpAllocationMethod # Remember original Private IP Allocation Method
If($PrivateIpAllocationMethod -eq 'Dynamic'){ # only change the IP addess to static it's Dynamic
$Nic.IpConfigurations[0].PrivateIpAllocationMethod = 'Static'
Set-AzNetworkInterface -NetworkInterface $Nic}
Write-Output "$($_.vmname) is currently set as $PrivateIpAllocationMethod"
# Stop deallocate, resize the VM
$vm = Get-AzVM -Name $_.vmname
$VMsize = $_.targetsize
Write-Output "Change $($_.vmname) to $VMsize"
$vm | Stop-AzVM -Force
$vm.HardwareProfile.VmSize = $VMsize
Update-AzVM -VM $vm -ResourceGroupName $vm.ResourceGroupName
$vm | Start-AzVM
# Changing the Private IP address allocation method of a running VM to Dynamic using PowerShell doesn't cause a restart
If($PrivateIpAllocationMethod -eq 'Dynamic'){ # only change the IP addess back to Dynamic it was Dynamic in the first instance
$Nic = Get-AzNetworkInterface -ResourceId ((Get-AzVM -Name $_.vmname).NetworkProfile.NetworkInterfaces[0].Id)
$Nic.IpConfigurations[0].PrivateIpAllocationMethod = 'Dynamic'
Set-AzNetworkInterface -NetworkInterface $Nic}
}
https://gist.github.com/marckean/41c35f4160bdc1c40fb0865fbcdbe638
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.