Why?
I often encountered VMs power down issues in my workplace. When I referred to the logs related to the issues are, storage was not sufficient. Then, I increase the size of the virtual hard disk. Voila!
but, let's say we have tons of VMs or often VMs power-down due to the storage issue, manually upgrading virtual disks are not possible. this where automation comes in.
So, I've decided to extend the disk space of Windows 2012/2016 VMs running on Hyper-V (I'll write a blog for Vms running on VMWare as well in my next post).
In this blog, I'll show how to increase and extend the C drive. In order to do this, we need to consider some cases mentioned below.
1. Get list of VMs Name
2. Get particular VM's virtual disk path
3. Resize the VHD/VHDx
4. Remote to the VM and Extend it's C drive Size.
Before we do this, I want you to understand about Virtual HardDisk (VDH/VDHx)
Hyper-V uses two different formats for virtual hard disk files: the original VHD and the newer VHDX.
You can resize any of Hyper-V’s three layout types (fixed, dynamically expanding, and differencing). However, you cannot resize an AVHDX file (a differencing disk automatically created by the checkpoint function).
Resizing a virtual disk file only changes the file. It does not impact its contents. Meaning that we need to go VMs Specific drive to extend otherwise, Disk which was extended remain unallocated space to the VMs File System.
Requirements for VHD/VHDX Disk Resizing
- If the virtual machine is Off, any of its disks can be resized as though no one owned them
- If the virtual machine is Saved or has checkpoints, none of its disks can be resized
- If the virtual machine is Running, then there are additional restrictions for resizing its virtual hard disks
In this tutorial I'm gonna resize running VMs only (if so, VDHx type Virtual Disk can only be partitioned. In my case, I'm Running 2016 server which is typically VDHx type)
How to check VDH type
Get-VM -VMName $VM | Select-Object VMId | Get-VHD
Get-VM -VMName $VM | Select-Object VMId | Get-VHD
1. Get list of VMs Name
$path = Read-Host "provide path or list of VM file EG: C:vm.txt"
2. Get VM's Guest username and password
2. Get VM's Guest username and password
So that, we login vm and extend C drive
Write-Host "enter the vm user password (valid user name and password for login VMs)" $UserVM = zss\fayasak $PasswordVM= Read-Host -Prompt " Guest Password for VM `n" $Crendential= New-Object System.Management.Automation.PSCredential ($UserVM, $PasswordVM)
3. Get particular VM's virtual disk path
$VMs = Get-Content $path
Foreach ($VM in $VMs)
{
#get the VHDX path of the particular VM
$vhdxpath=Get-VM | Select-Object VMId | Get-VHD | select path
4. Resize the VHD/VHDx
I resized with 30gb
Resize-VHD -Path $vhdxpath -SizeBytes 30gb
5. Remote to the VM and Extend it's C drive Size.
store the login session into the variable and $credential provide the username password which was given earlier.
$pss=New-PSSession -VMName $VM -Credential $Crendential
Invoke-Command -SciptBlock {command here}
Above mentioned script is to execute PowerShell script to the specified VM
Using Invoke-Command and Session which was stored earlier below script is being used to remotely execute PowerShell command to the VM.
Invoke-Command -Session $pss -VMName $VM -ScriptBlock {'Update-Disk -Number 0;$m=(Get-PartitionSupportedSize -DriveLetter c).sizeMax;Resize-Partition -DriveLetter c -Size $m' }
Write-Host "enter the vm user password (valid user name and password for login VMs)" $UserVM = zss\fayasak $PasswordVM= Read-Host -Prompt " Guest Password for VM `n" $Crendential= New-Object System.Management.Automation.PSCredential ($UserVM, $PasswordVM)
3. Get particular VM's virtual disk path
$VMs = Get-Content $path
Foreach ($VM in $VMs)
{
#get the VHDX path of the particular VM
$vhdxpath=Get-VM | Select-Object VMId | Get-VHD | select path
4. Resize the VHD/VHDx
I resized with 30gb
Resize-VHD -Path $vhdxpath -SizeBytes 30gb
5. Remote to the VM and Extend it's C drive Size.
store the login session into the variable and $credential provide the username password which was given earlier.
$pss=New-PSSession -VMName $VM -Credential $Crendential
Invoke-Command -SciptBlock {command here}
Above mentioned script is to execute PowerShell script to the specified VM
Using Invoke-Command and Session which was stored earlier below script is being used to remotely execute PowerShell command to the VM.
Invoke-Command -Session $pss -VMName $VM -ScriptBlock {'Update-Disk -Number 0;$m=(Get-PartitionSupportedSize -DriveLetter c).sizeMax;Resize-Partition -DriveLetter c -Size $m' }
Find full PowerShell script here
That's it! and Peace!!!!
No comments:
Post a Comment