Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

How to Resize Azure Virtual Machines using PowerShell Script

This PowerShell script automates resizing Azure VMs. First use Get-AzVMSize command as shown in the below screenshot to check supported and available VM sizes in the given Resource Group. From the generated list of the Virtual Machine Size names, Use selected one in the parameter and execute the main script with your inputs providing other required parameters. Make sure the Azure PowerShell (Az) module is installed and you’re logged in with Connect-AzAccount before running commands and scripts against Microsoft Azure resources.

Get-AzVMSize -VMName <Virtual Machine Name> -ResourceGroupName <Resource Group Name>

Screenshot of PowerShell output from Get-AzVMSize, listing available Azure VM sizes such as Standard_A2_v2 and Standard_D2ds_v4, along with their NumberOfCores, MemoryInMB, MaxDataDiskCount, OSDiskSizeInMB, and ResourceDiskSizeInMB.

Below is the main script Change-AzVMSize.ps1 output which shows what is happening in the background after execution. This script file need mandatory parameters -VmName-ResourceGroupName, and -NewVmSize. 

Caution: Resizing VM on Azure need to be stopped first. Make sure you are running this script with proper change management request and downtime window.

Screenshot of an Azure Virtual Machine's overview in the Azure portal, highlighting its current size property, before or after a resize operation.

You can download this PowerShell script Change-AzVMSize.ps1 or it also available on github.com.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<#
.SYNOPSIS
    Stops an Azure Virtual Machine, changes its size, and then starts it again.

.DESCRIPTION
    This script automates the process of resizing an Azure Virtual Machine.
    It first retrieves the specified VM, gracefully stops it (which is required
    for most VM size changes), updates its hardware profile with the new VM size,
    and then starts the VM back up.
    Error handling is included to provide informative messages if operations fail.

.PARAMETER VmName
    The name of the Azure Virtual Machine to be resized.

.PARAMETER ResourceGroupName
    The name of the Azure Resource Group where the Virtual Machine resides.

.PARAMETER NewVmSize
    The new Azure VM size (e.g., 'Standard_DS2_v2', 'Standard_D4s_v3').
    Ensure the new size is compatible with the existing VM configuration
    (e.g., supported disk types, available in the region).

.EXAMPLE
    # Resize a VM named 'MyWebAppVM' in 'ProductionRG' to 'Standard_D4s_v3'
    .\Resize-AzVM.ps1 -VmName "MyWebAppVM" -ResourceGroupName "ProductionRG" -NewVmSize "Standard_D4s_v3"

.EXAMPLE
    # Resize a VM and provide credentials if not already logged in (advanced)
    # Connect-AzAccount # Ensure you are logged into Azure
    # Get-AzSubscription | Out-GridView -PassThru | Select-AzSubscription # Select correct subscription
    # .\Resize-AzVM.ps1 -VmName "AppServer" -ResourceGroupName "DevServers" -NewVmSize "Standard_B2s"

.NOTES
    - Ensure you are logged into your Azure account via `Connect-AzAccount` before running this script.
    - Ensure you have selected the correct Azure subscription using `Select-AzSubscription` if you have multiple.
    - Not all VM sizes are available in all regions or compatible with all disk types.
      You can use `Get-AzVMSize -Location <YourAzureRegion>` to see available sizes.
    - Stopping the VM will incur downtime. Plan accordingly.
    - The original script had a commented-out line for tagging. You can uncomment and
      customize this line to automatically tag the VM after a size change if needed:
      `Get-AzResource -ResourceGroupName $ResourceGroupName -Name $VmName -ResourceType 'Microsoft.Compute/virtualMachines' | Set-AzResource -Tag @{ 'VMSizeChange' = 'True' } -Force`
    - Created by Janvi on 2024-10-01.
    - link: https://vcloud-lab.com
    - This script is provided as-is without warranty of any kind.
#>
param(
    [Parameter(Mandatory=$true)]
    [string]$VmName = 'test',

    [Parameter(Mandatory=$true)]
    [string]$ResourceGroupName = 'test',

    [Parameter(Mandatory=$true)]
    [string]$NewVmSize = 'Standard_DS1_v2' #'Standard_DS2_v2'
)

Write-Host "--- Azure VM Resizing Script ---" -ForegroundColor Cyan

# --- Step 1: Validate Azure Connection ---
try {
    if (-not (Get-Module -Name Az.Compute -ListAvailable)) {
        Write-Warning "Az.Compute module not found. Please install Azure PowerShell modules: Install-Module -Name Az -Scope CurrentUser"
    }
    $azContext = Get-AzContext -ErrorAction SilentlyContinue
    if (-not $azContext) {
        Write-Error "Not connected to Azure. Please run 'Connect-AzAccount' and 'Select-AzSubscription' if needed."
    }
    Write-Host "Connected to Azure subscription: $($azContext.Subscription.Name)" -ForegroundColor Green
}
catch {
    Write-Error "Azure connection check failed: $($_.Exception.Message)"
}

