Skip to content

Commit 18594f6

Browse files
inject to boot.wim for install
1 parent 50c4398 commit 18594f6

File tree

1 file changed

+92
-27
lines changed

1 file changed

+92
-27
lines changed

functions/private/Invoke-WinUtilISOScript.ps1

Lines changed: 92 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,68 @@ function Invoke-WinUtilISOScript {
8080
}
8181
}
8282

83+
# Returns the full paths of every exported .inf whose online driver class
84+
# matches one of the supplied class names.
85+
function Get-ExportedInfPaths {
86+
param ([string]$ExportRoot, [string[]]$Classes)
87+
Get-WindowsDriver -Online |
88+
Where-Object { $_.ClassName -in $Classes } |
89+
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
90+
Select-Object -Unique |
91+
ForEach-Object {
92+
Get-ChildItem -Path $ExportRoot -Filter "$_.inf" -Recurse -ErrorAction SilentlyContinue |
93+
Select-Object -ExpandProperty FullName
94+
}
95+
}
96+
97+
# Injects drivers into a DISM-mounted image. Pass either a list of .inf
98+
# paths via -InfPaths, or a driver folder via -DriverDir (uses /Recurse).
99+
function Add-DriversToImage {
100+
param (
101+
[string]$MountPath,
102+
[string[]]$InfPaths,
103+
[string]$DriverDir,
104+
[string]$Label = "image",
105+
[scriptblock]$Logger
106+
)
107+
if ($DriverDir) {
108+
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse 2>&1 |
109+
ForEach-Object { & $Logger " dism[$Label]: $_" }
110+
} else {
111+
foreach ($inf in $InfPaths) {
112+
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$inf" 2>&1 |
113+
ForEach-Object { & $Logger " dism[$Label]: $_" }
114+
}
115+
}
116+
}
117+
118+
# Mounts boot.wim index 2, injects drivers, saves, and dismounts.
119+
# Pass either -InfPaths (individual .inf files) or -DriverDir (/Recurse).
120+
function Invoke-BootWimInject {
121+
param (
122+
[string]$BootWimPath,
123+
[string[]]$InfPaths,
124+
[string]$DriverDir,
125+
[scriptblock]$Logger
126+
)
127+
Set-ItemProperty -Path $BootWimPath -Name IsReadOnly -Value $false -ErrorAction SilentlyContinue
128+
$mountDir = Join-Path $env:TEMP "WinUtil_BootMount_$(Get-Random)"
129+
New-Item -Path $mountDir -ItemType Directory -Force | Out-Null
130+
try {
131+
& $Logger "Mounting boot.wim (index 2 — Windows Setup) for driver injection..."
132+
Mount-WindowsImage -ImagePath $BootWimPath -Index 2 -Path $mountDir -ErrorAction Stop | Out-Null
133+
Add-DriversToImage -MountPath $mountDir -InfPaths $InfPaths -DriverDir $DriverDir -Label "boot" -Logger $Logger
134+
& $Logger "Saving boot.wim..."
135+
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
136+
& $Logger "boot.wim driver injection complete."
137+
} catch {
138+
& $Logger "Warning: boot.wim driver injection failed: $_"
139+
try { Dismount-WindowsImage -Path $mountDir -Discard -ErrorAction SilentlyContinue | Out-Null } catch {}
140+
} finally {
141+
Remove-Item -Path $mountDir -Recurse -Force -ErrorAction SilentlyContinue
142+
}
143+
}
144+
83145
# ═════════════════════════════════════════════════════════════════════════
84146
# 1. Remove provisioned AppX packages
85147
# ═════════════════════════════════════════════════════════════════════════
@@ -145,48 +207,42 @@ function Invoke-WinUtilISOScript {
145207

146208
# ═════════════════════════════════════════════════════════════════════════
147209
# 2. Inject hardware drivers (NVMe / Trackpad / Network)
210+
# Injected into BOTH install.wim (OS) AND boot.wim index 2 (Setup).
211+
# Without storage drivers in boot.wim, Windows Setup cannot see the
212+
# target disk on systems with unsupported NVMe / SATA controllers.
148213
# ═════════════════════════════════════════════════════════════════════════
149214
& $Log "Exporting hardware drivers from running system (NVMe, HID/Trackpad, Network)..."
150215

151216
$driverExportRoot = Join-Path $env:TEMP "WinUtil_DriverExport_$(Get-Random)"
152217
New-Item -Path $driverExportRoot -ItemType Directory -Force | Out-Null
153218

154219
try {
155-
# Export every online driver to the temp folder.
156-
# Export-WindowsDriver creates one sub-folder per .inf package.
157220
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
158221

159-
# Driver classes to inject:
160-
# SCSIAdapter - NVMe / AHCI storage controllers
161-
# HIDClass - Precision Touchpad and HID devices
162-
# Net - Ethernet and Wi-Fi adapters
163-
$targetClasses = @('SCSIAdapter', 'HIDClass', 'Net')
222+
# install.wim: SCSIAdapter + HIDClass + Net
223+
$installInfs = Get-ExportedInfPaths -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','HIDClass','Net')
224+
& $Log "Injecting $(@($installInfs).Count) driver package(s) into install.wim..."
225+
Add-DriversToImage -MountPath $ScratchDir -InfPaths $installInfs -Label "install" -Logger $Log
226+
& $Log "install.wim driver injection complete."
164227

165-
$targetInfBases = Get-WindowsDriver -Online |
166-
Where-Object { $_.ClassName -in $targetClasses } |
167-
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
168-
Select-Object -Unique
169-
170-
$injected = 0
171-
foreach ($infBase in $targetInfBases) {
172-
$infFile = Get-ChildItem -Path $driverExportRoot -Filter "$infBase.inf" `
173-
-Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
174-
if ($infFile) {
175-
& dism /English "/image:$ScratchDir" /Add-Driver "/Driver:$($infFile.FullName)"
176-
$injected++
228+
# boot.wim: SCSIAdapter + Net only (HID not needed in WinPE)
229+
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
230+
$bootWim = Join-Path $ISOContentsDir "sources\boot.wim"
231+
if (Test-Path $bootWim) {
232+
$bootInfs = Get-ExportedInfPaths -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','Net')
233+
& $Log "Injecting $(@($bootInfs).Count) driver package(s) into boot.wim..."
234+
Invoke-BootWimInject -BootWimPath $bootWim -InfPaths $bootInfs -Logger $Log
177235
} else {
178-
& $Log "Warning: exported .inf not found for '$infBase' — skipped."
236+
& $Log "Warning: boot.wim not found — skipping boot.wim driver injection."
179237
}
180238
}
181-
182-
& $Log "Driver injection complete - $injected driver package(s) added."
183239
} catch {
184240
& $Log "Error during driver export/injection: $_"
185241
} finally {
186242
Remove-Item -Path $driverExportRoot -Recurse -Force -ErrorAction SilentlyContinue
187243
}
188244

189-
# ── 2b. Optional: extended Storage & Network drivers from community repo ──
245+
# ── 2c. Optional: extended Storage & Network drivers from community repo ──
190246
$extDriverChoice = [System.Windows.MessageBox]::Show(
191247
"Would you like to add extended Storage and Network drivers?`n`n" +
192248
"This installs EVERY Storage and Networking device driver " +
@@ -221,10 +277,19 @@ function Invoke-WinUtilISOScript {
221277
$extRepoDir 2>&1 | ForEach-Object { & $Log " git: $_" }
222278

223279
if (Test-Path $extRepoDir) {
224-
& $Log "Injecting extended drivers into image (this may take several minutes)..."
225-
& dism /English "/image:$ScratchDir" /Add-Driver "/Driver:$extRepoDir" /Recurse 2>&1 |
226-
ForEach-Object { & $Log " dism: $_" }
227-
& $Log "Extended driver injection complete."
280+
& $Log "Injecting extended drivers into install.wim (this may take several minutes)..."
281+
Add-DriversToImage -MountPath $ScratchDir -DriverDir $extRepoDir -Label "install" -Logger $Log
282+
& $Log "Extended driver injection into install.wim complete."
283+
284+
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
285+
$bootWimExt = Join-Path $ISOContentsDir "sources\boot.wim"
286+
if (Test-Path $bootWimExt) {
287+
& $Log "Injecting extended drivers into boot.wim..."
288+
Invoke-BootWimInject -BootWimPath $bootWimExt -DriverDir $extRepoDir -Logger $Log
289+
} else {
290+
& $Log "Warning: boot.wim not found — skipping extended driver injection into boot.wim."
291+
}
292+
}
228293
} else {
229294
& $Log "Warning: repository clone directory not found — skipping extended drivers."
230295
}

0 commit comments

Comments
 (0)