PowerShell, Hyper-V : Identify orphaned VHDX files

If you have a Hyper-V cluster of just a lot of VM's on a standalone Hyper-V server keeping track of all the virtual hard disks can become difficult. Eventually you will probably end up in a situation where you dont want to delete anything becaase you aren't 100% sure if its in use or not.  It's like that everywhere. Trust me. Very few people have a handle on this sort of thing.

This script compares the file system of your VHDX location with the actual config file of the VM's on you hosts and gives you a handy list of any VHDX files that exsist but aren't mounted on a VM.

These can be considered orphans.

$fullFilePaths = @()
$VMpaths = @()

#first we get the file paths of all the VM's in your cluster and pop them in an array
$vmhosts = Get-ClusterNode
foreach ($vmhost in $vmhosts)
{
$VMPath =  get-vm -ComputerName $vmhost | Get-VMHardDiskDrive 
$VMpaths = $VMpaths + $VMPath.path
}

#Now we get the file paths of all VHDX files in your storage location(s)
$partFilePaths = (Get-ChildItem "C:\ClusterStorage\Volume1" -name *.vhdx -recurse) 
foreach ($partFilePath in $partFilePaths)
{
    $fullFilePath1 = "C:\ClusterStorage\Volume1\" + $partFilePath
    $fullFilePaths = $fullFilePaths + $fullFilePath1
}

$partFilePaths = (Get-ChildItem "C:\ClusterStorage\Volume2" -name *.vhdx -recurse) 
foreach ($partFilePath in $partFilePaths)
{
    $fullFilePath2 = "C:\ClusterStorage\Volume2\" + $partFilePath
    $fullFilePaths = $fullFilePaths + $fullFilePath2
}

$partFilePaths = (Get-ChildItem "C:\ClusterStorage\Volume3" -name *.vhdx -recurse) 
foreach ($partFilePath in $partFilePaths)
{
    $fullFilePath3 = "C:\ClusterStorage\Volume3\" + $partFilePath
    $fullFilePaths = $fullFilePaths + $fullFilePath3
}
$partFilePaths = (Get-ChildItem "C:\ClusterStorage\Volume4" -name *.vhdx -recurse)

foreach ($partFilePath in $partFilePaths)
{
    $fullFilePath4 = "C:\ClusterStorage\Volume4\" + $partFilePath
    $fullFilePaths = $fullFilePaths + $fullFilePath4
}

$partFilePaths = (Get-ChildItem "C:\ClusterStorage\Volume5" -name *.vhdx -recurse) 
foreach ($partFilePath in $partFilePaths)
{
    $fullFilePath5 = "C:\ClusterStorage\Volume5\" + $partFilePath
    $fullFilePaths = $fullFilePaths + $fullFilePath5
} 

#Now we compare the 2 arrays. Anything that is in the Filepath array and not in the VM path array is an orphan
$Orphans = $fullFilePaths | Where {$VMpaths -NotContains $_}
       



Please sir, more of your delicious disk space.