Creating AHV-Ready Windows ISOs with Embedded VirtIO Drivers

Overview

Deploying Windows VMs on Nutanix AHV requires VirtIO drivers that aren't included in the standard Windows installation media. This means manually loading drivers during setup or mounting driver ISOs after installation. I've built a PowerShell tool that simplifies this process by injecting the VirtIO drivers directly into your Windows ISO, complete with both a GUI for ease of use and a CLI for automation.

The Problem: Windows and VirtIO Drivers

When you deploy a Windows VM on Nutanix AHV, the Windows installer doesn't recognize the AHV SCSI virtual disks by default. This is because AHV uses VirtIO paravirtualized drivers for storage and networking, which deliver better performance than emulated hardware but require driver injection during or after installation.

The typical workarounds include:

  • Manual driver loading during setup: Mounting the VirtIO ISO and browsing to load drivers when Windows prompts for storage drivers
  • Driver injection after installation: Installing Windows to an IDE disk, then adding VirtIO drivers afterward and migrating to SCSI
  • Image-based deployment: Using a sysprepped image that already has drivers included

None of these are ideal for quick deployments or lab environments where you just want to boot from an ISO and go.

The Solution: Driver Slipstreaming

The concept is straightforward: take a Windows ISO, extract it, inject the VirtIO drivers into both the installation image (install.wim) and the boot image (boot.wim), then repackage it as a bootable ISO. The result is a Windows installation ISO that works seamlessly on AHV without any manual driver intervention.

I was first introduced to this approach through Jeroen Tielen's excellent blog post, where he created a PowerShell script to automate this process. His script has been invaluable, and I've used it for quite a while. However, I found that I didn't need some of the functionality (like silent installation configuration and Nutanix cluster uploads), and I had customers asking about a GUI option for those less comfortable with command-line tools.

So I set about modifying the script for my purposes, streamlining the functionality and adding a graphical interface on top.

Introducing the Tool: GUI and CLI in One

The result is a unified PowerShell script that supports both interactive (GUI) and command-line (CLI) modes:

  • GUI Mode: Perfect for one-off ISO creation or users who prefer a visual interface.
  • CLI Mode: Ideal for automation, scripting, and integration into larger workflows.

Both modes share the same core functionality and produce identical results.

Key Features

  • Dual mode operation: Launch with no parameters for GUI, or pass parameters for CLI automation.
  • Automatic Windows ADK installation: If the Windows Assessment and Deployment Kit isn't installed, the script downloads and installs just the Deployment Tools component.
  • Autoboot configuration: Optionally remove the "Press any key to boot from CD/DVD" prompt for fully automated installations.
  • Windows edition selection: Choose which Windows edition to include in the final ISO (useful when working with multi-edition media).
  • Automatic drive letter detection: No need to specify which drive letter to use for ISO mounting.

What's Different from the Original

For those familiar with Jeroen's original script, here's what I changed:

  1. Removed PowerShell 7 requirement: The script now works with PowerShell 5.1, which is included with Windows.
  2. Removed silent installation generation: I handle unattended installs separately with my own autounattend.xml files.
  3. Removed Nutanix cluster upload: I prefer to upload images manually or through other automation.
  4. Added GUI interface: A Windows Forms based interface for visual configuration.
  5. Combined into single script: One script handles both GUI and CLI modes based on how you invoke it.

Prerequisites

Before running the script, ensure you have:

  1. Windows operating system: This script must be run on a Windows machine. It relies on Windows-native tools like DISM (Deployment Image Servicing and Management) and the Windows ADK, which are not available on macOS or Linux, even with PowerShell Core installed.
  2. Administrator privileges: The script requires elevation for DISM operations and ISO mounting.
  3. Windows ISO: Your source Windows installation media (Server 2016/2019/2022/2025 or Windows 10/11).
  4. Nutanix VirtIO ISO: Download from the Nutanix Portal (requires login).
  5. Sufficient disk space: You'll need roughly 2-3x the size of your Windows ISO for the working directory.

