mirror of
https://github.com/ChrisTitusTech/winutil.git
synced 2026-10-08 11:39:10 +11:00
fix: inject Setup storage into boot.wim (#5102)
$WinpeDriver$ matched INF names, so RST companions reached Setup. Add SCSIAdapter and HDC packages to boot.wim index 2 with DISM.
This commit is contained in:
@@ -183,7 +183,7 @@ When the user corrects an agent approach, add or tighten one concrete rule here
|
|||||||
- Have each Pester file load the assemblies and dot-source the functions it needs; several passed only because an earlier file in alphabetical order happened to load them.
|
- Have each Pester file load the assemblies and dot-source the functions it needs; several passed only because an earlier file in alphabetical order happened to load them.
|
||||||
- Log install/uninstall package names and package-manager IDs before queuing background runspace work; do not rely on runspace host output for the package identity.
|
- Log install/uninstall package names and package-manager IDs before queuing background runspace work; do not rely on runspace host output for the package identity.
|
||||||
- For Win11 Creator, start each new ISO modification in a fresh `WinUtil_Win11ISO_*` temp directory; existing-work detection is only for resuming/exporting already modified media.
|
- For Win11 Creator, start each new ISO modification in a fresh `WinUtil_Win11ISO_*` temp directory; existing-work detection is only for resuming/exporting already modified media.
|
||||||
- For Win11 Creator driver injection, keep offline WIM servicing to one mount and one commit: add each root package folder with its own `/Add-Driver /Recurse` so a single bad driver cannot fail the rest, and skip any folder whose ancestor is already in the set, since that ancestor's `/Recurse` covers it. Warn per failure and commit only when at least one package was added; when none were, warn and discard rather than throwing, so the run still produces an ISO. The discard in the cleanup block carries both orphaned mounts and that intentional zero-added case; keep it. Do not export editions or run unrelated WIM cleanup, and reject damaged metadata before ISO export. Use `-LiteralPath` for driver export paths, since `%TEMP%` can contain wildcard characters.
|
- For Win11 Creator driver injection, inject storage controllers (`SCSIAdapter` / `HDC`) into `boot.wim` index 2 with DISM, not `$WinpeDriver$`. Keep `install.wim` on its own per-package `/Add-Driver` retry loop. For each image, add each root package folder with its own `/Add-Driver /Recurse` so a single bad driver cannot fail the rest, and skip any folder whose ancestor is already in the set, since that ancestor's `/Recurse` covers it. Warn per failure and commit only when at least one package was added; when none were, warn and discard rather than throwing, so the run still produces an ISO. The discard in the cleanup block carries both orphaned mounts and that intentional zero-added case; keep it. Do not export editions or run unrelated WIM cleanup, and reject damaged metadata before ISO export. Use `-LiteralPath` for driver export paths, since `%TEMP%` can contain wildcard characters.
|
||||||
- For Script Analyzer cleanup, fix actionable source warnings first and do not globally suppress accepted convention warnings such as plural names, `ShouldProcess` on UI helpers, `$global:sync`, or compile-time cross-file false positives.
|
- For Script Analyzer cleanup, fix actionable source warnings first and do not globally suppress accepted convention warnings such as plural names, `ShouldProcess` on UI helpers, `$global:sync`, or compile-time cross-file false positives.
|
||||||
- For DNS DHCP reset, keep the cmdlet reset and explicitly set IPv4 and IPv6 DNS source to DHCP.
|
- For DNS DHCP reset, keep the cmdlet reset and explicitly set IPv4 and IPv6 DNS source to DHCP.
|
||||||
- Public pull-request diffs may be sent to configured external review services without a separate privacy approval; do not block the review loop on upload authorization for this public repository.
|
- Public pull-request diffs may be sent to configured external review services without a separate privacy approval; do not block the review loop on upload authorization for this public repository.
|
||||||
|
|||||||
@@ -259,9 +259,9 @@ The `Invoke-WinUtilISOScript` function applies **50+ offline registry tweaks**:
|
|||||||
|
|
||||||
### Driver Injection Feature
|
### Driver Injection Feature
|
||||||
|
|
||||||
**Optional Enhancement**: When enabled, exports all drivers from the running system and injects them into both:
|
**Optional Enhancement**: When enabled, exports all drivers from the running system and injects them into:
|
||||||
- `install.wim` (main OS image)
|
- `install.wim` (main OS image), excluding stale duplicates
|
||||||
- `boot.wim` index 2 (Windows Setup PE environment)
|
- `boot.wim` index 2 (Windows Setup PE environment), storage controllers only (`SCSIAdapter` / `HDC`)
|
||||||
|
|
||||||
**Use Case**: Enables offline installation on systems with missing drivers.
|
**Use Case**: Enables offline installation on systems with missing drivers.
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Then click **Run Windows ISO Modification and Creator** to start the customizati
|
|||||||
- **Disable Copilot and search box suggestions**
|
- **Disable Copilot and search box suggestions**
|
||||||
|
|
||||||
**Optional: Driver Injection**
|
**Optional: Driver Injection**
|
||||||
- If enabled, WinUtil exports the drivers from your current system, stages boot-storage drivers for Windows Setup, and injects eligible packages into the selected `install.wim` image. Stale duplicate packages are excluded before injection. Each remaining package is added separately, so one incompatible package does not stop the others. If a package fails, WinUtil discards the partial mount and retries the remaining packages against the original image. Check the live log for warnings: if every package fails, WinUtil keeps the original `install.wim` and still produces the ISO.
|
- If enabled, WinUtil exports the drivers from your current system, injects boot-storage drivers into `boot.wim` (Windows Setup, index 2), and injects eligible packages into the selected `install.wim` image. Stale duplicate packages are excluded before injection. Each remaining package is added separately, so one incompatible package does not stop the others. If a package fails, WinUtil discards the partial mount and retries the remaining packages against the original image. Check the live log for warnings: if every package fails, WinUtil keeps the original `install.wim` and still produces the ISO.
|
||||||
|
|
||||||
A live log shows progress as each step completes. This stage usually takes **10–30 minutes** depending on disk speed. The WIM dismount near the end is the slowest part, so do not close WinUtil while it is running.
|
A live log shows progress as each step completes. This stage usually takes **10–30 minutes** depending on disk speed. The WIM dismount near the end is the slowest part, so do not close WinUtil while it is running.
|
||||||
|
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ function Invoke-WinUtilISOModify {
|
|||||||
|
|
||||||
if ($driversInjected.Value) {
|
if ($driversInjected.Value) {
|
||||||
Step-WinUtilJob -Status "Finalizing install image..." -Percent 70
|
Step-WinUtilJob -Status "Finalizing install image..." -Percent 70
|
||||||
Write-WinUtilISOLog "Added current-system drivers to $sourceImageFileName index $SelectedWimIndex with one mount and commit."
|
Write-WinUtilISOLog "Added current-system drivers to $sourceImageFileName index $SelectedWimIndex."
|
||||||
} elseif ($InjectDrivers) {
|
} elseif ($InjectDrivers) {
|
||||||
Step-WinUtilJob -Status "Preserving install image..." -Percent 70
|
Step-WinUtilJob -Status "Preserving install image..." -Percent 70
|
||||||
Write-WinUtilISOLog "No current-system drivers were injected into $sourceImageFileName index $SelectedWimIndex; install.wim was left unchanged. Review the warning log entries for details."
|
Write-WinUtilISOLog "No current-system drivers were injected into $sourceImageFileName index $SelectedWimIndex; install.wim was left unchanged. Review the warning log entries for details."
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ function Invoke-WinUtilISOScript {
|
|||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Stages WinUtil's AppX removal, registry tweaks, and scheduled-task cleanup
|
Stages WinUtil's AppX removal, registry tweaks, and scheduled-task cleanup
|
||||||
in the answer file for first logon, writes sources\ei.cfg for the selected
|
in the answer file for first logon, writes sources\ei.cfg for the selected
|
||||||
edition, and optionally adds current-system drivers to one install.wim index.
|
edition, and optionally adds current-system drivers to boot.wim index 2 and
|
||||||
|
one install.wim index.
|
||||||
|
|
||||||
.PARAMETER ISOContentsDir
|
.PARAMETER ISOContentsDir
|
||||||
Root directory of the copied ISO contents.
|
Root directory of the copied ISO contents.
|
||||||
@@ -51,31 +52,9 @@ function Invoke-WinUtilISOScript {
|
|||||||
)
|
)
|
||||||
$DriversInjected.Value = $false
|
$DriversInjected.Value = $false
|
||||||
|
|
||||||
function Copy-WinUtilISODriverFolder {
|
|
||||||
param (
|
|
||||||
[Parameter(Mandatory)][string]$Source,
|
|
||||||
[Parameter(Mandatory)][string]$Destination
|
|
||||||
)
|
|
||||||
|
|
||||||
$folderName = Split-Path $Source -Leaf
|
|
||||||
$targetPath = Join-Path $Destination $folderName
|
|
||||||
$suffix = 1
|
|
||||||
while (Test-Path -LiteralPath $targetPath) {
|
|
||||||
$targetPath = Join-Path $Destination "${folderName}_$suffix"
|
|
||||||
$suffix++
|
|
||||||
}
|
|
||||||
|
|
||||||
Copy-Item -LiteralPath $Source -Destination $targetPath -Recurse -Force -ErrorAction Stop
|
|
||||||
return $targetPath
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test-WinUtilISOStorageDriver {
|
function Test-WinUtilISOStorageDriver {
|
||||||
param ([Parameter(Mandatory)][System.IO.FileInfo]$InfFile)
|
param ([Parameter(Mandatory)][System.IO.FileInfo]$InfFile)
|
||||||
|
|
||||||
if ($InfFile.BaseName -match '(?i)(iaahci|iastor|vmd|irst|rst)') {
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (Get-Content -LiteralPath $InfFile.FullName -Raw -ErrorAction Stop) -match '(?im)^\s*Class\s*=\s*(SCSIAdapter|HDC)\s*(?:;.*)?$'
|
return (Get-Content -LiteralPath $InfFile.FullName -Raw -ErrorAction Stop) -match '(?im)^\s*Class\s*=\s*(SCSIAdapter|HDC)\s*(?:;.*)?$'
|
||||||
} catch {
|
} catch {
|
||||||
@@ -267,6 +246,93 @@ function Invoke-WinUtilISOScript {
|
|||||||
return @(& dism.exe /English /Get-MountedImageInfo 2>$null) -match [regex]::Escape($Path)
|
return @(& dism.exe /English /Get-MountedImageInfo 2>$null) -match [regex]::Escape($Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Get-WinUtilISODriverFolderName {
|
||||||
|
param ([Parameter(Mandatory)][string]$DriverFolder)
|
||||||
|
|
||||||
|
if ($DriverFolder.StartsWith($driverExportRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
||||||
|
return $DriverFolder.Substring($driverExportRoot.Length).TrimStart('\')
|
||||||
|
}
|
||||||
|
return $DriverFolder
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-WinUtilISORootDriverFolders {
|
||||||
|
param ([Parameter(Mandatory)][AllowEmptyCollection()][string[]]$DriverFolders)
|
||||||
|
|
||||||
|
return @($DriverFolders | Where-Object {
|
||||||
|
$candidate = $_
|
||||||
|
-not ($DriverFolders | Where-Object { $candidate.StartsWith("$_\", [System.StringComparison]::OrdinalIgnoreCase) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-WinUtilISODriversToImage {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory)][string]$ImagePath,
|
||||||
|
[Parameter(Mandatory)][int]$ImageIndex,
|
||||||
|
[Parameter(Mandatory)][string]$MountDir,
|
||||||
|
[Parameter(Mandatory)][AllowEmptyCollection()][string[]]$DriverFolders,
|
||||||
|
[Parameter(Mandatory)][string]$ImageLabel,
|
||||||
|
[Parameter(Mandatory)][ref]$ImageMounted
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($DriverFolders.Count -eq 0) {
|
||||||
|
& $Logger "No driver packages to add to ${ImageLabel}."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-ItemProperty -LiteralPath $ImagePath -Name IsReadOnly -Value $false
|
||||||
|
New-Item -Path $MountDir -ItemType Directory -Force | Out-Null
|
||||||
|
|
||||||
|
$remainingDriverFolders = @($DriverFolders)
|
||||||
|
while ($remainingDriverFolders.Count -gt 0) {
|
||||||
|
& $Logger "Mounting $ImageLabel index $ImageIndex for driver injection..."
|
||||||
|
Invoke-WinUtilISODism -Arguments @('/English', '/Mount-Image', "/ImageFile:$ImagePath", "/Index:$ImageIndex", "/MountDir:$MountDir") -Operation 'mount' | Out-Null
|
||||||
|
$ImageMounted.Value = $true
|
||||||
|
|
||||||
|
$failedDriverFolder = $null
|
||||||
|
$driverName = $null
|
||||||
|
foreach ($driverFolder in $remainingDriverFolders) {
|
||||||
|
$driverName = Get-WinUtilISODriverFolderName -DriverFolder $driverFolder
|
||||||
|
try {
|
||||||
|
Invoke-WinUtilISODism -Arguments @('/English', "/Image:$MountDir", '/Add-Driver', "/Driver:$driverFolder", '/Recurse') -Operation "add-driver:$driverName" | Out-Null
|
||||||
|
} catch {
|
||||||
|
& $Logger "Warning: failed to add driver package '$driverName': $_"
|
||||||
|
$failedDriverFolder = $driverFolder
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $failedDriverFolder) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
& $Logger "Discarding the potentially partial $ImageLabel mount before continuing without '$driverName'."
|
||||||
|
try {
|
||||||
|
Invoke-WinUtilISODism -Arguments @('/English', '/Unmount-Image', "/MountDir:$MountDir", '/Discard') -Operation 'discard' | Out-Null
|
||||||
|
$ImageMounted.Value = $false
|
||||||
|
} catch {
|
||||||
|
throw "Failed to discard the potentially partial $ImageLabel mount after driver package '$driverName' failed: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
$remainingDriverFolders = @($remainingDriverFolders | Where-Object { $_ -ne $failedDriverFolder })
|
||||||
|
}
|
||||||
|
|
||||||
|
$addedCount = $remainingDriverFolders.Count
|
||||||
|
if ($addedCount -eq 0) {
|
||||||
|
if ($ImageLabel -eq 'install.wim') {
|
||||||
|
& $Logger "Warning: none of the $($DriverFolders.Count) exported driver packages could be added; continuing with an unmodified install.wim."
|
||||||
|
} else {
|
||||||
|
& $Logger "Warning: none of the $($DriverFolders.Count) driver packages could be added to ${ImageLabel}."
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
& $Logger "Added $addedCount of $($DriverFolders.Count) driver packages to ${ImageLabel}."
|
||||||
|
& $Logger "Committing the driver-only $ImageLabel change..."
|
||||||
|
Invoke-WinUtilISODism -Arguments @('/English', '/Unmount-Image', "/MountDir:$MountDir", '/Commit') -Operation 'commit' | Out-Null
|
||||||
|
$ImageMounted.Value = $false
|
||||||
|
return $addedCount
|
||||||
|
}
|
||||||
|
|
||||||
if ([IO.Path]::GetExtension($InstallImagePath) -ne '.wim') {
|
if ([IO.Path]::GetExtension($InstallImagePath) -ne '.wim') {
|
||||||
throw 'Current-system driver injection requires install.wim; install.esd cannot be serviced in place.'
|
throw 'Current-system driver injection requires install.wim; install.esd cannot be serviced in place.'
|
||||||
}
|
}
|
||||||
@@ -287,7 +353,7 @@ function Invoke-WinUtilISOScript {
|
|||||||
$imageMounted = $false
|
$imageMounted = $false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
& $Logger "Exporting current system drivers before modifying install.wim..."
|
& $Logger "Exporting current system drivers before WIM driver injection..."
|
||||||
$dismLog = Join-Path $env:TEMP "WinUtil_DismDriverExport_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
$dismLog = Join-Path $env:TEMP "WinUtil_DismDriverExport_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
|
||||||
Invoke-WinUtilISODism -Arguments @('/English', '/Online', '/Export-Driver', "/Destination:$driverExportRoot", "/LogPath:$dismLog") -Operation 'export-driver' | Out-Null
|
Invoke-WinUtilISODism -Arguments @('/English', '/Online', '/Export-Driver', "/Destination:$driverExportRoot", "/LogPath:$dismLog") -Operation 'export-driver' | Out-Null
|
||||||
|
|
||||||
@@ -296,32 +362,6 @@ function Invoke-WinUtilISOScript {
|
|||||||
throw 'DISM exported no driver INF files.'
|
throw 'DISM exported no driver INF files.'
|
||||||
}
|
}
|
||||||
$driverFolders = @($driverInfs | Group-Object { $_.Directory.FullName })
|
$driverFolders = @($driverInfs | Group-Object { $_.Directory.FullName })
|
||||||
$winpeDriverDir = Join-Path $ContentRoot '$WinpeDriver$'
|
|
||||||
$storageCount = 0
|
|
||||||
$copyFailures = 0
|
|
||||||
|
|
||||||
foreach ($driverFolderGroup in $driverFolders) {
|
|
||||||
$driverFolder = [string]$driverFolderGroup.Name
|
|
||||||
$storageInfs = @($driverFolderGroup.Group | Where-Object { Test-WinUtilISOStorageDriver -InfFile $_ })
|
|
||||||
if ($storageInfs.Count -eq 0) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
New-Item -Path $winpeDriverDir -ItemType Directory -Force | Out-Null
|
|
||||||
$winpeTarget = Copy-WinUtilISODriverFolder -Source $driverFolder -Destination $winpeDriverDir
|
|
||||||
$storageCount++
|
|
||||||
& $Logger "Staged boot-storage package '$driverFolder' for WinPE as '$winpeTarget'."
|
|
||||||
} catch {
|
|
||||||
$copyFailures++
|
|
||||||
& $Logger "Warning: failed to stage boot-storage package '$driverFolder': $_"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($copyFailures -gt 0) {
|
|
||||||
throw "Failed to stage $copyFailures boot-storage driver package folders."
|
|
||||||
}
|
|
||||||
|
|
||||||
$stagedDriverFolders = @(Select-WinUtilISOStagedDriverPackages -DriverFolderGroups $driverFolders -Logger $Logger)
|
$stagedDriverFolders = @(Select-WinUtilISOStagedDriverPackages -DriverFolderGroups $driverFolders -Logger $Logger)
|
||||||
$metadataBefore = Get-WinUtilISOWimMetadata -ImagePath $InstallImagePath -Index $InstallImageIndex
|
$metadataBefore = Get-WinUtilISOWimMetadata -ImagePath $InstallImagePath -Index $InstallImageIndex
|
||||||
Assert-WinUtilISOWimMetadata -Before $metadataBefore
|
Assert-WinUtilISOWimMetadata -Before $metadataBefore
|
||||||
@@ -352,67 +392,33 @@ function Invoke-WinUtilISOScript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& $Logger "Exported $($stagedDriverFolders.Count) of $($driverFolders.Count) driver packages ($storageCount staged for WinPE, $($excludedDriverFolderGroups.Count) excluded)."
|
& $Logger "Exported $($stagedDriverFolders.Count) of $($driverFolders.Count) driver packages ($($excludedDriverFolderGroups.Count) excluded)."
|
||||||
|
|
||||||
Set-ItemProperty -LiteralPath $InstallImagePath -Name IsReadOnly -Value $false
|
# Storage for Setup comes from the same surviving set as install.wim, so stale
|
||||||
New-Item -Path $mountDir -ItemType Directory -Force | Out-Null
|
# duplicates never reach boot.wim.
|
||||||
|
$storageFolders = @(
|
||||||
|
$driverFolders |
|
||||||
|
Where-Object { $_.Name -in $stagedDriverFolders } |
|
||||||
|
Where-Object { @($_.Group | Where-Object { Test-WinUtilISOStorageDriver -InfFile $_ }).Count -gt 0 } |
|
||||||
|
ForEach-Object { [string]$_.Name }
|
||||||
|
)
|
||||||
|
$storageRootFolders = @(Get-WinUtilISORootDriverFolders -DriverFolders $storageFolders)
|
||||||
|
$rootPackageFolders = @(Get-WinUtilISORootDriverFolders -DriverFolders $stagedDriverFolders)
|
||||||
|
$imageMountedRef = [ref]$imageMounted
|
||||||
|
|
||||||
# Add each package separately so one bad driver cannot fail the rest. Because
|
$bootWim = Join-Path $ContentRoot 'sources\boot.wim'
|
||||||
# /Recurse covers descendants, only the highest surviving folder in each tree
|
if ($storageRootFolders.Count -gt 0) {
|
||||||
# needs its own DISM call.
|
if (Test-Path -LiteralPath $bootWim) {
|
||||||
$rootPackageFolders = @($stagedDriverFolders | Where-Object {
|
& $Logger "Adding $($storageRootFolders.Count) root storage driver packages to boot.wim."
|
||||||
$candidate = $_
|
$null = Add-WinUtilISODriversToImage -ImagePath $bootWim -ImageIndex 2 -MountDir $mountDir -DriverFolders $storageRootFolders -ImageLabel 'boot.wim' -ImageMounted $imageMountedRef
|
||||||
-not ($stagedDriverFolders | Where-Object { $candidate.StartsWith("$_\", [System.StringComparison]::OrdinalIgnoreCase) })
|
} else {
|
||||||
})
|
& $Logger 'Warning: boot.wim was not found; Windows Setup will not have injected storage drivers.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
& $Logger "Adding $($rootPackageFolders.Count) root driver packages to install.wim."
|
& $Logger "Adding $($rootPackageFolders.Count) root driver packages to install.wim."
|
||||||
$remainingDriverFolders = @($rootPackageFolders)
|
$addedCount = Add-WinUtilISODriversToImage -ImagePath $InstallImagePath -ImageIndex $InstallImageIndex -MountDir $mountDir -DriverFolders $rootPackageFolders -ImageLabel 'install.wim' -ImageMounted $imageMountedRef
|
||||||
while ($remainingDriverFolders.Count -gt 0) {
|
if ($addedCount -gt 0) {
|
||||||
& $Logger "Mounting install.wim index $InstallImageIndex for driver injection..."
|
|
||||||
Invoke-WinUtilISODism -Arguments @('/English', '/Mount-Image', "/ImageFile:$InstallImagePath", "/Index:$InstallImageIndex", "/MountDir:$mountDir") -Operation 'mount' | Out-Null
|
|
||||||
$imageMounted = $true
|
|
||||||
|
|
||||||
$failedDriverFolder = $null
|
|
||||||
foreach ($driverFolder in $remainingDriverFolders) {
|
|
||||||
$driverName = $driverFolder
|
|
||||||
if ($driverFolder.StartsWith($driverExportRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
||||||
$driverName = $driverFolder.Substring($driverExportRoot.Length).TrimStart('\')
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Invoke-WinUtilISODism -Arguments @('/English', "/Image:$mountDir", '/Add-Driver', "/Driver:$driverFolder", '/Recurse') -Operation "add-driver:$driverName" | Out-Null
|
|
||||||
} catch {
|
|
||||||
& $Logger "Warning: failed to add driver package '$driverName': $_"
|
|
||||||
$failedDriverFolder = $driverFolder
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not $failedDriverFolder) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
& $Logger "Discarding the potentially partial install.wim mount before continuing without '$driverName'."
|
|
||||||
try {
|
|
||||||
Invoke-WinUtilISODism -Arguments @('/English', '/Unmount-Image', "/MountDir:$mountDir", '/Discard') -Operation 'discard' | Out-Null
|
|
||||||
$imageMounted = $false
|
|
||||||
} catch {
|
|
||||||
throw "Failed to discard the potentially partial install.wim mount after driver package '$driverName' failed: $_"
|
|
||||||
}
|
|
||||||
|
|
||||||
$remainingDriverFolders = @($remainingDriverFolders | Where-Object { $_ -ne $failedDriverFolder })
|
|
||||||
}
|
|
||||||
|
|
||||||
$addedCount = $remainingDriverFolders.Count
|
|
||||||
if ($addedCount -eq 0) {
|
|
||||||
# Boot-storage drivers staged for WinPE remain available to Windows Setup.
|
|
||||||
& $Logger "Warning: none of the $($rootPackageFolders.Count) exported driver packages could be added; continuing with an unmodified install.wim."
|
|
||||||
} else {
|
|
||||||
& $Logger "Added $addedCount of $($rootPackageFolders.Count) driver packages to install.wim."
|
|
||||||
& $Logger 'Committing the driver-only install.wim change...'
|
|
||||||
Invoke-WinUtilISODism -Arguments @('/English', '/Unmount-Image', "/MountDir:$mountDir", '/Commit') -Operation 'commit' | Out-Null
|
|
||||||
$imageMounted = $false
|
|
||||||
|
|
||||||
$metadataAfter = Get-WinUtilISOWimMetadata -ImagePath $InstallImagePath -Index $InstallImageIndex
|
$metadataAfter = Get-WinUtilISOWimMetadata -ImagePath $InstallImagePath -Index $InstallImageIndex
|
||||||
Assert-WinUtilISOWimMetadata -Before $metadataBefore -After $metadataAfter
|
Assert-WinUtilISOWimMetadata -Before $metadataBefore -After $metadataAfter
|
||||||
& $Logger 'Driver injection complete; install.wim metadata validation passed.'
|
& $Logger 'Driver injection complete; install.wim metadata validation passed.'
|
||||||
@@ -423,7 +429,7 @@ function Invoke-WinUtilISOScript {
|
|||||||
try {
|
try {
|
||||||
Invoke-WinUtilISODism -Arguments @('/English', '/Unmount-Image', "/MountDir:$mountDir", '/Discard') -Operation 'discard' | Out-Null
|
Invoke-WinUtilISODism -Arguments @('/English', '/Unmount-Image', "/MountDir:$mountDir", '/Discard') -Operation 'discard' | Out-Null
|
||||||
} catch {
|
} catch {
|
||||||
& $Logger "Warning: could not discard the failed install.wim mount: $_"
|
& $Logger "Warning: could not discard the failed WIM mount: $_"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Remove-Item -LiteralPath $mountDir -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item -LiteralPath $mountDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
|||||||
+102
-19
@@ -214,7 +214,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
$script:modifyFunction | Should -Match 'if \(\$m -like "Warning:\*"\)[\s\S]*Write-WinUtilISOLog -Level "WARN" -Message \$m -SkipSessionLog[\s\S]*Write-Warning \$m'
|
$script:modifyFunction | Should -Match 'if \(\$m -like "Warning:\*"\)[\s\S]*Write-WinUtilISOLog -Level "WARN" -Message \$m -SkipSessionLog[\s\S]*Write-Warning \$m'
|
||||||
}
|
}
|
||||||
|
|
||||||
It "keeps WIM servicing limited to one driver-only mount and commit" {
|
It "keeps WIM servicing limited to DISM Add-Driver without image export or cleanup" {
|
||||||
$isoScriptContent = Get-Content -Path $script:isoScriptPath -Raw
|
$isoScriptContent = Get-Content -Path $script:isoScriptPath -Raw
|
||||||
|
|
||||||
foreach ($expectedText in @(
|
foreach ($expectedText in @(
|
||||||
@@ -222,7 +222,8 @@ Describe "Win11 Creator setup media" {
|
|||||||
"'/Add-Driver'",
|
"'/Add-Driver'",
|
||||||
"'/Commit'",
|
"'/Commit'",
|
||||||
"`$mountDir = Join-Path (Split-Path -Path `$ContentRoot -Parent) 'wim_mount'",
|
"`$mountDir = Join-Path (Split-Path -Path `$ContentRoot -Parent) 'wim_mount'",
|
||||||
'install.wim metadata validation passed'
|
'install.wim metadata validation passed',
|
||||||
|
"Join-Path `$ContentRoot 'sources\boot.wim'"
|
||||||
)) {
|
)) {
|
||||||
$isoScriptContent | Should -Match ([regex]::Escape($expectedText))
|
$isoScriptContent | Should -Match ([regex]::Escape($expectedText))
|
||||||
}
|
}
|
||||||
@@ -233,17 +234,19 @@ Describe "Win11 Creator setup media" {
|
|||||||
'Export-WindowsImage',
|
'Export-WindowsImage',
|
||||||
'Set-WindowsImage',
|
'Set-WindowsImage',
|
||||||
'/ResetBase',
|
'/ResetBase',
|
||||||
'/Cleanup-Image'
|
'/Cleanup-Image',
|
||||||
|
'$WinpeDriver$'
|
||||||
)) {
|
)) {
|
||||||
$isoScriptContent | Should -Not -Match ([regex]::Escape($forbiddenText))
|
$isoScriptContent | Should -Not -Match ([regex]::Escape($forbiddenText))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
It "stages only boot-storage drivers in WinPE" {
|
It "injects only SCSIAdapter or HDC storage drivers into boot.wim" {
|
||||||
$isoScriptContent = Get-Content -Path $script:isoScriptPath -Raw
|
$isoScriptContent = Get-Content -Path $script:isoScriptPath -Raw
|
||||||
|
|
||||||
$isoScriptContent | Should -Match ([regex]::Escape("Join-Path `$ContentRoot '`$WinpeDriver$'"))
|
|
||||||
$isoScriptContent | Should -Match 'SCSIAdapter\|HDC'
|
$isoScriptContent | Should -Match 'SCSIAdapter\|HDC'
|
||||||
|
$isoScriptContent | Should -Match ([regex]::Escape("Join-Path `$ContentRoot 'sources\boot.wim'"))
|
||||||
|
$isoScriptContent | Should -Not -Match ([regex]::Escape("Join-Path `$ContentRoot '`$WinpeDriver$'"))
|
||||||
$isoScriptContent | Should -Not -Match ([regex]::Escape('sources\$OEM$\$$\Drivers'))
|
$isoScriptContent | Should -Not -Match ([regex]::Escape('sources\$OEM$\$$\Drivers'))
|
||||||
$isoScriptContent | Should -Not -Match ([regex]::Escape('WinUtil-InstallDrivers.ps1'))
|
$isoScriptContent | Should -Not -Match ([regex]::Escape('WinUtil-InstallDrivers.ps1'))
|
||||||
$isoScriptContent | Should -Not -Match ([regex]::Escape('SetupComplete.cmd'))
|
$isoScriptContent | Should -Not -Match ([regex]::Escape('SetupComplete.cmd'))
|
||||||
@@ -435,7 +438,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
It "stages storage drivers for WinPE and adds all drivers to one install.wim index" {
|
It "adds eligible drivers to one install.wim index and does not create `$WinpeDriver$" {
|
||||||
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoDrivers_$([guid]::NewGuid())"
|
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoDrivers_$([guid]::NewGuid())"
|
||||||
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
||||||
$template = Get-Content -Path $script:autoUnattendPath -Raw
|
$template = Get-Content -Path $script:autoUnattendPath -Raw
|
||||||
@@ -443,7 +446,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
|
|
||||||
New-WinUtilDriverExportHarness -Fixtures @(
|
New-WinUtilDriverExportHarness -Fixtures @(
|
||||||
@{ Path = 'system_pkg'; Name = 'chipset.inf'; Class = 'System' },
|
@{ Path = 'system_pkg'; Name = 'chipset.inf'; Class = 'System' },
|
||||||
@{ Path = 'storage_pkg'; Name = 'iaStorAC.inf'; Class = 'System' },
|
@{ Path = 'storage_pkg'; Name = 'iaStorAC.inf'; Class = 'SCSIAdapter' },
|
||||||
@{ Path = 'scsi_pkg'; Name = 'controller.inf'; Class = 'SCSIAdapter' },
|
@{ Path = 'scsi_pkg'; Name = 'controller.inf'; Class = 'SCSIAdapter' },
|
||||||
@{ Path = 'net_pkg'; Name = 'network.inf'; Class = 'Net' },
|
@{ Path = 'net_pkg'; Name = 'network.inf'; Class = 'Net' },
|
||||||
@{ Path = 'group_a\duplicate'; Name = 'audio.inf'; Class = 'Media' },
|
@{ Path = 'group_a\duplicate'; Name = 'audio.inf'; Class = 'Media' },
|
||||||
@@ -465,12 +468,8 @@ Describe "Win11 Creator setup media" {
|
|||||||
$logs.Add([string]$message)
|
$logs.Add([string]$message)
|
||||||
}
|
}
|
||||||
|
|
||||||
$winpeDriverRoot = Join-Path $contentRoot '$WinpeDriver$'
|
Test-Path (Join-Path $contentRoot '$WinpeDriver$') | Should -BeFalse
|
||||||
@(Get-ChildItem -Path $winpeDriverRoot -Directory).Count | Should -Be 2
|
($logs -join '|') | Should -Match 'Warning: boot.wim was not found'
|
||||||
Test-Path (Join-Path $winpeDriverRoot 'system_pkg\chipset.inf') | Should -BeFalse
|
|
||||||
Test-Path (Join-Path $winpeDriverRoot 'storage_pkg\iaStorAC.inf') | Should -BeTrue
|
|
||||||
Test-Path (Join-Path $winpeDriverRoot 'scsi_pkg\controller.inf') | Should -BeTrue
|
|
||||||
Test-Path (Join-Path $winpeDriverRoot 'net_pkg\network.inf') | Should -BeFalse
|
|
||||||
|
|
||||||
@($script:dismCalls | Where-Object { $_ -match '/Mount-Image' }).Count | Should -Be 1
|
@($script:dismCalls | Where-Object { $_ -match '/Mount-Image' }).Count | Should -Be 1
|
||||||
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 9
|
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 9
|
||||||
@@ -488,7 +487,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
$nsMgr = New-Object System.Xml.XmlNamespaceManager($answerFile.NameTable)
|
$nsMgr = New-Object System.Xml.XmlNamespaceManager($answerFile.NameTable)
|
||||||
$nsMgr.AddNamespace('sg', 'https://schneegans.de/windows/unattend-generator/')
|
$nsMgr.AddNamespace('sg', 'https://schneegans.de/windows/unattend-generator/')
|
||||||
$answerFile.SelectSingleNode('//sg:File[@path="C:\Windows\Setup\Scripts\WinUtil-InstallDrivers.ps1"]', $nsMgr) | Should -BeNullOrEmpty
|
$answerFile.SelectSingleNode('//sg:File[@path="C:\Windows\Setup\Scripts\WinUtil-InstallDrivers.ps1"]', $nsMgr) | Should -BeNullOrEmpty
|
||||||
($logs -join '|') | Should -Match 'Exported 10 of 11 driver packages \(2 staged for WinPE, 1 excluded\)'
|
($logs -join '|') | Should -Match 'Exported 10 of 11 driver packages \(1 excluded\)'
|
||||||
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*ntprint\.inf_x86_7426e1b60aa62272' \(DriverVer 1/1/2023,10\.0\.26100\.8875\) superseded by '.*ntprint\.inf_x86_58e7118cdecb935e' \(DriverVer 6/1/2024,10\.0\.26100\.9168\)"
|
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*ntprint\.inf_x86_7426e1b60aa62272' \(DriverVer 1/1/2023,10\.0\.26100\.8875\) superseded by '.*ntprint\.inf_x86_58e7118cdecb935e' \(DriverVer 6/1/2024,10\.0\.26100\.9168\)"
|
||||||
($logs -join '|') | Should -Match 'install.wim metadata validation passed'
|
($logs -join '|') | Should -Match 'install.wim metadata validation passed'
|
||||||
($logs -join '|') | Should -Match 'DISM mount completed.'
|
($logs -join '|') | Should -Match 'DISM mount completed.'
|
||||||
@@ -505,6 +504,91 @@ Describe "Win11 Creator setup media" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
It "injects SCSIAdapter storage drivers into boot.wim index 2 and not `$WinpeDriver`$" {
|
||||||
|
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoBootWim_$([guid]::NewGuid())"
|
||||||
|
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
||||||
|
$bootWim = Join-Path $contentRoot 'sources\boot.wim'
|
||||||
|
$template = Get-Content -Path $script:autoUnattendPath -Raw
|
||||||
|
$logs = [System.Collections.Generic.List[string]]::new()
|
||||||
|
|
||||||
|
New-WinUtilDriverExportHarness -Fixtures @(
|
||||||
|
@{ Path = 'net_pkg'; Name = 'network.inf'; Class = 'Net' },
|
||||||
|
@{ Path = 'scsi_pkg'; Name = 'controller.inf'; Class = 'SCSIAdapter' },
|
||||||
|
@{ Path = 'hdc_pkg'; Name = 'ide.inf'; Class = 'HDC' },
|
||||||
|
@{ Path = 'name_only_pkg'; Name = 'iaStorAC.inf'; Class = 'System' },
|
||||||
|
@{ Path = 'iastorhsacomponent.inf_amd64_1b2a068a8496b6a2'; Name = 'iaStorHsaComponent.inf'; Class = 'SoftwareComponent' },
|
||||||
|
@{ Path = 'iastorhsa_ext.inf_amd64_ba71359697f80d4e'; Name = 'iaStorHsa_Ext.inf'; Class = 'Extension' }
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
New-Item -Path (Split-Path $installWim -Parent) -ItemType Directory -Force | Out-Null
|
||||||
|
Set-Content -Path $installWim -Value 'mock-wim'
|
||||||
|
Set-Content -Path $bootWim -Value 'mock-boot'
|
||||||
|
. $script:isoScriptPath
|
||||||
|
Invoke-WinUtilISOScript -ISOContentsDir $contentRoot -AutoUnattendXml $template -InjectCurrentSystemDrivers $true -InstallImagePath $installWim -InstallImageIndex 6 -InstallEditionId 'Professional' -Log {
|
||||||
|
param($message)
|
||||||
|
$logs.Add([string]$message)
|
||||||
|
}
|
||||||
|
|
||||||
|
Test-Path (Join-Path $contentRoot '$WinpeDriver$') | Should -BeFalse
|
||||||
|
@($script:dismCalls | Where-Object { $_ -match '/Mount-Image' -and $_ -match 'boot\.wim' -and $_ -match '/Index:2' }).Count | Should -Be 1
|
||||||
|
@($script:dismCalls | Where-Object { $_ -match '/Mount-Image' -and $_ -match 'install\.wim' }).Count | Should -Be 1
|
||||||
|
@($script:dismCalls | Where-Object { $_ -match '/Unmount-Image\|.*\|/Commit' }).Count | Should -Be 2
|
||||||
|
|
||||||
|
$bootMountCall = $script:dismCalls | Where-Object { $_ -match '/Mount-Image' -and $_ -match 'boot\.wim' } | Select-Object -First 1
|
||||||
|
$installMountCall = $script:dismCalls | Where-Object { $_ -match '/Mount-Image' -and $_ -match 'install\.wim' } | Select-Object -First 1
|
||||||
|
$bootMountIndex = [Array]::IndexOf($script:dismCalls.ToArray(), $bootMountCall)
|
||||||
|
$installMountIndex = [Array]::IndexOf($script:dismCalls.ToArray(), $installMountCall)
|
||||||
|
$bootAdds = @($script:dismCalls[$bootMountIndex..($installMountIndex - 1)] | Where-Object { $_ -match '/Add-Driver' })
|
||||||
|
$bootAdds.Count | Should -Be 2
|
||||||
|
($bootAdds -join "`n") | Should -Match ([regex]::Escape('scsi_pkg'))
|
||||||
|
($bootAdds -join "`n") | Should -Match ([regex]::Escape('hdc_pkg'))
|
||||||
|
($bootAdds -join "`n") | Should -Not -Match ([regex]::Escape('net_pkg'))
|
||||||
|
($bootAdds -join "`n") | Should -Not -Match 'iastorhsa'
|
||||||
|
($bootAdds -join "`n") | Should -Not -Match ([regex]::Escape('name_only_pkg'))
|
||||||
|
|
||||||
|
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 8
|
||||||
|
($logs -join '|') | Should -Match 'Added 2 of 2 driver packages to boot.wim'
|
||||||
|
($logs -join '|') | Should -Match 'Added 6 of 6 driver packages to install.wim'
|
||||||
|
} finally {
|
||||||
|
Remove-Item Function:\dism.exe -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Path $contentRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It "injects only the newest duplicate storage package into boot.wim" {
|
||||||
|
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoBootWimDedup_$([guid]::NewGuid())"
|
||||||
|
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
||||||
|
$bootWim = Join-Path $contentRoot 'sources\boot.wim'
|
||||||
|
$template = Get-Content -Path $script:autoUnattendPath -Raw
|
||||||
|
$logs = [System.Collections.Generic.List[string]]::new()
|
||||||
|
|
||||||
|
New-WinUtilDriverExportHarness -Fixtures @(
|
||||||
|
@{ Path = 'iastorvd.inf_amd64_11111111aaaaaaaa'; Name = 'iaStorVD.inf'; Class = 'SCSIAdapter'; DriverVer = '1/1/2023,20.2.1.1016' },
|
||||||
|
@{ Path = 'iastorvd.inf_amd64_22222222bbbbbbbb'; Name = 'iaStorVD.inf'; Class = 'SCSIAdapter'; DriverVer = '6/1/2024,20.2.8.1028' }
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
New-Item -Path (Split-Path $installWim -Parent) -ItemType Directory -Force | Out-Null
|
||||||
|
Set-Content -Path $installWim -Value 'mock-wim'
|
||||||
|
Set-Content -Path $bootWim -Value 'mock-boot'
|
||||||
|
. $script:isoScriptPath
|
||||||
|
Invoke-WinUtilISOScript -ISOContentsDir $contentRoot -AutoUnattendXml $template -InjectCurrentSystemDrivers $true -InstallImagePath $installWim -InstallImageIndex 6 -InstallEditionId 'Professional' -Log {
|
||||||
|
param($message)
|
||||||
|
$logs.Add([string]$message)
|
||||||
|
}
|
||||||
|
|
||||||
|
$bootAdds = @($script:dismCalls | Where-Object { $_ -match '/Add-Driver' })
|
||||||
|
@($bootAdds | Where-Object { $_ -match '22222222bbbbbbbb' }).Count | Should -Be 2
|
||||||
|
@($bootAdds | Where-Object { $_ -match '11111111aaaaaaaa' }).Count | Should -Be 0
|
||||||
|
($logs -join '|') | Should -Match 'Added 1 of 1 driver packages to boot.wim'
|
||||||
|
($logs -join '|') | Should -Match 'Added 1 of 1 driver packages to install.wim'
|
||||||
|
} finally {
|
||||||
|
Remove-Item Function:\dism.exe -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Path $contentRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
It "injects Class=Extension driver packages like any other export" {
|
It "injects Class=Extension driver packages like any other export" {
|
||||||
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoExtensionInject_$([guid]::NewGuid())"
|
$contentRoot = Join-Path ([IO.Path]::GetTempPath()) "WinUtilIsoExtensionInject_$([guid]::NewGuid())"
|
||||||
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
$installWim = Join-Path $contentRoot 'sources\install.wim'
|
||||||
@@ -528,7 +612,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 3
|
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 3
|
||||||
($logs -join '|') | Should -Match 'Exported 3 of 3 driver packages \(0 staged for WinPE, 0 excluded\)'
|
($logs -join '|') | Should -Match 'Exported 3 of 3 driver packages \(0 excluded\)'
|
||||||
$driversInjected.Value | Should -BeTrue
|
$driversInjected.Value | Should -BeTrue
|
||||||
|
|
||||||
$script:exportRootAtAddDriver | Should -Contain (Join-Path $script:driverExportRoot 'ext_pkg_lower')
|
$script:exportRootAtAddDriver | Should -Contain (Join-Path $script:driverExportRoot 'ext_pkg_lower')
|
||||||
@@ -628,7 +712,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 2
|
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 2
|
||||||
($logs -join '|') | Should -Match 'Exported 2 of 2 driver packages \(0 staged for WinPE, 0 excluded\)'
|
($logs -join '|') | Should -Match 'Exported 2 of 2 driver packages \(0 excluded\)'
|
||||||
($logs -join '|') | Should -Not -Match 'Excluding stale duplicate driver package'
|
($logs -join '|') | Should -Not -Match 'Excluding stale duplicate driver package'
|
||||||
|
|
||||||
$script:exportRootAtAddDriver | Should -Contain (Join-Path $script:driverExportRoot 'device.inf_amd64_11111111aaaaaaaa')
|
$script:exportRootAtAddDriver | Should -Contain (Join-Path $script:driverExportRoot 'device.inf_amd64_11111111aaaaaaaa')
|
||||||
@@ -669,7 +753,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 3
|
@($script:dismCalls | Where-Object { $_ -match '/Add-Driver' }).Count | Should -Be 3
|
||||||
($logs -join '|') | Should -Match 'Exported 3 of 7 driver packages \(0 staged for WinPE, 4 excluded\)'
|
($logs -join '|') | Should -Match 'Exported 3 of 7 driver packages \(4 excluded\)'
|
||||||
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*ntprint\.inf_x86_7426e1b60aa62272' \(DriverVer 1/1/2023,10\.0\.26100\.8875\) superseded by '.*ntprint\.inf_x86_58e7118cdecb935e'"
|
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*ntprint\.inf_x86_7426e1b60aa62272' \(DriverVer 1/1/2023,10\.0\.26100\.8875\) superseded by '.*ntprint\.inf_x86_58e7118cdecb935e'"
|
||||||
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*ntprint\.inf_x86_6688e7b66f8d9fb5' \(DriverVer 1/1/2024,10\.0\.26100\.8972\) superseded by '.*ntprint\.inf_x86_58e7118cdecb935e'"
|
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*ntprint\.inf_x86_6688e7b66f8d9fb5' \(DriverVer 1/1/2024,10\.0\.26100\.8972\) superseded by '.*ntprint\.inf_x86_58e7118cdecb935e'"
|
||||||
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*sample\.inf_amd64_11111111aaaaaaaa' \(DriverVer unknown\) superseded by '.*sample\.inf_amd64_22222222bbbbbbbb' \(DriverVer 3/1/2024,1\.2\.3\.4\)"
|
($logs -join '|') | Should -Match "Excluding stale duplicate driver package '.*sample\.inf_amd64_11111111aaaaaaaa' \(DriverVer unknown\) superseded by '.*sample\.inf_amd64_22222222bbbbbbbb' \(DriverVer 3/1/2024,1\.2\.3\.4\)"
|
||||||
@@ -753,8 +837,7 @@ Describe "Win11 Creator setup media" {
|
|||||||
|
|
||||||
($logs -join '|') | Should -Match "none of the $script:expectedRootPackages exported driver packages could be added"
|
($logs -join '|') | Should -Match "none of the $script:expectedRootPackages exported driver packages could be added"
|
||||||
($logs -join '|') | Should -Not -Match "Added 0 of $script:expectedRootPackages"
|
($logs -join '|') | Should -Not -Match "Added 0 of $script:expectedRootPackages"
|
||||||
# WinPE staging is independent of WIM servicing, so it must survive the failure.
|
Test-Path (Join-Path $contentRoot '$WinpeDriver$') | Should -BeFalse
|
||||||
@(Get-ChildItem -Path (Join-Path $contentRoot '$WinpeDriver$') -Directory).Count | Should -Be 2
|
|
||||||
$driversInjected.Value | Should -BeFalse
|
$driversInjected.Value | Should -BeFalse
|
||||||
} finally {
|
} finally {
|
||||||
Remove-Item Function:\dism.exe -ErrorAction SilentlyContinue
|
Remove-Item Function:\dism.exe -ErrorAction SilentlyContinue
|
||||||
|
|||||||
Reference in New Issue
Block a user