Specifically I am talking here about Hyper-V Server 2012 /2012R2 with VHD's stored on an NTFS volume on a ISCSI target with compression enabled.
Degragmenting an NTFS volume COPIES the data from blocks to re-arrange it and defragment. It does not write 0's to the (now) un-used blocks, which will screw up your compression and deduplication. Zero filled blocks dedup/compress extremely well. As you VHD's fluctuate in size, and your guest VM's with NTFS volumes ALSO run defragmentation (and they should) you will end up with "empty" blocks that are not zero filled. (both in the guest VM and on the hyper-v host)
How do you get back that space?
One way is to use a program called Erase to write 0's to all the empty blocks on your NTFS volumes hosted on ISCSI targets.
With the free version of Hyper-V, Hyper-V Server, you will need to manually install the 3.5 .NET framework and manually start the eraser.exe program from its installation folder, but otherwise you can use the
"British HMG Infosec Standard 5, Baseline Standard" which writes 0's to empty blocks when cleaning empty space.
To install 3.5 .NET framework on hyper-v, use the command prompt to copy a Server 2012 ISO image to the C: drive of your hyper-v server.
mount the ISO image with
powershell Mount-DiskImage
then give it the path to the ISO image you copied.
now
powershell Get-Volume
to see what drive letter the ISO image ended up at.
install the 3.5 framework:
dism /online /enable-feature /featurename:NetFX3 /all /Source:K:\sources\sxs
replace K: with the drive letter of the iso image, and you should then be able to install Eraser and run it from the command line (first switching to its install directory.)
make sure to configure the 0 byte fill and you can add a task to erase empty space on your NTFS ISCSI target volumes.
this will be more effective if you also run it inside your VM's that have NTFS volumes you defragment.