@@ -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..."
0 commit comments