What are the possible reasons why Hyper-V can't compact a VHD?

Solution 1:

Remove the shadow copies from the guest. That will do it!

vssadmin delete shadows /all

Solution 2:

In the interest of Internet search consolidation: Eventually found this link thas an approach that has worked when HyperV compact did not: https://fiddley.wordpress.com/2014/01/27/dynamically-expanding-vhd-not-compacting-in-hyper-v/

In Administrative command prompt, run DISKPART

At the DISKPART command prompt

select vdisk File=”I:\path\to\your.vhd”
attach vdisk readonly
compact vdisk
detach vdisk

Solution 3:

Apart from the suggestion of deleting the shadow copies you should use SDelete for zeroing the empty space before compaction, since sometimes it allows compacting much more unused space. For example, for zeroing the empty space in C: you should run this from inside the virtual machine:

sdelete -z c:

In my case I had a virtual disk file with a total size of 80 GB, the first compaction reduced it only to 78 GB, deleting the shadows copies and compacting again reduced it to 72 GB, but after running sdelete the next compaction reduced the file size to 56 GB.