In virtualised workstation environments on Windows 11, virtual hard disks formatted as VHDX frequently require storage capacity adjustments. As development workloads grow, guest partitions run low on unallocated space, requiring disk expansion. Conversely, after large builds, container image purges, or temporary file deletions inside guest operating systems, dynamically expanding VHDX files remain inflated on the physical host filesystem due to retained zero-fill blocks. Using Windows PowerShell and the Hyper-V module, administrators can execute online virtual disk expansions, shrink physical virtual disk boundaries, and reclaim wasted physical drive space through Resize-VHD and Optimize-VHD without launching the graphical Hyper-V Manager.
VHDX Disk Architecture: Expanding vs Compacting
Hyper-V VHDX format supports two fundamental storage maintenance operations:
- Disk Resizing (Resize-VHD): Modifies the maximum logical storage capacity exposed to the guest operating system.
- Expanding (Online/Offline): Can be performed online while the virtual machine is actively running (on SCSI controllers). Increases available disk space, allowing the guest volume to be extended.
- Shrinking (Offline): Requires the virtual machine to be powered down. Truncates unallocated sectors from the end of the virtual hard disk after the internal guest filesystem partition has been shrunk.
- Compacting (Optimize-VHD): Reclaims physical disk space on the host storage array without altering the maximum logical capacity. It scans the differencing or dynamically expanding VHDX, purges blocks that have been zeroed or discarded via TRIM, and collapses the physical file size on NTFS or ReFS volumes.
Auditing Existing Virtual Hard Disk Geometry in PowerShell
Before modifying disk geometry, inspect the target VHDX file properties using the Get-VHD cmdlet in Windows PowerShell as an Administrator:
# Query VHDX metadata
Get-VHD -Path "D:\Hyper-V\Disks\DevVM_OS.vhdx" | Select-Object `
VhdType, `
VhdFormat, `
@{Name="LogicalSizeGB"; Expression={[math]::Round($_.Size / 1GB, 2)}}, `
@{Name="PhysicalFileSizeGB"; Expression={[math]::Round($_.FileSize / 1GB, 2)}}, `
MinimumSize, `
FragmentationPercentage
Key attributes to note include:
- Size: The maximum logical disk capacity presented to the guest partition manager.
- FileSize: The actual physical byte count consumed by the VHDX file on the host storage volume.
- MinimumSize: The lowest byte threshold to which the disk can safely be truncated without truncating active partition data.
Expanding a Virtual Hard Disk Online via Resize-VHD
Hyper-V supports online disk expansion for virtual hard disks attached to virtual SCSI controllers. The virtual machine can remain fully operational throughout the expansion.
# Expand the logical capacity of the virtual disk to 120 GB
Resize-VHD -Path "D:\Hyper-V\Disks\DevVM_OS.vhdx" -SizeBytes 120GB
Once the host operation completes, extend the filesystem volume inside the guest operating system:
# Inside Windows guest (PowerShell as Admin)
$DriveLetter = "C"
$MaxSize = (Get-PartitionSupportedSize -DriveLetter $DriveLetter).SizeMax
Resize-Partition -DriveLetter $DriveLetter -Size $MaxSize
On Linux guests, use growpart and resize2fs (for ext4) or xfs_growfs (for XFS) to claim the expanded unallocated sectors.
Shrinking a Virtual Hard Disk via Resize-VHD
Shrinking a virtual hard disk requires two sequential steps: reducing the partition inside the guest, then truncating the VHDX file on the host. The virtual machine must be powered off.
Step 1: Shrink the volume partition inside the guest:
# Inside Windows guest: Shrink C: partition to 60 GB
Resize-Partition -DriveLetter C -Size 60GB
Step 2: Shut down the guest virtual machine from the host:
Stop-VM -Name "DevVM" -Passthru
Step 3: Query the new MinimumSize on the host to ensure safe boundary calculations:
(Get-VHD -Path "D:\Hyper-V\Disks\DevVM_OS.vhdx").MinimumSize / 1GB
Step 4: Execute the shrink command on the host:
# Shrink VHDX to match the targeted capacity
Resize-VHD -Path "D:\Hyper-V\Disks\DevVM_OS.vhdx" -ToMinimumSize
Compacting Dynamically Expanding Disks via Optimize-VHD
When files are deleted inside a guest, the guest OS marks blocks as unallocated, but the host VHDX container retains those physical sectors. Compacting strips unused blocks and shrinks the physical host file size.
To compact a dynamically expanding VHDX in Quick mode (compacts zero-filled sectors):
Optimize-VHD -Path "D:\Hyper-V\Disks\DevVM_OS.vhdx" -Mode Quick
To perform a comprehensive full compaction (mounts the VHDX as read-only, scans for zero blocks, and defragments storage structures):
Optimize-VHD -Path "D:\Hyper-V\Disks\DevVM_OS.vhdx" -Mode Full
Automating Zero-Filling Before Compacting Inside Guest
If compaction reclaims minimal space, deleted sectors may contain residual non-zero garbage data. Inside a Windows guest, run defrag with the slab consolidation switch prior to compaction:
# Inside Windows guest: Retrim filesystem to notify hypervisor of free blocks
Optimize-Volume -DriveLetter C -ReTrim -Verbose
On Linux guests, issue an fstrim -v / command prior to shutting down the virtual machine.
Mastering Resize-VHD and Optimize-VHD in Windows 11 allows virtualization administrators to maintain agile storage arrays and reclaim gigabytes of dormant host disk space with ease.