mirror of
https://github.com/ChrisTitusTech/winutil
synced 2026-04-06 14:48:31 +00:00
fix single driver install issues
This commit is contained in:
@@ -80,47 +80,48 @@ function Invoke-WinUtilISOScript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Returns the full paths of every exported .inf whose online driver class
|
# Copies driver package folders (one per exported .inf) whose online class
|
||||||
# matches one of the supplied class names.
|
# matches any of the supplied class names into a new temp staging directory.
|
||||||
function Get-ExportedInfPaths {
|
# Returns the staging directory path — caller must delete it when done.
|
||||||
|
# Using a staging dir lets DISM inject all drivers in a single /Recurse
|
||||||
|
# call instead of one DISM process launch per .inf file.
|
||||||
|
function New-DriverStagingDir {
|
||||||
param ([string]$ExportRoot, [string[]]$Classes)
|
param ([string]$ExportRoot, [string[]]$Classes)
|
||||||
|
$stagingDir = Join-Path $env:TEMP "WinUtil_DriverStage_$(Get-Random)"
|
||||||
|
New-Item -Path $stagingDir -ItemType Directory -Force | Out-Null
|
||||||
Get-WindowsDriver -Online |
|
Get-WindowsDriver -Online |
|
||||||
Where-Object { $_.ClassName -in $Classes } |
|
Where-Object { $_.ClassName -in $Classes } |
|
||||||
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
|
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
|
||||||
Select-Object -Unique |
|
Select-Object -Unique |
|
||||||
ForEach-Object {
|
ForEach-Object {
|
||||||
Get-ChildItem -Path $ExportRoot -Filter "$_.inf" -Recurse -ErrorAction SilentlyContinue |
|
Get-ChildItem -Path $ExportRoot -Filter "$_.inf" -Recurse -ErrorAction SilentlyContinue |
|
||||||
Select-Object -ExpandProperty FullName
|
Select-Object -ExpandProperty DirectoryName -Unique |
|
||||||
|
ForEach-Object {
|
||||||
|
# Each exported driver lives in its own sub-folder;
|
||||||
|
# copy that folder (with its binary files) into staging.
|
||||||
|
$dest = Join-Path $stagingDir (Split-Path $_ -Leaf)
|
||||||
|
Copy-Item -Path $_ -Destination $dest -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $stagingDir
|
||||||
|
}
|
||||||
|
|
||||||
# Injects drivers into a DISM-mounted image. Pass either a list of .inf
|
# Injects all drivers from $DriverDir into a DISM-mounted image in one call.
|
||||||
# paths via -InfPaths, or a driver folder via -DriverDir (uses /Recurse).
|
|
||||||
function Add-DriversToImage {
|
function Add-DriversToImage {
|
||||||
param (
|
param (
|
||||||
[string]$MountPath,
|
[string]$MountPath,
|
||||||
[string[]]$InfPaths,
|
|
||||||
[string]$DriverDir,
|
[string]$DriverDir,
|
||||||
[string]$Label = "image",
|
[string]$Label = "image",
|
||||||
[scriptblock]$Logger
|
[scriptblock]$Logger
|
||||||
)
|
)
|
||||||
if ($DriverDir) {
|
|
||||||
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse 2>&1 |
|
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse 2>&1 |
|
||||||
ForEach-Object { & $Logger " dism[$Label]: $_" }
|
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.
|
# Mounts boot.wim index 2, injects all drivers from $DriverDir, saves, dismounts.
|
||||||
# Pass either -InfPaths (individual .inf files) or -DriverDir (/Recurse).
|
|
||||||
function Invoke-BootWimInject {
|
function Invoke-BootWimInject {
|
||||||
param (
|
param (
|
||||||
[string]$BootWimPath,
|
[string]$BootWimPath,
|
||||||
[string[]]$InfPaths,
|
|
||||||
[string]$DriverDir,
|
[string]$DriverDir,
|
||||||
[scriptblock]$Logger
|
[scriptblock]$Logger
|
||||||
)
|
)
|
||||||
@@ -130,7 +131,7 @@ function Invoke-WinUtilISOScript {
|
|||||||
try {
|
try {
|
||||||
& $Logger "Mounting boot.wim (index 2 — Windows Setup) for driver injection..."
|
& $Logger "Mounting boot.wim (index 2 — Windows Setup) for driver injection..."
|
||||||
Mount-WindowsImage -ImagePath $BootWimPath -Index 2 -Path $mountDir -ErrorAction Stop | Out-Null
|
Mount-WindowsImage -ImagePath $BootWimPath -Index 2 -Path $mountDir -ErrorAction Stop | Out-Null
|
||||||
Add-DriversToImage -MountPath $mountDir -InfPaths $InfPaths -DriverDir $DriverDir -Label "boot" -Logger $Logger
|
Add-DriversToImage -MountPath $mountDir -DriverDir $DriverDir -Label "boot" -Logger $Logger
|
||||||
& $Logger "Saving boot.wim..."
|
& $Logger "Saving boot.wim..."
|
||||||
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
||||||
& $Logger "boot.wim driver injection complete."
|
& $Logger "boot.wim driver injection complete."
|
||||||
@@ -219,19 +220,22 @@ function Invoke-WinUtilISOScript {
|
|||||||
try {
|
try {
|
||||||
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
|
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
|
||||||
|
|
||||||
|
# Stage matching driver folders then do a single DISM /Recurse call.
|
||||||
# install.wim: SCSIAdapter + HIDClass + Net
|
# install.wim: SCSIAdapter + HIDClass + Net
|
||||||
$installInfs = Get-ExportedInfPaths -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','HIDClass','Net')
|
$installStage = New-DriverStagingDir -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','HIDClass','Net')
|
||||||
& $Log "Injecting $(@($installInfs).Count) driver package(s) into install.wim..."
|
& $Log "Injecting staged drivers into install.wim (single DISM call)..."
|
||||||
Add-DriversToImage -MountPath $ScratchDir -InfPaths $installInfs -Label "install" -Logger $Log
|
Add-DriversToImage -MountPath $ScratchDir -DriverDir $installStage -Label "install" -Logger $Log
|
||||||
|
Remove-Item -Path $installStage -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
& $Log "install.wim driver injection complete."
|
& $Log "install.wim driver injection complete."
|
||||||
|
|
||||||
# boot.wim: SCSIAdapter + Net only (HID not needed in WinPE)
|
# boot.wim: SCSIAdapter + Net only (HID not needed in WinPE)
|
||||||
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
$bootWim = Join-Path $ISOContentsDir "sources\boot.wim"
|
$bootWim = Join-Path $ISOContentsDir "sources\boot.wim"
|
||||||
if (Test-Path $bootWim) {
|
if (Test-Path $bootWim) {
|
||||||
$bootInfs = Get-ExportedInfPaths -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','Net')
|
$bootStage = New-DriverStagingDir -ExportRoot $driverExportRoot -Classes @('SCSIAdapter','Net')
|
||||||
& $Log "Injecting $(@($bootInfs).Count) driver package(s) into boot.wim..."
|
& $Log "Injecting staged drivers into boot.wim (single DISM call)..."
|
||||||
Invoke-BootWimInject -BootWimPath $bootWim -InfPaths $bootInfs -Logger $Log
|
Invoke-BootWimInject -BootWimPath $bootWim -DriverDir $bootStage -Logger $Log
|
||||||
|
Remove-Item -Path $bootStage -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
} else {
|
} else {
|
||||||
& $Log "Warning: boot.wim not found — skipping boot.wim driver injection."
|
& $Log "Warning: boot.wim not found — skipping boot.wim driver injection."
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user