Restoring a physical server into a Hyper-V test VM sounds straightforward. Veeam Instant Recovery promises a running VM in minutes, not hours. For the most part, it delivers.
Until the boot manager can’t find Windows.
On July 7, 2026, I spun up a sandbox VM from a Veeam Agent backup of our production server. The goal was simple: a disposable test bench for Windows Update experiments. What followed was a spiral through vPower NFS internals, BCD partition references, and a drive letter that should never have been Z:.
The Environment
- Host: Windows Server 2019, Hyper-V, Veeam Backup & Replication
- Backup: Veeam Agent for Windows (managed), backing up the host itself
- Restore type: Instant Recovery to Hyper-V (Gen 2, UEFI)
- Storage: E: drive (8TB HDD), single spindle for both backup repository and IR differencing disks
- Sandbox VM:
j-server, 6 vCPUs, dynamic memory, NICs disconnected
The backup was recent — restore points going back to June 27, with a fresh agent backup from the morning of the restore.
The Symptom
The VM booted. The Hyper-V firmware loaded. The Windows Boot Manager appeared.
Then:
A recent hardware or software change might have installed a file that is incorrect.
File: \windows\system32\winload.efi
Status: 0xc000000e
Not a disk controller error. Not a missing VHD. The boot manager found the EFI partition, loaded bootmgfw.efi, read the BCD, and then failed to locate winload.efi on the OS partition.
Why This Matters
This is not a corrupted backup. It’s not a Veeam bug. It’s a configuration detail baked into the Windows registry at the time the backup was taken — and Veeam restores bits, it doesn’t rewrite registry hives.
Understanding how that detail survives a restore, and why we couldn’t fix it from the host side, is the core of this post.
What We Tried First (And Why Most of It Failed)
The PowerShell CLI
Veeam’s PowerShell module has Start-VBREpInstantRecovery. It should have been one command:
Start-VBREpInstantRecovery-RestorePoint$rp-Server$hvHost `
-Path"E:\VMs\j-server"-VMName"j-server"-PowerUp$true-NICsEnabled$false
It failed. Repeatedly. The mount phase returned Mount failed or Dismount failed.
The logs told the story:
Error: CHvBootLayoutDetector..ctor()
Error: CHvRestoreAlgVawBase.ChooseVmGenerationAndBootDisks()
Veeam’s boot layout auto-detector couldn’t parse the backup metadata to decide Gen 1 vs Gen 2 and which disk boots first. The PowerShell cmdlet has no -Generation or -BootDisk parameter — it relies entirely on that auto-detector. When the detector crashes, the whole IR fails.
The GUI (It Worked)
The Veeam Backup & Replication Console has a wizard step where you manually choose VM generation, boot disk, and boot order. That step bypasses the broken auto-detector. The GUI IR succeeded where the CLI couldn’t — same restore point, same host, same path.
This is a PowerShell cmdlet limitation, not a vPower NFS failure.
The Disk Export (Also Failed)
Start-VBRRestoreVirtualDisks exports backup contents as standalone VHDX files. It worked briefly — Disk 1 (640 MB, EFI) completed, Disk 2 (585 GB, OS) started growing. Then it stalled at 0.5 GB.
Cause: the backup repository and the export destination both lived on the same 8TB HDD. Reading compressed backup blocks and writing decompressed VHDX blocks to the same spindle created a 1 GB/min bottleneck. A competing Veeam backup sync job made it worse.
Killing the sync job helped briefly, but the export never reliably resumed.
Fresh Agent Backup (The Rate Was Good, But…)
Backing up C: (NVMe SSD) to E: (HDD) eliminated the read/write contention on E:. The write rate was solid. But the Veeam Agent backup creates compressed .vbk/.vib files — you still need an Instant Recovery or export step after the backup, and that second step puts you back on the same spindle problem. The extra step wasn’t worth it.
The Real Problem: The BCD
Once the GUI IR produced a running VM, we could inspect the EFI partition from the host:
Mount-VHD-Path"E:\VMs\2ddcd51a-...avhdx"-ReadOnly$bcdPath = "\\?\Volume{...}\EFI\Microsoft\Boot\BCD"
bcdedit /store $bcdPath /enum
The BCD revealed the root cause:
Windows Boot Loader
--------------------
identifier {default}
device partition=Z:
osdevice partition=Z:
Z:. Windows was installed on Z: on the physical machine at the time of backup. The current host runs on C: — at some point the server was rebuilt or the drive letter was changed. But the backup captured the registry as it was, including HKLM\SYSTEM\MountedDevices mapping the OS partition to \DosDevices\Z:.
When the restored VM boots, the Windows Boot Manager reads the BCD, looks for a partition with Z: assigned, and can’t find one. The OS partition in the VM has no drive letter at all — WinRE doesn’t assign one because the registry says it belongs to Z:, and Z: doesn’t exist in the recovery environment.
Why We Couldn’t Fix the BCD from the Host
This is the part that surprised me.
The AVHDX differencing disks were mounted and visible to the host OS:
Get-Disk | Where-Object Location -like"*avhdx"# Disk 8 (EFI, 960 MB) and Disk 9 (OS, 1 TB) both presentGet-Partition-DiskNumber8# Partition 1: Recovery (449 MB)# Partition 2: System / EFI (100 MB)# Partition 3: Reserved (16 MB)# Partition 4: Recovery (415 MB)
The block layer worked. I could read the partition table, enumerate partition GUIDs, and even read the raw BCD file through the volume GUID path. But every attempt to go further failed:
| Operation | Result |
|---|---|
Set-Partition -NewDriveLetter | “Not Supported” |
mountvol S: \\?\Volume{...}\ | “The parameter is incorrect” |
Get-ChildItem on OS volume | No output (filesystem inaccessible) |
bcdboot W:\Windows /s S: /f UEFI | “failure when initializing library system volume” |
bcdedit /store ... /set {default} device partition=C: | “The parameter is incorrect” (via PowerShell; worked via cmd /c) |
The EFI partition was partially accessible — I could read the BCD and even modify it via cmd /c bcdedit. But the OS partition’s filesystem was completely invisible from the host.
Why?
vPower NFS serves the base VHDX as a streamed NFS pseudo-file. It’s not a regular VHDX sitting on an NTFS volume — it’s a virtual file exported by the VeeamNFSSvc NFS server. When Hyper-V reads blocks from it, NFS translates those reads into decompressed chunks from the backup repository.
The AVHDX differencing chain looks like this:
current.avhdx (writes, on E:)
-> checkpoint.avhdx (snapshot diff, on E:)
-> base.vhdx (READ-ONLY, served by vPower NFS)
The host OS can mount the differencing chain as a block device. The NTFS driver can read the GPT headers and partition table. But when it tries to mount the filesystem — to enumerate directories, assign a drive letter, or open winload.efi — the full I/O path crosses into the NFS-served base file, and that boundary doesn’t support all the operations NTFS needs.
Inside the VM, Hyper-V’s VMBus/SCSI stack handles the full chain transparently. The guest OS sees a normal disk and can mount, format, and boot from it. That’s why bcdboot worked perfectly in the WinPE recovery environment but not from the host PowerShell session.
This is architectural, not a bug. The base VHDX is designed for Hyper-V consumption, not host filesystem mounting.
What Did Work: Editing the BCD from the Host
We could change the BCD entry via cmd /c:
cmd /c "bcdedit /store \\?\Volume{...}\EFI\Microsoft\Boot\BCD /set {default} device partition=C:"
cmd /c "bcdedit /store \\?\Volume{...}\EFI\Microsoft\Boot\BCD /set {default} osdevice partition=C:"
This changed the boot loader reference from Z: to C:. The VM then tried to load C:\Windows\System32\winload.efi — but still failed, because the OS partition’s filesystem wasn’t properly initialised during boot through the NFS chain. Changing the drive letter in the BCD wasn’t enough.
The Fix: Boot from ISO and Rebuild
The reliable repair path was to boot from Windows Server 2019 installation media and use the recovery environment:
- Mount the ISO to the VM’s DVD drive, boot from it.
- From Repair your computer → Troubleshoot → Command Prompt:
diskpart select disk 0 list partition # EFI = partition 2, 100 MB select disk 1 list partition # OS = partition 3, ~931 GB select partition 3 assign letter=W exit dir W:\Windows # Confirmed: Windows directory present - Assign the EFI partition and rebuild:
diskpart select disk 0 select partition 2 assign letter=S exit format S: /FS:FAT32 /Q bcdboot W:\Windows /s S: /f UEFI - Remove the ISO, reboot.
The VM booted cleanly. The repair took under five minutes once the ISO was mounted and the console was accessible.
Why the GUI IR Worked When the CLI Didn’t
Two separate failure modes:
- CLI IR (
Start-VBREpInstantRecovery): TheCHvBootLayoutDetectorauto-detection crashes on this backup’s metadata. There’s no parameter to override it. The IR session fails during mount. - GUI IR (Veeam Console wizard): The wizard has a manual step for VM generation and boot disk selection. That bypasses the broken auto-detector. The IR mounts successfully, but the BCD still points to
Z:because the wizard can’t rewrite registry data inside the backup.
The first problem is a PowerShell cmdlet limitation. The second is expected behaviour — Veeam restores the bits as they were, and Z: was the drive letter at backup time.
Key Takeaways
- Veeam Instant Recovery for agent backups is fast — minutes, not hours — but the boot configuration may need manual repair if the original machine had non-standard drive letters.
- The Veeam PowerShell cmdlet doesn’t expose VM generation or boot disk selection. If the auto-detector fails (as it did here), the CLI IR fails. The GUI wizard is the fallback.
- You can’t reliably mount or modify the OS filesystem on vPower NFS-backed AVHDX differencing disks from the host. The block layer works; NTFS filesystem operations don’t. This is by design — the base VHDX is a streamed NFS pseudo-file, not a local VHDX.
- The EFI partition’s BCD is readable and editable from the host via
bcdedit /storewithcmd /c. But editing the BCD alone may not be enough if the OS filesystem can’t be initialised through the NFS chain. - Windows Recovery Environment (WinPE) from the installation ISO sees the disks natively. Inside the VM, the Hyper-V SCSI stack handles the full differencing chain transparently.
bcdbootanddiskpartwork exactly as they would on physical hardware. - Don’t do disk export to the same spindle as the backup repository. Reading and writing to the same HDD creates a ~1 GB/min bottleneck. If you must export, use a different physical disk.
- Drive letters matter in backups. If your production server has a non-standard OS drive letter (
Z:,E:, anything butC:), the restored VM will need BCD repair. Document it. Better yet, standardise onC:for the system volume. - Take a checkpoint before booting the repaired VM. Once the BCD is fixed and the VM boots cleanly, save that state. It’s your rollback point for any future sandbox experiments.
The Differencing Chain, Explained
This is worth a diagram because it explains both the speed and the limitations:
┌─────────────────────────────────┐
│ Hyper-V VM (j-server) │
│ ┌───────────────────────────┐ │
│ │ Windows (guest) │ │ ← Full disk access,
│ │ - diskpart works │ │ filesystem works
│ │ - bcdboot works │ │
│ │ - format S: works │ │
│ └───────────┬───────────────┘ │
└──────────────┼──────────────────┘
│ VMBus / SCSI
┌──────────────▼──────────────────┐
│ Host: Hyper-V Worker Process │
│ ┌───────────────────────────┐ │
│ │ current.avhdx (writes) │ │ ← Differencing disk on E:\
│ │ ↓ parent │ │
│ │ snapshot.avhdx (checkpt) │ │ ← Checkpoint diff on E:\
│ │ ↓ parent │ │
│ │ base.vhdx (READ) │ │ ← NFS-served virtual file
│ └───────────┬───────────────┘ │
└──────────────┼──────────────────┘
│ NFS (loopback/localhost)
┌──────────────▼──────────────────┐
│ Veeam vPower NFS Service │
│ ┌───────────────────────────┐ │
│ │ Compressed backup blocks │ │ ← On-demand decompression
│ │ (E:\Backup\*.vbk/*.vib) │ │ and block streaming
│ └───────────────────────────┘ │
└─────────────────────────────────┘
From the host, you can mount the AVHDX chain as a block device. You see partitions. You can even read individual sectors (the BCD file). But when NTFS tries to mount the filesystem, it hits the NFS boundary and the operations fall apart.
From the guest, Hyper-V’s native SCSI stack handles the chain end-to-end. The guest never knows the base VHDX is a virtual NFS file. It just sees a disk.
References
This was a sandbox VM, so the stakes were low. The same problem on a production disaster recovery restore would need the same five-minute ISO boot and BCD rebuild. Worth knowing about before you need it.
Leave a Reply