Skip to content

Instantly share code, notes, and snippets.

@rdbahm
Last active April 1, 2025 22:12
Show Gist options
  • Save rdbahm/851ef4cfe77ba1a132a693a003cbb84d to your computer and use it in GitHub Desktop.
Save rdbahm/851ef4cfe77ba1a132a693a003cbb84d to your computer and use it in GitHub Desktop.
Integrate Nutanix VirtIO drivers into a Windows ISO
#requires -RunAsAdministrator
<#
.SYNOPSIS
Given a Windows install disk and a Nutanix VirtIO disc, produce install media which includes Nutanix drivers.
.PARAMETER WindowsPath
The path to a Windows install DVD (or a mounted ISO), such as D:\
.PARAMETER NutanixDriverPath
The path to the appropriate Nutanix drivers from the VirtIO ISO. For example, F:\Windows Server 2019
.NOTES
You must have the Windows ADK installed - specifically, the "Deployment Tools."
This takes a good long while to run, and your antivirus WILL slow things down (though shouldn't break anything). You could consider setting $ScratchPath to a location excluded from AV scans.
The search indexer also does a number on performance. Disabling it could help performance if you're doing a lot of ISOs.
The script is based on https://polarclouds.co.uk/injecting-drivers-windows-server-2025-installer/
#>
Param(
[Parameter(Mandatory)]
[String]
$WindowsPath,
[Parameter(Mandatory)]
[String]
$NutanixDriverPath,
[Parameter(Mandatory)]
[String]
$OutputPath,
[String]
$OscdimgPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg",
[String]
$ScratchPath = $env:TEMP
)
$WinISOPath = Join-Path $ScratchPath "Windows-ISO"
$WimMount = Join-Path $ScratchPath "Wim"
# Double-check that we're set to the right driver directory.
if(!(Test-Path (Join-Path $NutanixDriverPath "x64"))) {
# There's no "x64" directory, so we're in the wrong spot.
Throw 'Incorrect Nutanix directory specified. Make sure you provided a path which contains the directory "x64".'
}
# Double-check that the ISO write directory exists.
if(!(Test-Path (Split-Path $OutputPath -Parent))) {
Throw 'The output directory does not exist.'
}
# Verify that OSCDIMG exists.
if(!(Test-Path (Join-Path $OscdimgPath "oscdimg.exe"))) {
Throw "Check `$oscdimgpath. Oscdimg.exe is not present at $oscdimgpath"
}
$MountedWIMs = Get-WindowsImage -Mounted
if($null -notlike $MountedWIMs) {
Write-Warning "A WIM is already mounted. Unmounting it."
$MountedWIMs | Dismount-WindowsImage -Discard
}
# If the WinISO path already exists, delete it.
if(Test-Path $WinISOPath) {
$null = Remove-Item $WinISOPath -Force -Recurse
}
$null = New-Item -Path $WinISOPath -ItemType Directory
$null = Copy-Item -Path $WindowsPath\* -Destination $WinISOPath -Recurse -Force
# Unset all read-only properties.
Foreach($Item in (Get-ChildItem $WinISOPath -Recurse)) {
if($Item.IsReadOnly -eq $true) {
$Item.IsReadOnly = $false
}
}
# Repeat for WimMount.
if(Test-Path $WimMount) {
$null = Remove-Item $WimMount -Force -Recurse
}
$null = New-Item -Path $WimMount -ItemType Directory
ForEach ($Image in (Get-WindowsImage -ImagePath "$WinISOPath\sources\boot.wim")){
Write-Host "Updating boot.wim: $($Image.ImageName)"
$null = Mount-WindowsImage -ImagePath "$WinISOPath\sources\boot.wim" -Path "$WimMount" -Index $Image.ImageIndex
$null = Add-WindowsDriver -Path "$WimMount" -Driver "$NutanixDriverPath" -Recurse
$null = Dismount-WindowsImage -Path "$WimMount" -Save
}
ForEach ($Image in (Get-WindowsImage -ImagePath "$WinISOPath\sources\install.wim")){
Write-Host "Updating install.wim: $($Image.ImageName)"
$null = Mount-WindowsImage -ImagePath "$WinISOPath\sources\install.wim" -Path "$WimMount" -Index $Image.ImageIndex
$null = Add-WindowsDriver -Path "$WimMount" -Driver "$NutanixDriverPath" -Recurse
$null = Dismount-WindowsImage -Path "$WimMount" -Save
}
Start-Process -NoNewWindow -FilePath "$OscdimgPath\oscdimg.exe" -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$WinISOPath\boot\etfsboot.com#pEF,e,b$WinISOPath\efi\microsoft\boot\efisys.bin $WinISOPath $OutputPath"
Write-Host "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment