10 Nov

Resize the OS Disk in Resource Manager Azure Deployments using PowerShell

Recently I’ve had to increase the OS Disk size of about 10 Ubuntu virtual machines running on Microsoft Azure. Looking to the future I can also foresee this happening quite a few times so I thought I would write a script that could do this for me. The script essentially shuts the virtual machine down (after prompting you for confirmation), checks the new size is larger than the old size (an Azure requirement), resizes the disk to the new size and then starts the virtual machine back up.

There is a small quirk in the process that you will sometimes notice if you ever use the web UI to resize the OS disk. Azure sometimes doesn’t report the size of the disk correctly and so you don’t always know what the new size should be. To get around this I previously wrote a script (see here) which can get the disk size in an indirect way. Make sure you grab the retrieve size function from the linked post.

An example usage is the following:

Set-AzureRmOSDiskSize -VirtualMachineName "APP01" -ResourceGroupName "Platform-Dev" -SizeInGB 40

Here is the code below:

function Ask-ToContinue {

    param(
        [string]$message = $(throw "specify message"),
        [string]$prompt = $(throw "specify prompt")
    )

    $choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
    $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'))
    $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&No'))

    $decision = $Host.UI.PromptForChoice($message, $prompt, $choices, 1)
    
    return $decision -eq 0

}

function Set-AzureRmOSDiskSize () {

    param(
        [string]$VirtualMachineName = $(throw "Specify virtual machine name"),
        [string]$ResourceGroupName = $(throw "Specify resource group name"),
        [int]$SizeInGB = (throw "Specify Size in GB")
    )

    $currentSize = Get-AzureRmOSDiskSize -VirtualMachineName $VirtualMachineName -ResourceGroupName $ResourceGroupName

    if ($currentSize -ne $null -and $SizeInGB -le $currentSize) {

        throw "Specified Disk Size is not larger than current size"

    }

    $VM = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName -Status

    if ($VM -eq $null) {

        throw "Virtual Machine not found"

    }

    $VMRunning = ($VM.Statuses | ? { $_.Code -eq "PowerState/running" } | Measure-Object | Select -ExpandProperty Count) -eq 1

    if ($VMRunning) {

        Write-Host "The VM is currently running." -ForegroundColor Magenta

        $stopTheVM = Ask-ToContinue -message "The VM must be stopped" -prompt "Would you like to stop the VM now?"

        if ($stopTheVM) {

            Write-Host -ForegroundColor Yellow "Stopping the VM"
            Stop-AzureRmVM -Name $VirtualMachineName -ResourceGroupName $ResourceGroupName -Force

        } else {

            Write-Host -ForegroundColor Cyan "Not stopping the VM."
            return

        }

    }

    $VM = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName
    $VM.StorageProfile.OsDisk.DiskSizeGB = $SizeInGB

    $result = Update-AzureRmVM -VM $VM -ResourceGroupName $ResourceGroupName

    if ($result.IsSuccessStatusCode) {
        
        Write-Host -ForegroundColor Green "Updated VM Successfully"

    }

    $startTheVM = Ask-ToContinue -message "The VM is currently stopped" -prompt "Would you like to start the VM now?"

    if ($startTheVM) {

        Write-Host -ForegroundColor Yellow "Starting the VM"
        Start-AzureRmVM -Name $VirtualMachineName -ResourceGroupName $ResourceGroupName

    }

}