The script will automatically check for the Windows ADK and, if not found, download it directly from Microsoft using Invoke-WebRequest and install the Deployment Tools component silently.

Using the GUI Mode

Launch the script without any parameters to open the graphical interface:

1.\New-WindowsISOWithVirtIODrivers.ps1

Or explicitly request GUI mode:

1.\New-WindowsISOWithVirtIODrivers.ps1 -GUI

The interface provides fields for:

  • VirtIO ISO Path: Browse to your Nutanix VirtIO driver ISO.
  • Windows ISO Path: Browse to your Windows installation ISO.
  • Working Directory: Where temporary files and the output ISO will be created.
  • Press any key to boot: Checkbox to enable/disable the boot prompt (unchecked = autoboot).
  • Windows Edition Selection: After selecting a Windows ISO, the available editions are listed for selection.

Once configured, click Start to begin the process. The script will:

  1. Mount and extract both ISOs.
  2. Present available Windows editions (if not preselected).
  3. Inject VirtIO drivers into install.wim and boot.wim.
  4. Optionally remove the boot prompt.
  5. Create the new bootable ISO.
  6. Open Explorer to the output folder.
  7. Clean up temporary files.

Using the CLI Mode

For automation, pass the required parameters directly:

1.\New-WindowsISOWithVirtIODrivers.ps1 `
2    -VirtIOIso "C:\ISOs\Nutanix-VirtIO-1.2.4.iso" `
3    -WindowsIso "C:\ISOs\Windows_Server_2022.iso"

CLI Parameters

ParameterRequiredDefaultDescription
-VirtIOIsoYes-Path to the Nutanix VirtIO driver ISO
-WindowsIsoYes-Path to the Windows installation ISO
-PressKeyToBootNo$trueSet to $false to enable autoboot
-WorkingDirNo$env:TEMPDirectory for temporary files and output

Example: Autoboot ISO

Create an ISO that boots automatically without the "Press any key" prompt:

1.\New-WindowsISOWithVirtIODrivers.ps1 `
2    -VirtIOIso "C:\ISOs\Nutanix-VirtIO-1.2.4.iso" `
3    -WindowsIso "C:\ISOs\Win2022.iso" `
4    -PressKeyToBoot $false

Example: Custom Working Directory

Specify a working directory with more space:

1.\New-WindowsISOWithVirtIODrivers.ps1 `
2    -VirtIOIso "D:\Drivers\Nutanix-VirtIO-1.2.4.iso" `
3    -WindowsIso "D:\ISOs\Windows11.iso" `
4    -WorkingDir "D:\Temp\Slipstream"

How It Works Under the Hood

For those curious about the technical details, here's what the script does:

1. Environment Preparation

The script first verifies administrator privileges, then checks for the Windows ADK Deployment Tools by looking for oscdimg.exe. If not found, it downloads the ADK installer from Microsoft using Invoke-WebRequest and silently installs just the Deployment Tools component. The oscdimg.exe utility is essential for creating bootable ISO images with dual BIOS/UEFI support.

2. ISO Extraction

Both the VirtIO and Windows ISOs are mounted using Mount-DiskImage and their contents copied to working directories. The script automatically finds an unused drive letter for mounting.

3. Windows Edition Selection

Windows installation media often contains multiple editions (Standard, Datacenter, etc.). The script uses Get-WindowsImage to enumerate available editions and prompts for selection. All other editions are removed from install.wim using Remove-WindowsImage.

4. Driver Injection

This is the core operation. The script:

  1. Mounts install.wim using Mount-WindowsImage.
  2. Injects all VirtIO drivers using Add-WindowsDriver -Recurse.
  3. Saves and dismounts the image.
  4. Repeats for boot.wim (Index 2, the Setup environment).

Injecting into boot.wim is critical because that's what runs during the installation wizard. Without those drivers, Windows Setup can't see your disks.

5. Boot Prompt Removal (Optional)

If autoboot is requested, the script replaces the standard boot files with their "noprompt" variants:

  • cdboot.eficdboot_noprompt.efi
  • efisys.binefisys_noprompt.bin

