Windows Migration Considerations
Windows migrations require additional attention due to driver binding and licensing considerations.
The Driver Challenge
In your VMware environment, Windows has loaded VMware paravirtualized drivers (vmxnet3 for network, pvscsi for storage, etc.) and bound them to specific hardware identifiers. When you move the disk to VPC, the hardware changes:
- Network: VMware vmxnet3 → VirtIO network adapter
- Storage (boot): VMware PVSCSI → VirtIO SCSI adapter
- Storage (data): VMware PVSCSI → VirtIO block adapter
If Windows boots and finds different hardware IDs for its boot storage controller, it will fail to boot (INACCESSIBLE_BOOT_DEVICE blue screen).
Solution A: Sysprep Approach
Microsoft's sysprep utility "generalizes" a Windows installation, resetting it to a first-boot state. This:
- Releases driver bindings
- Resets the Windows Security Identifier (SID)
- Removes computer-specific information
- Prepares the image for redeployment
The following is the process for sysprep:
-
Install VirtIO drivers in your Windows virtual machine while still hosted in VMware:
- Download virtio-win ISO from a RHEL VSI (
/usr/share/virtio-win) - Mount ISO, run
virtio-win-gt-x64.exeandvirtio-win-guest-tools.exe - Install drivers for both OS and recovery partition
- Download virtio-win ISO from a RHEL VSI (
-
Run sysprep:
C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /shutdown -
Export and migrate using any of the migration methods, with the exception of VDDK Direct Extraction, which is only for vCenter.
-
First boot in VPC:
- Windows runs mini-setup wizard (OOBE)
- Detects new hardware, loads VirtIO drivers
- May require re-entering product key
- May require re-joining domain
Advantages
- Well-documented Microsoft process
- Works reliably for Windows deployments
Disadvantages
- Resets machine identity (problematic for domain-joined servers)
- May trigger Windows re-activation
- Application-specific issues (some apps don't handle sysprep well)
- Requires OOBE completion on first boot
Design Decision: Use sysprep for template-based deployments or when migrating development/test virtual machines where identity reset is acceptable. Avoid for production domain-joined servers with complex app dependencies.
Solution B: virt-v2v Driver Injection
The libguestfs virt-v2v tool can inject VirtIO drivers into a Windows installation without running sysprep. It:
- Mounts the Windows filesystem (without booting Windows)
- Injects VirtIO drivers into the driver store
- Modifies registry to force Windows to load these drivers
- Preserves machine identity, domain membership, and application state
Prerequisites:
- virtual machine must be cleanly shut down (not crashed, not forced off)
- Windows version must be supported (Server 2008 R2 through 2025, Windows 7 through 11)
- virtio-win driver package (available on RHEL systems:
/usr/share/virtio-win)
The following is the process for virt-v2v driver injection:
-
Install VirtIO drivers in Windows boot and recovery partitions (same as sysprep approach)
-
Cleanly shut down Windows virtual machine
-
Export/transfer disk to worker VSI using any of the migration methods.
-
Run virt-v2v:
virt-v2v -i disk windows-vm.img -o disk -os /target --block-driver virtio-scsiParameters:
-i disk: Input is a disk image file-o disk -os /target: Output to directory--block-driver virtio-scsi: Use SCSI driver for first disk (required for VPC boot volumes)
-
If writing directly to device:
ln -fs /dev/vdb /target/windows-vm-sda virt-v2v -i disk windows-vm.img -o disk -os /target --block-driver virtio-scsi
Advantages of virt-v2v:
- Preserves machine identity (no re-activation, no re-domain-join)
- No first-boot setup wizard
- Application state intact
- Works for production servers
Disadvantages:
- Requires RHEL/Ubuntu hybrid setup
- More complex than sysprep
- Requires clean shutdown (won't process crashed/forced-off virtual machines)
Design Decision: Use virt-v2v for production Windows servers where preserving identity is critical. Accept the additional tooling complexity as a trade-off for cleaner migrations.
The RHEL/Ubuntu Challenge
Critical issue: The --block-driver virtio-scsi option is required for VPC Windows virtual machines (boot disk uses VirtIO SCSI, not VirtIO block), but:
- RHEL virt-v2v does not support
--block-driver virtio-scsi - Ubuntu virt-v2v supports
--block-driver virtio-scsi - RHEL libguestfs includes virtio-win drivers at
/usr/share/virtio-win - Ubuntu libguestfs does not include virtio-win drivers
Workaround
There are two workarounds for the RHEL/Ubuntu issue.
Option 1: Build libguestfs on Ubuntu
The first option is to build libguestfs on Ubuntu by running the following command.
# On Ubuntu worker VSI
apt-get install libguestfs-tools
# Copy virtio-win from a RHEL system
# On RHEL: tar czf virtio-win.tar.gz /usr/share/virtio-win
# Transfer to Ubuntu and extract:
tar xzf virtio-win.tar.gz -C /usr/share/
# Now virt-v2v on Ubuntu has both SCSI support and drivers
virt-v2v -i disk windows.img -o disk -os /target --block-driver virtio-scsi
Option 2: Two-stage conversion
The second option is to use the following command to do a two-stage conversion.
# On RHEL worker (has drivers, no SCSI support)
virt-v2v -i disk windows.img -o disk -os /tmp
# Transfer to Ubuntu worker
scp /tmp/windows-sda ubuntu-worker:/tmp/
# On Ubuntu worker (has SCSI support)
virt-v2v -i disk /tmp/windows-sda -o disk -os /target --block-driver virtio-scsi
Windows Storage Driver Architecture in VPC
Understanding how VPC presents storage to Windows helps troubleshoot boot issues:
First Volume (Boot Disk):
- Presented as VirtIO SCSI device
- Requires virtio-scsi driver
- This is why
--block-driver virtio-scsiis mandatory
Subsequent Volumes (Data Disks):
- Presented as VirtIO block devices
- Require virtio-blk driver
- Different driver than boot disk
Both drivers must be installed in both:
- The running OS
- The recovery environment (WinRE)
Recovery Environment Driver Installation
Windows Recovery Environment (WinRE) is a separate mini-Windows used for recovery operations. If it doesn't have VirtIO drivers, you can't use it for recovery after migration.
Locating WinRE:
reagentc /info
This might report a recovery volume, but the actual WinRE image might be at:
C:\Windows\System32\Recovery\winre.wim
Installing Drivers in WinRE:
-
Mount virtio-win ISO
-
Identify WinRE location via
reagentc /info -
If on a separate volume, mount it temporarily
-
Use DISM to inject drivers:
dism /mount-wim /wimfile:C:\Windows\System32\Recovery\winre.wim /index:1 /mountdir:C:\mount dism /image:C:\mount /add-driver /driver:E:\viostor\w10\amd64 /recurse dism /image:C:\mount /add-driver /driver:E:\netkvm\w10\amd64 /recurse dism /unmount-wim /mountdir:C:\mount /commit
GPT Partition Considerations:
If your Windows disk uses GPT (not MBR):
- Use
list volumeandselect volumeinstead oflist partition - Setting volume IDs differs:
- Data volume:
set id=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 - System volume:
set id=c12a7328-f81f-11d2-ba4b-00a0c93ec93b
- Data volume:
Supported Windows Versions
Red Hat's virtio-win package provides drivers for:
Windows Server:
- 2008 R2
- 2012, 2012 R2
- 2016, 2019, 2022, 2025
Windows Client:
- 7
- 8, 8.1
- 10
- 11
Older versions (Server 2003, 2008 non-R2, Vista) are not supported.
The following table is the design decision matrix for Windows
| Scenario | Recommended Approach |
|---|---|
| Development/test virtual machines | Sysprep (simple, identity reset acceptable) |
| Production standalone servers | virt-v2v (preserves identity) |
| Domain-joined production servers | virt-v2v (avoids domain re-join) |
| Template-based deployments | Sysprep (appropriate for templates) |
| Servers with licensing tied to hardware ID | virt-v2v + careful license review |
| Very old Windows (2003, 2008 non-R2) | Not supported for migration |