Table of contents
I’d like to think that we plan ahead and build Hyper-V virtual machines with adequate disk space. But sometimes our best plans can quickly fly out the window. Or you might have a legacy virtual machine that you can’t get rid of yet but its disk space is becoming an issue. Fortunately, this is easily remedied with the Resize-VHD cmdlet. Let me walk you through how I fixed such an issue.
On my test Hyper-V rig I have an older Windows 7 virtual machine that is just about out of space as you can see here.
Fig 1 Drive C running out of space
Since there’s very little to be done I’ll shut it down for now. I need to do that anyway in order to resize the VHD file anyway. Using PowerShell, I can get all of the disk files associated with the virtual machine and pass each path to the Get-VHD cmdlet to return more detailed information.
PS C:> get-vm "jdhlab win7" | select -expand HardDrives | get-vhd
My results can be seen here.
Fig 2 the current state of the VHD file
As you can see from the highlighted section, there’s no more space in the VHD file. I’ll need to resize it. I’m a “belt and suspenders” kind of IT Pro, so first I’m going to create a copy of the existing VHD file in case something goes wrong by copying it to a different location.
PS C:> get-vm "jdhlab win7" | select -expand HardDrives | select -first 1 | copy -destination e:backup
Once that is finished I’m ready to begin resizing. The Resize-VHD cmdlet needs the path to the VHD (or VHDX) file. But I don’t feel like copying and pasting so I’ll modify copy command, since I already know it gets the problem disk file.
PS C:> get-vm "jdhlab win7" | select -expand HardDrives | select -first 1 | resize-vhd -SizeBytes 20gb –passthru -whatif What if: Performing operation "Resize-VHD" on Target "C:UsersPublicDocumentsHyper-VVirtual hard disksWin7-2.vhd".
I am taking advantage of the Resize-VHD –WhatIf parameter to verify I’ve selected the correct disk file. I’m going to resize it to 20GB. This looks good so I can press the up arrow in the console, delete –Whatif and let the cmdlet do its thing. This shouldn’t take too long. I used –Passthru so the cmdlet would write the new disk file object back to the pipeline. You can see the new size.
Fig 3 The expanded VHD
Excellent. Time to fire up the virtual machine.
PS C:> start-vm "jdhlab win7"
The operating system shows the new unallocated space.
Fig 4 Unallocated space after resizing
The process of extending the disk might vary by operating system. In this case, all I need to do is right-click on the C: partition, select Extend Volume and follow the wizard to use the new 5GB of space.
Fig 5 Extension complete.
Problem solved! Extending files will work with both VHD and VHDX formats. If you are using the latter, you can also shrink the volume back to its minimum size.
[optin-monster-shortcode id=”lwzgfpb294pntqna”]
Lastly, let me demonstrate how to use PowerShell to determine which files might be in need of resizing. Here’s a relatively simple one-line PowerShell command that you could put into a script file.
#requires -version 3.0 Get-VM | select -expand harddrives | foreach { $vm = $_.VMName Get-VHD $_.path | Select @{Name="VMName";Expression={$vm}}, Path,VHDType,VHDFormat,Size,FileSize,FragmentationPercentage, @{Name="Utilization";Expression={($_.filesize/$_.size)*100}} } | Out-GridView -Title "VHD Report"
This command gets all hard drives for all virtual machines and then selects some key properties. The main one is something I added called Utilization which should show you a utilization percentage. This sample is send the results to Out-Gridview so I can further sort and filter. I’ve clicked on the Utilization column to sort in descending order.
Figure 6 A disk drive utilization report
But you could just as easily save the information to a CSV file, XML or even an HTML report. I could even write a PowerShell script to take this information and for drives that exceed a certain value, calculate a new size based on a percentage such as 25%, take the virtual machine offline if running, resize the file and bring the virtual machine back on line. But personally, unless I was managing hundreds of virtual machines where this might be necessary, I’m quite satisfied to use PowerShell to identify what VHD files need resizing and then handling it on my own.