Importing Hyper-V VMs After Rebuilding Host

One of my test lab host machines suffered a hard drive failure this week. The server started locking up at random intervals and become inaccessible, although the virtual machines it was hosting kept running. Before I got a chance to really investigate it the server completely died, and after a bit of testing I worked out that the hard disk that the server’s operating system was installed on had failed.

My lab hosts are not very resilient to this type of failure. I used to run clustered Hyper-V servers and RAID protected OS volumes but eventually it got too time consuming managing all that stuff and I took a more relaxed approach to the environment. VMs are spread across two hosts such that if one fails, even if a bunch of VMs are lost with it, my main test environment will survive and be recoverable with a little work. I also back the VMs up from time to time, just in case.

hyper-v

So a failed OS disk was no big deal. I had a spare I could put in the server, reinstalled Windows Server 2012 R2, discovered that the spare drive was also dead (must have been an earlier failed one I forgot to label correctly), installed another spare, reinstalled Windows Server 2012 R2 *again*, spent a bit of time fiddling with NIC drivers to get it all working, and then I’m ready to set up Hyper-V again. I installed the role, adding my virtual switches, and turned my attention to the VMs themselves.

None of the SATA and SSD disks in the server were damaged and still contained all of my VMs. I went looking for a quick way to re-import them into Hyper-V and was pleased to find that Import-VM let’s you do this in PowerShell very easily.

For example, I have a bunch of VMs on D:, E: and F: drives on this Hyper-V host. The config files for each VM are stored in XML, so the first step was to locate all of the XML files, starting with D: drive.

PS C:> Set-Location D:\
PS D:\> $vms = Get-ChildItem -Recurse -Include *.xml

Next, import them into Hyper-V.

PS D:\> $vms | % {Write-Host "Importing $($_.FullName)"; Import-VM -Path $_}

I used the Write-Host cmdlet so that I could see each XML file’s name as it was being imported. Just as well, because I had a few errors.

Import-VM : Unable to import virtual machine due to configuration errors.  Please use Compare-VM to repair the virtual
machine.
At line:1 char:50
+ $vms | % {Write-Host "Importing $($_.FullName)"; Import-VM -Path $_}
+                                                  ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Import-VM], VirtualizationOperationFailedException
    + FullyQualifiedErrorId : Microsoft.HyperV.PowerShell.Commands.ImportVMCommand

So what was the issue with the VMs that threw that error? As suggested I used Compare-VM to find out.

PS D:\> $report = Compare-VM -Path "D:\Virtual Machines\General\Virtual Machines\340FB73C-6EFF-475A-8285-B95A15600114.xm
l"
PS D:\> $report.Incompatibilities | fl
Message   : Virtual Hard Disk file not found.
MessageId : 40010
Source    : Microsoft.HyperV.PowerShell.HardDiskDrive

Looks like at least one of my VHDs is missing. Or rather they are not missing, but are in different locations. It seems I have run into this issue that is explained by Ben Armstrong. His solution worked for me.

PS D:\> $report.Incompatibilities[0].Source | fl

DiskNumber                    :
SupportPersistentReservations : False
MaximumIOPS                   : 0
MinimumIOPS                   : 0
ControllerType                : SCSI
ControllerNumber              : 0
ControllerLocation            : 2
Name                          : Hard Drive on SCSI controller number 0 at location 2
PoolName                      : Primordial
Path                          : D:\ProgramData\Microsoft\Windows\Hyper-V\Exchange 2016 Demo - DEMOEX16\Virtual Hard
                                Disks\exdemo refs test.vhdx
Disk                          :
ComputerName                  : HV4
Id                            : Microsoft:719F06C2-E5DE-4E12-9A63-1607C073048B\2DCBFBAB-8120-42A1-AA4D-39B577C2B285\0\2
                                \D
IsDeleted                     : False
VMId                          : 719f06c2-e5de-4e12-9a63-1607c073048b
VMName                        : Exchange 2016 Demo - DEMOEX16
VMSnapshotId                  : 00000000-0000-0000-0000-000000000000
VMSnapshotName                :
Key                           :

For some reason Hyper-V thinks that VHD is in a folder on D:\ drive, when it’s actually in a different folder on E:\ drive. Simply correct the path in the compatibility report, then import the VM based on the corrected report.

PS D:\> Set-VMHardDiskDrive $report.Incompatibilities[0].Source -Path "E:\Virtual Machines\exdemo refs test.vhdx"
PS D:\> Import-VM -CompatibilityReport $report
Name                          State CPUUsage(%) MemoryAssigned(M) Uptime   Status
----                          ----- ----------- ----------------- ------   ------
Exchange 2016 Demo - DEMOEX16 Off   0           0                 00:00:00 Operating normally

I had to repeat that for a small number of my VMs and then everything was back to normal operations.

By Paul Cunningham

Paul is a writer and entrepreneur living in Brisbane, Australia. He enjoys spending time with his family and running in the mountains. Paul was the founder of Practical 365, a former Microsoft MVP, and Pluralsight trainer. Paul is also on Twitter and Instagram.

1 comment

Comments are closed.