# --- Step 2: Get the Virtual Machine ---
Write-Host "Retrieving VM '$VmName' in Resource Group '$ResourceGroupName'..." -ForegroundColor Cyan
try {
    $vm = Get-AzVM -Name $VmName -ResourceGroupName $ResourceGroupName -ErrorAction Stop
    Write-Host "VM '$VmName' found. Current size: $($vm.HardwareProfile.VmSize)" -ForegroundColor Green
}
catch {
    Write-Error "Failed to retrieve VM '$VmName'. Error: $($_.Exception.Message)"
    Write-Error "Please ensure VM name and Resource Group are correct."
}

# --- Step 3: Stop the Virtual Machine ---
Write-Host "Stopping VM '$VmName'..." -ForegroundColor Yellow
try {
    $vm | Stop-AzVM -Force -ErrorAction Stop | Out-Null # -Force bypasses confirmation
    Write-Host "VM '$VmName' stopped successfully." -ForegroundColor Green
}
catch {
    Write-Error "Failed to stop VM '$VmName'. Error: $($_.Exception.Message)"
}

# --- Step 4: Update VM Size ---
Write-Host "Attempting to change VM size from '$($vm.HardwareProfile.VmSize)' to '$NewVmSize'..." -ForegroundColor Cyan
try {
    $vm.HardwareProfile.VmSize = $NewVmSize
    $vm | Update-AzVM -ErrorAction Stop | Out-Null
    Write-Host "VM '$VmName' size update initiated successfully." -ForegroundColor Green
}
catch {
    Write-Error "Failed to update VM size for '$VmName'. Error: $($_.Exception.Message)"
    Write-Error "Common reasons: Incompatible VM size, size not available in region, or resource locks."
}

# --- Step 5: Verify New VM Size (Optional, but good practice) ---
Write-Host "Verifying new VM size..." -ForegroundColor Cyan
try {
    # Re-retrieve VM object to get the latest properties
    $vm = Get-AzVM -Name $VmName -ResourceGroupName $ResourceGroupName -ErrorAction Stop
    Write-Host "VM '$VmName' new size: $($vm.HardwareProfile.VmSize)" -ForegroundColor Green
}
catch {
    Write-Warning "Could not re-retrieve VM properties to verify size. Error: $($_.Exception.Message)"
}

# --- Step 6: Start the Virtual Machine ---
Write-Host "Starting VM '$VmName'..." -ForegroundColor Yellow
try {
    $vm | Start-AzVM -ErrorAction Stop | Out-Null
    Write-Host "VM '$VmName' started successfully." -ForegroundColor Green
}
catch {
    Write-Error "Failed to start VM '$VmName'. Error: $($_.Exception.Message)"
}

Write-Host "--- VM Resizing Script Completed ---" -ForegroundColor Green

Below is the script breakdown in nutshell.

# Provide Name of VM.
$vmName = 'test'

# Validate provided Virtual Machine Name exists in Microsoft Azure subscription environment
$vmResources = Get-AzResource -Name $vmName -ResourceType 'Microsoft.Compute/virtualMachines'
#| Set-AzResource -Tag @{ 'VMSizeChange' = 'True' } -Force

# After validation store the information of VM in the variable.
$vm = Get-AzVM -Name $vmName -ResourceGroupName $vm.ResourceGroupName

# PowerOff - Stop VM before changing Size/SKU
$vm | Stop-AzVM -Force

# Verify and check current VMsize
$vm.HardwareProfile.VmSize

# Get available virtual machine size 
#Get-AzVMSize -VMName $vmName -ResourceGroupName $vm.ResourceGroupName

# Change valid Virtual Machine size and update VM.
$vm.HardwareProfile.VmSize = 'Standard_DS2_v2'
$vm | Update-AzVM

# Get VM information to check and verify new VM size
$vm = Get-AzVM -Name $vmName -ResourceGroupName $vm.ResourceGroupName
$vm.HardwareProfile.VmSize

# Start virtual machine once everything is ok
$vm | Start-AzVM

Here is the screenshot after VM size change, I have verified in overview summary portal. VM is Powered On after size change. Did quick health check, All looks good.

Screenshot of an Azure Virtual Machine's Overview blade in the Azure portal, displaying properties like OS, size (Standard_DS1_v2), IP addresses, and health status.

Useful Articles
Create an Azure virtual machine scale set and load balancer using Terraform
Azure Terraform fixed Availibility Zones on Virtual Machine Scale Set
Writing and Using Terraform modules
Terraform Using one module variable in another module
Hashicorp Terraform dynamic block with example
Terraform for_each loop on map example
Terraform for_each loop on resource example
Terraform manage similar resources with for_each loop inside modules
Importing existing resources into Terraform - Step by Step
Importing already created module Infrastructure into Terraform and update state file
Conditionally create resources in Terraform
How to create a Storage Account in Microsoft Azure
Host static website on Azure Storage Account
10 Useful Tips to Save Money as an Azure User

Go Back

Comment

Blog Search

Page Views

13060090

Follow me on Blogarama