6. ISO Creation

Finally, oscdimg.exe creates a new bootable ISO with dual BIOS/UEFI support. The output filename includes the Windows edition, version, and date for easy identification.

Sample Output

When running the script, you'll see progress output like this:

 1Running in CLI mode...
 2Running with administrator privileges
 3Using drive letter: E: for temporary ISO mounting
 4OSCDIMG is available, continuing...
 5Cleaning up system and removing leftovers from previous runs...
 6Working directories created successfully
 7Mounting VirtIO driver ISO and copying files...
 8VirtIO driver ISO extracted successfully
 9Mounting Windows ISO and copying files...
10Windows ISO extracted successfully
11Removing read-only attributes from copied files...
12
13Available Windows editions in the ISO:
14----------------------------------------------------------------------
15Index 1: Windows Server 2022 Standard
16Index 2: Windows Server 2022 Standard (Desktop Experience)
17Index 3: Windows Server 2022 Datacenter
18Index 4: Windows Server 2022 Datacenter (Desktop Experience)
19
20Enter the index number of the Windows edition you want to use: 4
21Removing unused Windows editions from install.wim...
22  Removing index 3: Windows Server 2022 Datacenter
23  Removing index 2: Windows Server 2022 Standard (Desktop Experience)
24  Removing index 1: Windows Server 2022 Standard
25Selected Windows edition: Windows Server 2022 Datacenter (Desktop Experience)
26Mounting install.wim...
27Injecting VirtIO drivers into install.wim...
28Drivers successfully added to install.wim:
29...
30Dismounting and saving install.wim...
31Mounting boot.wim (Setup environment)...
32Injecting VirtIO drivers into boot.wim (Setup environment)...
33...
34Creating bootable Windows ISO...
35Running OSCDIMG to create ISO (this may take several minutes)...
36ISO created successfully: Windows Server 2022 Datacenter (Desktop Experience) en-US 10.0.20348.1 - 25 Nov 2025 - VirtIO.iso
37Script completed successfully!
38Your custom Windows ISO with VirtIO drivers is located at:
39  C:\Users\mike\AppData\Local\Temp\Slipstream\Output\Windows Server 2022 Datacenter (Desktop Experience) en-US 10.0.20348.1 - 25 Nov 2025 - VirtIO.iso

Tips and Best Practices

Keep Your ISOs Organized

I maintain a folder structure like this:

 1D:\ISOs\
 2├── Source\
 3│   ├── Windows_Server_2022.iso
 4│   ├── Windows_Server_2025.iso
 5│   └── Windows_11_23H2.iso
 6├── Drivers\
 7│   └── Nutanix-VirtIO-1.2.4.iso
 8└── Slipstreamed\
 9    ├── Win2022_VirtIO.iso
10    └── Win2025_VirtIO.iso

Update Regularly

When Nutanix releases new VirtIO drivers, regenerate your slipstreamed ISOs. New drivers often include performance improvements and bug fixes.

Test Before Production

Always test a slipstreamed ISO in a non-production VM before using it for critical deployments. Verify that:

  • Windows installs successfully.
  • All VirtIO drivers are present (check Device Manager).
  • Network and storage performance are as expected.

Consider Autoboot for Automation

If you're using the ISO with automation tools like Nutanix Calm or other orchestration platforms, the autoboot option (-PressKeyToBoot $false) eliminates the need for manual intervention during the boot process.

Download the Script

Ready to try it out? Download the script here:

Download: New-WindowsISOWithVirtIODrivers.ps1

Acknowledgments

A huge thank you to Jeroen Tielen for creating the original script that inspired this tool. His work saved me countless hours and formed the foundation for this version.

Wrapping Up

Slipstreaming VirtIO drivers into Windows ISOs transforms the AHV deployment experience. What used to require manual driver loading during installation now works seamlessly out of the box. Whether you prefer the visual approach of the GUI or the automation capabilities of the CLI, this tool should fit into your workflow.

Have questions or suggestions for improvements? Feel free to reach out at mike@mikedent.io.

Thanks for reading!