Bulk Registering Virtual Machines with PowerShell

I recently rebuilt a Hyper-V server – where all of my virtual machines were shutdown first and stored on a secondary disk.  Once I had finished installing the operating system and had Hyper-V up and running – I wondered what the most efficient way to get the virtual machines all reconnected would be.  I ended up using PowerShell to do a bulk import; however this did involve a bit of experimentation to get right.

The first thing I had to deal with was the fact that our “import-VM” command requires that you provide a .XML file to import.  An initial listing of all XML files in my virtual machines folder revealed a problem – there were XML files for virtual machines and for snapshots – and I needed to be able to differentiate between the two.

I ended up relying on the fact that the virtual machine XML file is always in a folder called “Virtual Machines” while the snapshot XML file is in a folder called “Snapshots”.  So this piece of PowerShell got me the right files:

Get-ChildItem e:\vms -Recurse -Filter "Virtual Machines" | %{Get-ChildItem $_.FullName -Filter *.xml} | select fullname

As shown here:

Capture1

The next concern that I had was that I did not know if I had all the files I needed / had named virtual switches correctly / etc…

If I were importing these virtual machines one at a time it would be easy to fix them up – but that would be annoying for a bulk import.  What I decided to do was to check if any virtual machines would fail to import – and then move them to another location for individual treatment later on.  To do this I used this piece of PowerShell:

Get-ChildItem e:\vms -Recurse -Filter "Virtual Machines" | %{write-host "VM Name: "$_.Fullname; Get-ChildItem $_.FullName -Filter *.xml} | %{Compare-VM $_.FullName -Register} | %{$_.Incompatibilities.message; write-host}

Shown here:

Capture2

What this PowerShell does is use the Compare-VM commandlet to let me know if any of the virtual machines would have compatibility issues with my new Hyper-V server.  After running this I either moved problematic VMs to a separate folder (the screenshot above is actually taken after I did this) so I could manually register them one at time later on.

Finally – I ran my command to import all of the known good virtual machines:

Get-ChildItem e:\vms -Recurse -Filter "Virtual Machines" | %{Get-ChildItem $_.FullName -Filter *.xml} | %{import-vm $_.FullName -Register}

The result of this was that in under a minute I had all of my virtual machines back and functioning on my new Hyper-V server.  Neat!

Cheers,
Ben