mirror of
https://github.com/ChrisTitusTech/winutil
synced 2026-04-05 22:28:31 +00:00
inject to boot.wim for install
This commit is contained in:
@@ -80,6 +80,68 @@ function Invoke-WinUtilISOScript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Returns the full paths of every exported .inf whose online driver class
|
||||||
|
# matches one of the supplied class names.
|
||||||
|
function Get-ExportedInfPaths {
|
||||||
|
param ([string]$ExportRoot, [string[]]$Classes)
|
||||||
|
Get-WindowsDriver -Online |
|
||||||
|
Where-Object { $_.ClassName -in $Classes } |
|
||||||
|
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
|
||||||
|
Select-Object -Unique |
|
||||||
|
ForEach-Object {
|
||||||
|
Get-ChildItem -Path $ExportRoot -Filter "$_.inf" -Recurse -ErrorAction SilentlyContinue |
|
||||||
|
Select-Object -ExpandProperty FullName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Injects drivers into a DISM-mounted image. Pass either a list of .inf
|
||||||
|
# paths via -InfPaths, or a driver folder via -DriverDir (uses /Recurse).
|
||||||
|
function Add-DriversToImage {
|
||||||
|
param (
|
||||||
|
[string]$MountPath,
|
||||||
|
[string[]]$InfPaths,
|
||||||
|
[string]$DriverDir,
|
||||||
|
[string]$Label = "image",
|
||||||
|
[scriptblock]$Logger
|
||||||
|
)
|
||||||
|
if ($DriverDir) {
|
||||||
|
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse 2>&1 |
|
||||||
|
ForEach-Object { & $Logger " dism[$Label]: $_" }
|
||||||
|
} else {
|
||||||
|
foreach ($inf in $InfPaths) {
|
||||||
|
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$inf" 2>&1 |
|
||||||
|
ForEach-Object { & $Logger " dism[$Label]: $_" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mounts boot.wim index 2, injects drivers, saves, and dismounts.
|
||||||
|
# Pass either -InfPaths (individual .inf files) or -DriverDir (/Recurse).
|
||||||
|
function Invoke-BootWimInject {
|
||||||
|
param (
|
||||||
|
[string]$BootWimPath,
|
||||||
|
[string[]]$InfPaths,
|
||||||
|
[string]$DriverDir,
|
||||||
|
[scriptblock]$Logger
|
||||||
|
)
|
||||||
|
Set-ItemProperty -Path $BootWimPath -Name IsReadOnly -Value $false -ErrorAction SilentlyContinue
|
||||||
|
$mountDir = Join-Path $env:TEMP "WinUtil_BootMount_$(Get-Random)"
|
||||||
|
New-Item -Path $mountDir -ItemType Directory -Force | Out-Null
|
||||||
|
try {
|
||||||
|
& $Logger "Mounting boot.wim (index 2 — Windows Setup) for driver injection..."
|
||||||
|
Mount-WindowsImage -ImagePath $BootWimPath -Index 2 -Path $mountDir -ErrorAction Stop | Out-Null
|
||||||
|
Add-DriversToImage -MountPath $mountDir -InfPaths $InfPaths -DriverDir $DriverDir -Label "boot" -Logger $Logger
|
||||||
|
& $Logger "Saving boot.wim..."
|
||||||
|
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
||||||
|
& $Logger "boot.wim driver injection complete."
|
||||||
|
} catch {
|
||||||
|
& $Logger "Warning: boot.wim driver injection failed: $_"
|
||||||
|
try { Dismount-WindowsImage -Path $mountDir -Discard -ErrorAction SilentlyContinue | Out-Null } catch {}
|
||||||
|
} finally {
|
||||||
|
Remove-Item -Path $mountDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# 1. Remove provisioned AppX packages
|
# 1. Remove provisioned AppX packages
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
@@ -145,6 +207,9 @@ function Invoke-WinUtilISOScript {
|
|||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
# 2. Inject hardware drivers (NVMe / Trackpad / Network)
|
# 2. Inject hardware drivers (NVMe / Trackpad / Network)
|
||||||
|
# Injected into BOTH install.wim (OS) AND boot.wim index 2 (Setup).
|
||||||
|
# Without storage drivers in boot.wim, Windows Setup cannot see the
|
||||||
|
# target disk on systems with unsupported NVMe / SATA controllers.
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
& $Log "Exporting hardware drivers from running system (NVMe, HID/Trackpad, Network)..."
|
& $Log "Exporting hardware drivers from running system (NVMe, HID/Trackpad, Network)..."
|
||||||
|
|
||||||
@@ -152,41 +217,32 @@ function Invoke-WinUtilISOScript {
|
|||||||
New-Item -Path $driverExportRoot -ItemType Directory -Force | Out-Null
|
New-Item -Path $driverExportRoot -ItemType Directory -Force | Out-Null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
# Export every online driver to the temp folder.
|
|
||||||
# Export-WindowsDriver creates one sub-folder per .inf package.
|
|
||||||
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
|
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
|
||||||
|
|
||||||
# Driver classes to inject:
|
# install.wim: SCSIAdapter + HIDClass + Net
|
||||||
# SCSIAdapter - NVMe / AHCI storage controllers
|
$installInfs = Get-ExportedInfPaths -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','HIDClass','Net')
|
||||||
# HIDClass - Precision Touchpad and HID devices
|
& $Log "Injecting $(@($installInfs).Count) driver package(s) into install.wim..."
|
||||||
# Net - Ethernet and Wi-Fi adapters
|
Add-DriversToImage -MountPath $ScratchDir -InfPaths $installInfs -Label "install" -Logger $Log
|
||||||
$targetClasses = @('SCSIAdapter', 'HIDClass', 'Net')
|
& $Log "install.wim driver injection complete."
|
||||||
|
|
||||||
$targetInfBases = Get-WindowsDriver -Online |
|
# boot.wim: SCSIAdapter + Net only (HID not needed in WinPE)
|
||||||
Where-Object { $_.ClassName -in $targetClasses } |
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
|
$bootWim = Join-Path $ISOContentsDir "sources\boot.wim"
|
||||||
Select-Object -Unique
|
if (Test-Path $bootWim) {
|
||||||
|
$bootInfs = Get-ExportedInfPaths -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','Net')
|
||||||
$injected = 0
|
& $Log "Injecting $(@($bootInfs).Count) driver package(s) into boot.wim..."
|
||||||
foreach ($infBase in $targetInfBases) {
|
Invoke-BootWimInject -BootWimPath $bootWim -InfPaths $bootInfs -Logger $Log
|
||||||
$infFile = Get-ChildItem -Path $driverExportRoot -Filter "$infBase.inf" `
|
|
||||||
-Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
||||||
if ($infFile) {
|
|
||||||
& dism /English "/image:$ScratchDir" /Add-Driver "/Driver:$($infFile.FullName)"
|
|
||||||
$injected++
|
|
||||||
} else {
|
} else {
|
||||||
& $Log "Warning: exported .inf not found for '$infBase' — skipped."
|
& $Log "Warning: boot.wim not found — skipping boot.wim driver injection."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& $Log "Driver injection complete - $injected driver package(s) added."
|
|
||||||
} catch {
|
} catch {
|
||||||
& $Log "Error during driver export/injection: $_"
|
& $Log "Error during driver export/injection: $_"
|
||||||
} finally {
|
} finally {
|
||||||
Remove-Item -Path $driverExportRoot -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path $driverExportRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── 2b. Optional: extended Storage & Network drivers from community repo ──
|
# ── 2c. Optional: extended Storage & Network drivers from community repo ──
|
||||||
$extDriverChoice = [System.Windows.MessageBox]::Show(
|
$extDriverChoice = [System.Windows.MessageBox]::Show(
|
||||||
"Would you like to add extended Storage and Network drivers?`n`n" +
|
"Would you like to add extended Storage and Network drivers?`n`n" +
|
||||||
"This installs EVERY Storage and Networking device driver " +
|
"This installs EVERY Storage and Networking device driver " +
|
||||||
@@ -221,10 +277,19 @@ function Invoke-WinUtilISOScript {
|
|||||||
$extRepoDir 2>&1 | ForEach-Object { & $Log " git: $_" }
|
$extRepoDir 2>&1 | ForEach-Object { & $Log " git: $_" }
|
||||||
|
|
||||||
if (Test-Path $extRepoDir) {
|
if (Test-Path $extRepoDir) {
|
||||||
& $Log "Injecting extended drivers into image (this may take several minutes)..."
|
& $Log "Injecting extended drivers into install.wim (this may take several minutes)..."
|
||||||
& dism /English "/image:$ScratchDir" /Add-Driver "/Driver:$extRepoDir" /Recurse 2>&1 |
|
Add-DriversToImage -MountPath $ScratchDir -DriverDir $extRepoDir -Label "install" -Logger $Log
|
||||||
ForEach-Object { & $Log " dism: $_" }
|
& $Log "Extended driver injection into install.wim complete."
|
||||||
& $Log "Extended driver injection complete."
|
|
||||||
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
|
$bootWimExt = Join-Path $ISOContentsDir "sources\boot.wim"
|
||||||
|
if (Test-Path $bootWimExt) {
|
||||||
|
& $Log "Injecting extended drivers into boot.wim..."
|
||||||
|
Invoke-BootWimInject -BootWimPath $bootWimExt -DriverDir $extRepoDir -Logger $Log
|
||||||
|
} else {
|
||||||
|
& $Log "Warning: boot.wim not found — skipping extended driver injection into boot.wim."
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
& $Log "Warning: repository clone directory not found — skipping extended drivers."
|
& $Log "Warning: repository clone directory not found — skipping extended drivers."
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user