Skip to content

Commit cca9bee

Browse files
Add minimal driver injection
1 parent 669ecd9 commit cca9bee

File tree

3 files changed

+68
-39
lines changed

3 files changed

+68
-39
lines changed

functions/private/Invoke-WinUtilISO.ps1

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -562,15 +562,21 @@ function Invoke-WinUtilISOCleanAndReset {
562562
foreach ($f in $files) {
563563
try { Remove-Item -Path $f.FullName -Force -ErrorAction Stop } catch {}
564564
$deleted++
565-
$pct = [math]::Round(($deleted / [Math]::Max($total,1)) * 85) + 5
566-
SetProgress "Deleting files... ($deleted / $total)" $pct
565+
if ($deleted % 100 -eq 0 -or $deleted -eq $files.Count) {
566+
$pct = [math]::Round(($deleted / [Math]::Max($total,1)) * 85) + 5
567+
SetProgress "Deleting files... ($deleted / $total)" $pct
568+
Log "Deleting files... $deleted of $total"
569+
}
567570
}
568571

569572
foreach ($d in $dirs) {
570573
try { Remove-Item -Path $d.FullName -Force -Recurse -ErrorAction Stop } catch {}
571574
$deleted++
572-
$pct = [math]::Round(($deleted / [Math]::Max($total,1)) * 85) + 5
573-
SetProgress "Removing directories... ($deleted / $total)" $pct
575+
if ($deleted % 50 -eq 0 -or $deleted -eq $total) {
576+
$pct = [math]::Round(($deleted / [Math]::Max($total,1)) * 85) + 5
577+
SetProgress "Removing directories... ($deleted / $total)" $pct
578+
Log "Removing directories... $deleted of $total"
579+
}
574580
}
575581

576582
# Remove the root work directory itself

functions/private/Invoke-WinUtilISOScript.ps1

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,12 @@ function Invoke-WinUtilISOScript {
44
Applies WinUtil modifications to a mounted Windows 11 install.wim image.
55
66
.DESCRIPTION
7-
Performs the following operations against an already-mounted WIM image:
8-
9-
1. Removes provisioned AppX bloatware packages via DISM.
10-
2. Removes OneDriveSetup.exe from the system image.
11-
3. Loads offline registry hives (COMPONENTS, DEFAULT, NTUSER, SOFTWARE, SYSTEM)
12-
and applies the following tweaks:
13-
- Bypasses hardware requirement checks (CPU, RAM, SecureBoot, Storage, TPM).
14-
- Disables sponsored-app delivery and ContentDeliveryManager features.
15-
- Enables local-account OOBE path (BypassNRO).
16-
- Writes autounattend.xml to the Sysprep directory inside the WIM and,
17-
optionally, to the ISO/USB root so Windows Setup picks it up at boot.
18-
- Disables reserved storage.
19-
- Disables BitLocker device encryption.
20-
- Hides the Chat (Teams) taskbar icon.
21-
- Disables OneDrive folder backup (KFM).
22-
- Disables telemetry, advertising ID, and input personalization.
23-
- Blocks post-install delivery of DevHome, Outlook, and Teams.
24-
- Disables Windows Copilot.
25-
- Disables Windows Update during OOBE.
26-
4. Deletes unwanted scheduled-task XML definition files (CEIP, Appraiser, etc.).
27-
5. Removes the support\ folder from the ISO contents directory (if supplied).
28-
29-
Mounting and dismounting the WIM is the responsibility of the caller
30-
(e.g. Invoke-WinUtilISO).
7+
Removes AppX bloatware and OneDrive, injects hardware drivers (NVMe, Precision
8+
Touchpad/HID, and network) exported from the running system, applies offline
9+
registry tweaks (hardware bypass, privacy, OOBE, telemetry, update suppression),
10+
deletes CEIP/WU scheduled-task definition files, and optionally drops
11+
autounattend.xml and removes the support\ folder from the ISO contents directory.
12+
Mounting/dismounting the WIM is the caller's responsibility (e.g. Invoke-WinUtilISO).
3113
3214
.PARAMETER ScratchDir
3315
Mandatory. Full path to the directory where the Windows image is currently mounted.
@@ -62,15 +44,11 @@ function Invoke-WinUtilISOScript {
6244
.NOTES
6345
Author : Chris Titus @christitustech
6446
GitHub : https://github.com/ChrisTitusTech
65-
Version : 26.02.22
47+
Version : 26.02.25
6648
#>
6749
param (
6850
[Parameter(Mandatory)][string]$ScratchDir,
69-
# Root directory of the extracted ISO contents. When supplied, autounattend.xml
70-
# is written here so Windows Setup picks it up automatically at boot.
7151
[string]$ISOContentsDir = "",
72-
# Autounattend XML content. In compiled winutil.ps1 this comes from the embedded
73-
# $WinUtilAutounattendXml here-string; in dev mode it is read from tools\autounattend.xml.
7452
[string]$AutoUnattendXml = "",
7553
[scriptblock]$Log = { param($m) Write-Output $m }
7654
)
@@ -164,15 +142,58 @@ function Invoke-WinUtilISOScript {
164142
}
165143

166144
# ═════════════════════════════════════════════════════════════════════════
167-
# 2. Remove OneDrive
145+
# 2. Inject hardware drivers (NVMe / Trackpad / Network)
146+
# ═════════════════════════════════════════════════════════════════════════
147+
& $Log "Exporting hardware drivers from running system (NVMe, HID/Trackpad, Network)..."
148+
149+
$driverExportRoot = Join-Path $env:TEMP "WinUtil_DriverExport_$(Get-Random)"
150+
New-Item -Path $driverExportRoot -ItemType Directory -Force | Out-Null
151+
152+
try {
153+
# Export every online driver to the temp folder.
154+
# Export-WindowsDriver creates one sub-folder per .inf package.
155+
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
156+
157+
# Driver classes to inject:
158+
# SCSIAdapter - NVMe / AHCI storage controllers
159+
# HIDClass - Precision Touchpad and HID devices
160+
# Net - Ethernet and Wi-Fi adapters
161+
$targetClasses = @('SCSIAdapter', 'HIDClass', 'Net')
162+
163+
$targetInfBases = Get-WindowsDriver -Online |
164+
Where-Object { $_.ClassName -in $targetClasses } |
165+
ForEach-Object { [IO.Path]::GetFileNameWithoutExtension($_.OriginalFileName) } |
166+
Select-Object -Unique
167+
168+
$injected = 0
169+
foreach ($infBase in $targetInfBases) {
170+
$infFile = Get-ChildItem -Path $driverExportRoot -Filter "$infBase.inf" `
171+
-Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
172+
if ($infFile) {
173+
& dism /English "/image:$ScratchDir" /Add-Driver "/Driver:$($infFile.FullName)"
174+
$injected++
175+
} else {
176+
& $Log "Warning: exported .inf not found for '$infBase' — skipped."
177+
}
178+
}
179+
180+
& $Log "Driver injection complete — $injected driver package(s) added."
181+
} catch {
182+
& $Log "Error during driver export/injection: $_"
183+
} finally {
184+
Remove-Item -Path $driverExportRoot -Recurse -Force -ErrorAction SilentlyContinue
185+
}
186+
187+
# ═════════════════════════════════════════════════════════════════════════
188+
# 3. Remove OneDrive
168189
# ═════════════════════════════════════════════════════════════════════════
169190
& $Log "Removing OneDrive..."
170191
& takeown /f "$ScratchDir\Windows\System32\OneDriveSetup.exe" | Out-Null
171192
& icacls "$ScratchDir\Windows\System32\OneDriveSetup.exe" /grant "$($adminGroup.Value):(F)" /T /C | Out-Null
172193
Remove-Item -Path "$ScratchDir\Windows\System32\OneDriveSetup.exe" -Force -ErrorAction SilentlyContinue
173194

174195
# ═════════════════════════════════════════════════════════════════════════
175-
# 3. Registry tweaks
196+
# 4. Registry tweaks
176197
# ═════════════════════════════════════════════════════════════════════════
177198
& $Log "Loading offline registry hives..."
178199
reg load HKLM\zCOMPONENTS "$ScratchDir\Windows\System32\config\COMPONENTS"
@@ -305,7 +326,7 @@ function Invoke-WinUtilISOScript {
305326
reg unload HKLM\zSYSTEM
306327

307328
# ═════════════════════════════════════════════════════════════════════════
308-
# 4. Delete scheduled task definition files
329+
# 5. Delete scheduled task definition files
309330
# ═════════════════════════════════════════════════════════════════════════
310331
& $Log "Deleting scheduled task definition files..."
311332
$tasksPath = "$ScratchDir\Windows\System32\Tasks"
@@ -325,7 +346,7 @@ function Invoke-WinUtilISOScript {
325346
& $Log "Scheduled task files deleted."
326347

327348
# ═════════════════════════════════════════════════════════════════════════
328-
# 5. Remove ISO support folder (fresh-install only; not needed)
349+
# 6. Remove ISO support folder (fresh-install only; not needed)
329350
# ═════════════════════════════════════════════════════════════════════════
330351
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
331352
& $Log "Removing ISO support\ folder..."

scripts/main.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,11 @@ $sync["FontScalingApplyButton"].Add_Click({
534534

535535
# ── Win11ISO Tab button handlers ──────────────────────────────────────────────
536536

537-
# Check for an existing working directory each time the Win11ISO tab is opened
538537
$sync["WPFTab5BT"].Add_Click({
539-
Invoke-WinUtilISOCheckExistingWork
538+
$sync["Form"].Dispatcher.BeginInvoke(
539+
[System.Windows.Threading.DispatcherPriority]::Background,
540+
[action]{ Invoke-WinUtilISOCheckExistingWork }
541+
) | Out-Null
540542
})
541543

542544
$sync["WPFWin11ISOBrowseButton"].Add_Click({

0 commit comments

Comments
 (0)