@@ -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