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.
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.
awesome, thanks for sharing!!