In several previous posts, I discussed how to resize the virtual hard disks on an Azure virtual machine using Azure CLI and PowerShell. In this post, I’m going to walk through how to resize an Azure virtual machine with PowerShell, and cover how to convert these commands into a script.
Log In and Verify Subscription
As always, we want to be sure we have PowerShell connected to Azure and that we using the right subscription. So, we login and then call Get-AzureRmContext
to see which subscription is selected:
Login-AzureRmAccount
(Get-AzureRmContext).Subscription.Name
Example output:
Visual Studio Enterprise
If you see no output, you are not connected to any Subscription. If you see the wrong subscription, then you will need to change it with Set-AzureRmContext
as follows:
$subscription = Get-AzureRmSubscription `
-SubscriptionName "BizSpark"
Set-AzureRmContext -SubscriptionObject $subscription
Deallocate the Virtual Machine
In order to resize a virtual machine, we have to shut it down and deallocate it first:
Get-AzureRmVM -ResourceGroupName $rg -Name $vm_name |
Stop-AzureRmVM -Force -AsJob
Throughout the post I refer to variables instead of the literal names, like the above example. We will be able to convert this to a script later much more easily as a result, and it will allow you to use the examples on whatever specific instances in your environment with minimal change.
We are doing our work in PowerShell, so to use these variables names we simply assign them values, as in this example:
$rg = 'lab1-rg'
$vm = 'ws2016server1'
To verify our virtual machine is deallocated, we have a couple of options. If we used the -AsJob
switch, like I did above, then all we need to do is pull that job up and check its status, like this:
Get-Job -Newest 1 | select Name,JobStateInfo
Example Output:
Name JobStateInfo
---- ------------
Long Running Operation for 'Stop-AzureRmVM' Completed
Otherwise, we can use the Get-AzureRmVM
cmdlet again, with the virtual machine name and the -Status
switch, which will show us detailed status by returning what’s called an Instance View of the virtual machine:
Get-AzureRmVM -ResourceGroupName $rg -Name $vm -Status
Example output:
ResourceGroupName : lab-rg
Name : ws2016server1
Disks[0] :
Name : ws2016server1-disk-os
Statuses[0] :
Code : ProvisioningState/succeeded
Level : Info
DisplayStatus : Provisioning succeeded
Time : <Date and Time>
Statuses[0] :
Code : ProvisioningState/succeeded
Level : Info
DisplayStatus : Provisioning succeeded
Time : <Date and Time>
Statuses[1] :
Code : PowerState/deallocated
Level : Info
DisplayStatus : VM deallocated
Note the PowerState
under Statuses[1]
. If we want to access this particular status by name later, in our script, PowerShell provides us a number of ways. Here’s one…
$vm_state = Get-AzureRmVM -ResourceGroupName $rg -Name $vm -Status
$vm_state.Statuses.Code -match 'Power'
Example Output:
PowerState/deallocated
We could then further extend our script functionality based on that PowerState
status.
Get the Current Disk Size
Next we should determine the current size of the disk, so we can compare it against the size we want to expand it to. The first step is to locate the disk ID and assign it to a variable, with the following query:
$vm_current = Get-AzureRmVM -ResourceGroupName $rg -Name $vm
$disk_name = $vm_current.StorageProfile.OsDisk.Name
(We could have done this in one line, but it’s a bit easier to read this way.)
Once we have the OS disk ID assigned to $disk_id
, we can use it to lookup the disk:
Get-AzureRmDisk $rg $disk_name |
select Name,DiskSizeGB,@{N='Tier';E={$_.Sku.Name}}
(If you’re wondering what the last bit is with the @{N='Tier'...
, it’s just a way for us to map the Storage SKU Name into a custom column of our output object, instead of having $_.Sku.Name
as the column header.)
Example output:
Name DiskSizeGB Tier
---- ---------- ----
ws2016server1-disk-os 127 StandardLRS
This is good output because it confirms both the current size of the disk, and reminds us what storage tier it’s using, in case that’s a concern.
Aside: You may be wondering why we didn’t just look up the disk directly, by name. We could have. The reason we didn’t is that most of the time we need to expand a disk, we are doing so based on some request that refers to the virtual machine by name, not the disk. Additionally, in some environments disk names are “square” with the virtual machine names, and in others, they aren’t. So, it’s a good idea to start at the source and programmatically move to the destination.
Additional Reading
- Documentation: Use PowerShell to resize a Windows VM in Azure
- Documentation: Windows VM sizes in Azure
- Documentation: