Q: How can I quickly find all virtual machines in a group of Hyper-V hosts that aren't stored in a specific location?

A: I previously moved all the virtual machines in a cluster to another location; however, I did this by dumping all the virtual machines that were cluster resources and moving them, even though some of the virtual machines might not have actually been clustered. I needed to find all the virtual machines that weren't stored in the new location. I used the following PowerShell code, which shows the virtual machine, its path, and the host it's currently running on:

Get-VM -ComputerName hypervhost1,hypervhost2,hypervhost3 | Where-Object {!$_.Path.StartsWith("C:\ClusterStorage\VM01\")} | ft Name, Path, ComputerName -autosize

To avoid having to type the name of each Hyper-v host in the cluster, I could use the following code instead. In addition, this code uses lowercase, to avoid case problems:

Get-ClusterNode | foreach {Get-VM -ComputerName $_.Name}| Where-Object {!$_.Path.ToLower().StartsWith("c:\clusterstorage\vm01\")} | ft Name, Path, ComputerName -autosize

I could use the following code to move the virtual machines to a new location:

$VMstoMove = Get-ClusterNode | foreach {Get-VM -ComputerName $_.Name}| Where-Object {!$_.Path.ToLower().StartsWith("c:\clusterstorage\vm01\")}

foreach ($VM in $VMstoMove)
{
    write-host $VM.Name
    $newpath = "C:\ClusterStorage\VM01\" + $VM.Name
    Move-VMStorage -DestinationStoragePath $newpath -VM $VM
}

This code is a modification of the code in "Use Hyper-V Live Storage Migration to Move Virtual Machines."