Hyper-V and Disk Fragmentation

There are 3 type of disk fragmentation you might need to deal with in regards to Hyper-V:

  1. Fragmentation of the file system on the host LUN where the VMs reside.
  2. Fragmentation of files system on the LUNs inside of the VM.
  3. Block fragmentation of the VHDX itself. This is potentially more of an issue with dynamic disks and differencing disks.

We deal with the first type by defragmenting the LUN, which might be a CSV, in which case you can take a look here for more information on this Defragmenting your CSV Windows 2012 R2 Style with Raxco Perfect Disk 13 SP2.  For more information on fragmentation in general take a look here What’s New in Defrag for Windows Server 2012/2012R. The second type is business as usual and is similar to the first one except that it’s the file system inside a VM.

For the third type we need to create a new virtual disk using the fragmented one as the source. See Checking and Correcting Virtual Hard Disk Fragmentation. This easily done but it does cause down time unless you leverage storage live migration. So that’s my preferred method, especially as I leverage ODX when I do this, so it’s pretty fast. So always leave yourself some margin on storage to be able to perform maintenance operations. That has always been true and still is.

But how do you find out that you have this issue? PowerShell is your friend! Here’s a snippet to show you can check all VMs their vhdx files on a cluster:

$AllVMsOnAllNodesInCluster = Get-VM -ComputerName (get-ClusterNode)
ForEach ($VM in $AllVMsOnAllNodesIncluster)
    #$HardDrives  = $VM.HardDrives
    invoke-command -ComputerName $VM.computername -ScriptBlock {
        param ($VM)
        Get-VM -Name $VM.Name | Get-VMHardDiskDrive | Get-VHD | ft path, fragmentationpercentage -AutoSize
    } -arg $VM

Here’s a screenshot of some output of this snippet


As said the best solution that does not incur down time is to storage (live) migrate the virtual disks affected. We can automate this and put in some logic to do this for all virtual hard disks that are more than X% fragmented. Do take care to also check for disk space or the migration will fail.

Hope this helps some of you!

6 thoughts on “Hyper-V and Disk Fragmentation

  1. This becomes more and more of a “problem” as VM-density per host (local storage) or CSV (shared storage) goes up. I’ve totally given up on any defragging, as mostly anyway all IOps together turn out to be largely random from the storage-perspective anyways (I know there are exceptions depending on application/workload type ofcourse). It’s just very costly in terms of IOps, and even outright “unnecessary” when using tiered storage as you’re just wearing your SSDs more. The tiering optimize even deliberately causes fragmentation, let alone when using dedup. Dynamic disks are dealing with this very very well actually. From all my VMs, only two ever get above 11% frag, and those 2 are VHDs instead of VHDx :-). Designing storage that can deal with any workload randomly in a more than sufficient matter is the solution to all of these “problems”, making defragging abbundant and even very counter-productive…

    • It all depends on what storage you have and what type of fragmentation. No one size fits all, but good storage design and not being to cheap goes a very long way in preventing fragmentation and having to deal with it.

  2. Refering to “3.Block fragmentation of the VHDX”. Are these vhdx occupying more space on CSV? In other words, in addition to performance gain due to defragmentation, would we also free up some space on CSV?

    • It’s fragmentation of the internal structure of the VHDX, that has no impact on the space consumed on the CSV/LUN. There is a bit more info in the Windows 201 R2 Optimization guide to check out. Just do a search for that and you’ll find the download.

  3. Hi. Our Hyper V cluster has 10 hosts. When trying to run your script on one of the hosts I get the following error/ouput:
    The term ‘Get-VM’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
    verify that the path is correct and try again.
    + CategoryInfo : ObjectNotFound: (Get-VM:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
    + PSComputerName : PROD01

    I have confirmed that get-vm works on its own. Any ideas would be greatly appreciated

    • Should and does work on W2K12R2. Can be a number of things, remoting, permissions … try to search for that error message as it’s nearly impossible and unfeasible for me to troube shoot specific errors. The MSFT technet/msdn forums are a great place to get help for that and many more eyes and helping hands of a very large community are available there to help out. Good luck.

Leave a Reply

Your email address will not be published. Required fields are marked *

* Checkbox GDPR is required


I agree

This site uses Akismet to reduce spam. Learn how your comment data is processed.