We are using Hyper-V R2 as a platform for virtualizing development and testing environment.

After month of use, with creating / deletion of many virtual machine, the vhd store is filled with a lot of vhd and avhd files. Some of them are drives of delete virtual computers.

How can I clean up the virtual drive folder ?

Is there any command line (PowerShell?) than can enumerate all virtual computers' disk binding (so I can remove all except this list) ?

[Edit] A bit of progress

I can list all xml file for VM definitions and analyse the controller sections :

    <pathname type="string">V:\Hyper-V\Virtual Hard Disks\my_computer_7679176A-F7AE-4D40-AC28-67FFDE7E2FEB.avhd</pathname>
    <type type="string">VHD</type>
    <pathname type="string">V:\Hyper-V\Virtual Hard Disks\my_computer_60892A6B-6AB4-44D7-8F08-509BF0E70A05.avhd</pathname>
    <type type="string">VHD</type>

However, as the computer can have snapshots, it only enumerates attached disks, and not their parents disks, which are also required.


After some digging, I used this method :

First, get all disks of all virtual machines (my server is in french, you should replace "Disque dur" by "Hard drive" for English systems) :

$disks = Get-vm | Get-VMDisk | ? { $_.DriveName -Match "disque dur" }

Then, I extract all VHD paths :

$vhds = @()
$disks | % { Get-VHDInfo $_.DiskPath } | % { $vhds+= $_.Path }
$vhds = $vhds | select -unique
write-host $vhds.Length -Foreground Yellow

Finally, I run the following code as often as required. I stop when the length of the array stops growing :

$disks | % { Get-VHDInfo $_.DiskPath }  | select ParentPath | ? {$_.ParentPath.Length -Gt 0} | % { $vhds+= $_.ParentPath }
$vhds = $vhds | select -unique
write-host $vhds.Length -Foreground Yellow

$vhds | % { Get-VHDInfo $_ }  | select ParentPath | ? {$_.ParentPath.Length -Gt 0} | % { $vhds+= $_.ParentPath }
$vhds = $vhds | select -unique
write-host $vhds.Length -Foreground Yellow

#Repeat while Length grows

At the end, $vhds contains all used drives and their parents. Simply enumerate all .vhd and .avhd files and substract the $vhd array to find useless disks.

I know this could be rewritten in a nice script, but it solved my problem.

These cmdlets are included in Windows Server 2012, are are a separate download for previous OSes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.