Skip to content

Commit d001244

Browse files
fix single driver install issues
1 parent 18594f6 commit d001244

File tree

1 file changed

+30
-26
lines changed

1 file changed

+30
-26
lines changed

functions/private/Invoke-WinUtilISOScript.ps1

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -80,47 +80,48 @@ 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 {
83+
# Copies driver package folders (one per exported .inf) whose online class
84+
# matches any of the supplied class names into a new temp staging directory.
85+
# Returns the staging directory path — caller must delete it when done.
86+
# Using a staging dir lets DISM inject all drivers in a single /Recurse
87+
# call instead of one DISM process launch per .inf file.
88+
function New-DriverStagingDir {
8689
param ([string]$ExportRoot, [string[]]$Classes)
90+
$stagingDir = Join-Path $env:TEMP "WinUtil_DriverStage_$(Get-Random)"
91+
New-Item -Path $stagingDir -ItemType Directory -Force | Out-Null
8792
Get-WindowsDriver -Online |
8893
Where-Object { $_.ClassName -in $Classes } |
8994
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
9095
Select-Object -Unique |
9196
ForEach-Object {
9297
Get-ChildItem -Path $ExportRoot -Filter "$_.inf" -Recurse -ErrorAction SilentlyContinue |
93-
Select-Object -ExpandProperty FullName
98+
Select-Object -ExpandProperty DirectoryName -Unique |
99+
ForEach-Object {
100+
# Each exported driver lives in its own sub-folder;
101+
# copy that folder (with its binary files) into staging.
102+
$dest = Join-Path $stagingDir (Split-Path $_ -Leaf)
103+
Copy-Item -Path $_ -Destination $dest -Recurse -Force -ErrorAction SilentlyContinue
104+
}
94105
}
106+
return $stagingDir
95107
}
96108

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).
109+
# Injects all drivers from $DriverDir into a DISM-mounted image in one call.
99110
function Add-DriversToImage {
100111
param (
101112
[string]$MountPath,
102-
[string[]]$InfPaths,
103113
[string]$DriverDir,
104114
[string]$Label = "image",
105115
[scriptblock]$Logger
106116
)
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-
}
117+
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse 2>&1 |
118+
ForEach-Object { & $Logger " dism[$Label]: $_" }
116119
}
117120

118-
# Mounts boot.wim index 2, injects drivers, saves, and dismounts.
119-
# Pass either -InfPaths (individual .inf files) or -DriverDir (/Recurse).
121+
# Mounts boot.wim index 2, injects all drivers from $DriverDir, saves, dismounts.
120122
function Invoke-BootWimInject {
121123
param (
122124
[string]$BootWimPath,
123-
[string[]]$InfPaths,
124125
[string]$DriverDir,
125126
[scriptblock]$Logger
126127
)
@@ -130,7 +131,7 @@ function Invoke-WinUtilISOScript {
130131
try {
131132
& $Logger "Mounting boot.wim (index 2 — Windows Setup) for driver injection..."
132133
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+
Add-DriversToImage -MountPath $mountDir -DriverDir $DriverDir -Label "boot" -Logger $Logger
134135
& $Logger "Saving boot.wim..."
135136
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
136137
& $Logger "boot.wim driver injection complete."
@@ -219,19 +220,22 @@ function Invoke-WinUtilISOScript {
219220
try {
220221
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
221222

223+
# Stage matching driver folders then do a single DISM /Recurse call.
222224
# 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
225+
$installStage = New-DriverStagingDir -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','HIDClass','Net')
226+
& $Log "Injecting staged drivers into install.wim (single DISM call)..."
227+
Add-DriversToImage -MountPath $ScratchDir -DriverDir $installStage -Label "install" -Logger $Log
228+
Remove-Item -Path $installStage -Recurse -Force -ErrorAction SilentlyContinue
226229
& $Log "install.wim driver injection complete."
227230

228231
# boot.wim: SCSIAdapter + Net only (HID not needed in WinPE)
229232
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
230233
$bootWim = Join-Path $ISOContentsDir "sources\boot.wim"
231234
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
235+
$bootStage = New-DriverStagingDir -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','Net')
236+
& $Log "Injecting staged drivers into boot.wim (single DISM call)..."
237+
Invoke-BootWimInject -BootWimPath $bootWim -DriverDir $bootStage -Logger $Log
238+
Remove-Item -Path $bootStage -Recurse -Force -ErrorAction SilentlyContinue
235239
} else {
236240
& $Log "Warning: boot.wim not found — skipping boot.wim driver injection."
237241
}

0 commit comments

Comments
 (0)