Compare commits

...
12 Commits
Author SHA1 Message Date
Chris TitusandGitHub 8147903ff2 chore: Update generated dev docs (#4801) 2026-07-02 15:26:16 -05:00
GabiandGitHub 7a72c73906 Talk about "PowerShell 7 from the Microsoft Store" inside of KnownIssues.md (#4758)
* Talk about "PowerShell 7 from the Microsoft Store" inside of KnownIssues.md

* Update Invoke-WinUtilInstallPSProfile.ps1

* Update KnownIssues.md

* Update KnownIssues.md

* Update KnownIssues.md
2026-07-02 15:25:08 -05:00
Chris TitusandGitHub 32891ada55 Fix DHCP DNS reset handling (#4800) 2026-07-02 15:24:14 -05:00
Chris TitusandGitHub e2d6f8534e chore: Update generated dev docs (#4798) 2026-07-02 13:29:34 -05:00
299b68e82d Added winget uninstall of Copilot. Line 968 Remove-AppxPackage is not working when Copilot is installed back after Windows Updates and the only option that works is using winget (#4797)
Co-authored-by: gepardjaro <192244662+gepardjaro@users.noreply.github.com>
2026-07-02 13:28:57 -05:00
de6652adc0 Remove local file preference storage and cleanup Invoke-WinutilThemeChange (#4617)
* Remove local file preference storage

* Update main.ps1

* Update main.ps1

* Update Set-Preferences.ps1

* Update main.ps1

* Update Set-Preferences.ps1

* Update main.ps1

* Delete functions/private/Set-Preferences.ps1

* simplify Invoke-WinutilThemeChange.ps1

* fix foss highlight in Invoke-WinutilThemeChange.ps1

* Update Invoke-WinutilThemeChange.ps1

* Update Invoke-WinutilThemeChange.ps1

* Update main.ps1

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2026-07-02 13:04:50 -05:00
727ba52a4d Deleted Test-WinUtilPackageManager.ps1 + custom winget and choco installs + remove winget/choco enums and exeptions (#4606)
* Update Invoke-WPFGetInstalled.ps1

* Update Install-WinUtilWinget.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilWinget.ps1

* Delete functions/private/Test-WinUtilPackageManager.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilWinget.ps1

* Update Install-WinUtilChoco.ps1

* Update Invoke-WPFGetInstalled.ps1

* Update Invoke-WPFGetInstalled.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilWinget.ps1

* Update Install-WinUtilWinget.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilWinget.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilWinget.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilChoco.ps1

* Update Install-WinUtilWinget.ps1

* Fixed lastrun.json

* refactor: remove PackageManagers enum and unused custom exception classes

* Update Invoke-WPFUIElements.ps1

* Update Get-WinUtilSelectedPackages.ps1

* Update Set-Preferences.ps1

* Update main.ps1

* Complete package manager enum removal

Use string package-manager preferences throughout the remaining helpers and focused tests. Restore the existing Winget install flow and package-manager probe helper so PR 4606 keeps the current WinGet repair method.

* Fix string keyed package split

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2026-07-02 12:50:57 -05:00
d45c62e470 Cleanup start.ps1 (#4587)
* Update start.ps1

* Update start.ps1

* Update start.ps1

* Update start.ps1

* Update start.ps1

* Update start.ps1

* Update start.ps1

* Update start.ps1

* Update start.ps1

* Fix startup logging regression

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2026-07-02 12:20:38 -05:00
Chris Titus 492d5b57d7 cleanup 2026-07-02 12:06:36 -05:00
Chris TitusandGitHub 58d37bb461 Clean up analyzer warnings across app search and ISO workflows (#4794)
* Clean up analyzer warnings

* Align analyzer warning cleanup policy

* Run PSScriptAnalyzer directly in unittests workflow

* Bind lazy-rendered buttons to click handlers

* Remove WinUtil performance tracing

* Fix Win11 ISO creator temp directory reuse
2026-07-02 12:05:25 -05:00
Sean (ANGRYxScotsman)andGitHub b72bfb03ba Update pre-release.yaml (#4746) 2026-07-02 11:01:18 -05:00
Chris Titus cc2be2d5e8 cleanup 2026-07-02 10:21:41 -05:00
102 changed files with 507 additions and 960 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
with:
token: ${{ secrets.AUTO_MERGE }}
commit-message: 'chore: Update documentation links in JSON configs'
title: 'chore: Update Generated Dev Docs'
title: 'chore: Update documentation links in JSON configs'
body: 'Automated update of documentation links in JSON configs from pre-release build'
branch: docs-update
delete-branch: true
+16 -8
View File
@@ -9,14 +9,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: lint
uses: devblackops/github-action-psscriptanalyzer@master
with:
sendComment: false
settingsPath: lint/PSScriptAnalyser.ps1
failOnErrors: false
failOnWarnings: false
failOnInfos: false
- name: Install PSScriptAnalyzer
run: |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module -Name PSScriptAnalyzer -RequiredVersion 1.20.0 -Scope CurrentUser -Force
Import-Module PSScriptAnalyzer -RequiredVersion 1.20.0 -Force
Get-Module PSScriptAnalyzer | Select-Object Name, Version, Path
shell: pwsh
- name: Run PSScriptAnalyzer
run: |
$results = Invoke-ScriptAnalyzer -Path . -Settings ./lint/PSScriptAnalyser.ps1 -Recurse
if ($results) {
$results | Format-Table -AutoSize | Out-String -Width 4096 | Write-Host
} else {
Write-Host "PSScriptAnalyzer found no diagnostics."
}
shell: pwsh
test:
runs-on: windows-latest
+3 -1
View File
@@ -188,4 +188,6 @@ When the user corrects an agent approach, add or tighten one concrete rule here
- Keep package install/uninstall process launches simple unless explicitly requested; do not add a separate stdout/stderr process logging helper for winget or Chocolatey.
- When the active log file is owned by `Start-Transcript`, do not call `Add-Content` against that file; write to host output so the transcript captures the line in the same log file without recording a terminating-error diagnostic.
- 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.
- Keep performance tracing helpers under `tools/perf`; include them in generated output only through `Compile.ps1 -Trace`.
- 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 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.
+3 -38
View File
@@ -1,27 +1,9 @@
param (
[switch]$Run,
[switch]$Trace
[switch]$Run
)
$OFS = "`r`n"
function Get-WinUtilTraceStrippedContent {
param(
[Parameter(Mandatory = $true)]
[string]$Content
)
if ($Trace) {
return $Content
}
$filteredLines = $Content -split "`r?`n" | Where-Object {
$_ -notmatch '^\s*(Start-WinUtilPerformanceTrace|Stop-WinUtilPerformanceTrace|Write-WinUtilPerformanceCheckpoint)\b'
}
$filteredLines -join "`r`n"
}
# Variable to sync between runspaces
$sync = [Hashtable]::Synchronized(@{})
$sync.configs = @{}
@@ -29,17 +11,7 @@ $sync.configs = @{}
$script = (Get-Content -Path scripts\start.ps1) -replace '#{replaceme}', (Get-Date -Format 'yy.MM.dd')
$script += Get-ChildItem -Path functions -Recurse -File | ForEach-Object {
Get-WinUtilTraceStrippedContent -Content (Get-Content -Path $_.FullName -Raw)
}
if ($Trace) {
$script += Get-ChildItem -Path tools\perf -Filter *.ps1 -File | Get-Content -Raw
$script += @'
$sync.PerformanceTraceEnabled = $true
Start-WinUtilPerformanceTrace
Write-WinUtilPerformanceCheckpoint -Name "Config load start"
'@
Get-Content -Path $_.FullName -Raw
}
Get-ChildItem config | ForEach-Object {
@@ -57,13 +29,6 @@ Get-ChildItem config | ForEach-Object {
$sync.configs[$_.BaseName] = $obj
$script += "`$sync.configs.$($_.BaseName) = @'`r`n$json`r`n'@ | ConvertFrom-Json"
if ($Trace) {
$script += "`r`nWrite-WinUtilPerformanceCheckpoint -Name `"Config $($_.BaseName) loaded`""
}
}
if ($Trace) {
$script += "`r`nWrite-WinUtilPerformanceCheckpoint -Name `"Config load complete`""
}
$xaml = Get-Content -Path xaml\inputXML.xaml -Raw
@@ -72,7 +37,7 @@ $script += "`$inputXML = @'`r`n$xaml`r`n'@"
$autounattendXml = Get-Content -Path tools\autounattend.xml -Raw
$script += "`$WinUtilAutounattendXml = @'`r`n$autounattendXml`r`n'@"
$script += Get-WinUtilTraceStrippedContent -Content (Get-Content -Path scripts\main.ps1 -Raw)
$script += Get-Content -Path scripts\main.ps1 -Raw
Set-Content -Path winutil.ps1 -Value $script
-107
View File
@@ -1,107 +0,0 @@
# Test TODO
Current suite status: broad parser, import, config JSON, compile, and runspace smoke coverage exists, but runtime behavior coverage is still very thin. Work from the top down; the first items are the highest-value gaps.
## P0 - Highest Priority
- [x] Add config reference integrity tests.
- Verify every preset entry points to an existing tweak, feature, app, appx item, or supported action.
- Verify `appnavigation.json` entries point to real tabs/panels and valid config groups.
- Verify tweak, feature, DNS, appx, and theme entries include all fields used by the UI/rendering code.
- Verify all embedded script strings in `config/*.json` parse as PowerShell when wrapped as scriptblocks.
- [x] Add XAML/control wiring tests.
- Load `xaml/inputXML.xaml` as XML and verify expected named controls exist.
- Verify controls referenced through `$sync["Name"]`, `$sync.Name`, or event handlers exist in XAML or are intentionally created dynamically.
- Verify `Invoke-WPF*` handler names used by buttons/tabs correspond to real functions.
- Verify core tabs, search controls, install panels, tweak panels, and Win11 Creator controls are present.
- [x] Add mock-based tests for registry and service helpers.
- Cover `Set-WinUtilRegistry` set/remove paths with `Mock New-Item`, `Mock Set-ItemProperty`, and `Mock Remove-ItemProperty`.
- Cover `Set-WinUtilService` for missing services, startup type changes, and no-op behavior.
- Assert command parameters instead of touching the real registry or services.
- [x] Add package selection and package manager tests.
- Cover `Get-WinUtilSelectedPackages` for winget-only, choco-only, mixed, `na`, empty, duplicate, and missing package entries.
- Cover `Test-WinUtilPackageManager` with mocked `Get-Command`.
- Cover `Install-WinUtilProgramWinget` and `Install-WinUtilProgramChoco` with mocked `Start-Process`, including install/uninstall arguments.
- [x] Add runspace behavior tests beyond the smoke test.
- Cover no argument list, one named parameter, multiple named parameters, and scriptblock failures.
- Assert callers receive a single `IAsyncResult`.
- Verify failure output/errors can be retrieved by the owning PowerShell instance.
- Add focused tests for public functions that call `Invoke-WPFRunspace` without executing their destructive inner work.
## P1 - Important Workflow Coverage
- [x] Add tweak execution orchestration tests.
- Cover `Invoke-WinUtilTweaks` with mocked `Invoke-WinUtilScript`, `Set-WinUtilRegistry`, `Set-WinUtilService`, and `Set-WinUtilDNS`.
- Verify undo mode uses `OriginalValue` and `OriginalType`.
- Verify DNS provider and progress counters are passed through correctly.
- [x] Add install/uninstall workflow tests.
- Cover `Invoke-WPFInstall` and `Invoke-WPFUnInstall` with mocked package sorting and mocked installers.
- Verify empty selection prompts and exits.
- Verify process-running guard prevents a second install/uninstall.
- Verify taskbar/progress cleanup happens on success and error.
- [x] Add update profile tests.
- Cover `Invoke-WPFUpdatesdisable`, `Invoke-WPFUpdatesdefault`, and `Invoke-WPFUpdatessecurity` with mocks for registry, services, scheduled tasks, and process calls.
- Assert intended registry paths, values, service startup types, and scheduled task paths.
- Keep all tests non-mutating.
- [x] Add AppX removal tests.
- Cover `Remove-WinUtilAPPX` with mocked `Get-AppxPackage` and `Remove-AppxPackage`.
- Cover `Invoke-WPFAppxRemoval` selection behavior and runspace parameter passing.
- Verify empty selection is handled without removal calls.
- [x] Add UI selection/state helper tests.
- Cover `Update-WinUtilSelections`, `Reset-WPFCheckBoxes`, `Invoke-WPFSelectedCheckboxesUpdate`, and `Invoke-WPFToggleAllCategories`.
- Use small fake checkbox/control objects instead of WPF windows where possible.
- Verify selected apps, tweaks, toggles, appx, and features stay in sync with checkbox state.
## P2 - Domain-Specific Coverage
- [x] Expand Win11 Creator tests.
- Test edition name to edition ID mapping.
- Test `ei.cfg` and `PID.txt` generation/removal behavior in a temp directory.
- Test autounattend conversion preserves required nodes and removes unsupported product key paths.
- Test driver injection branching with mocked DISM commands.
- Test ISO export fallback when `oscdimg.exe` is missing and winget install fails.
- [x] Add preferences/theme tests.
- Cover `Set-Preferences` loading, saving, old preference cleanup, and defaults.
- Cover theme resource updates without opening the full GUI.
- Verify theme config contains required brushes/colors used by the theme code.
- [x] Add search/filter tests.
- Cover `Find-AppsByNameOrDescription` and `Find-TweaksByNameOrDescription` with fake UI item trees.
- Verify empty search restores visibility.
- Verify category labels and panels hide/show correctly.
- Verify description and display-name matches both work.
- [x] Add compile contract tests.
- Verify compiled config key transformation for `applications.json` adds `WPFInstall` prefixes.
- Verify source ordering in `winutil.ps1`: start script, functions, configs, XAML, autounattend XML, main script.
- Verify generated build date placeholder is replaced.
- Verify generated script does not contain unresolved `#{replaceme}`.
## P3 - Nice To Have
- [ ] Add Script Analyzer as a failing CI gate once existing findings are triaged.
- [ ] Add docs generation/link checks for `docs/content`.
- [ ] Add coverage reporting in CI as informational output.
- [ ] Add a lightweight test helper module for fake `$sync`, fake WPF controls, and common mocks.
- [ ] Add regression tests whenever a production bug is fixed.
## Guardrails
- Tests must not mutate the real registry, services, scheduled tasks, package managers, AppX packages, USB disks, ISOs, or user profile state.
- Prefer Pester mocks and temp directories for system-facing code.
- Keep generated `winutil.ps1` ignored and never commit it.
- Run the full gate before marking test work complete:
```powershell
Import-Module Pester -RequiredVersion 5.8.0 -Force
Invoke-Pester -Path 'pester/*.Tests.ps1' -Output Detailed -CI
```
+1
View File
@@ -913,6 +913,7 @@
New-Item \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\EndOfLife\\$Sid\\$Appx\" -Force
Get-AppxPackage -AllUsers \"*Copilot*\" | Remove-AppxPackage -AllUsers
winget uninstall -e --name \"Copilot\" --silent --force --accept-source-agreements 2>$null
Get-AppxPackage -AllUsers Microsoft.MicrosoftOfficeHub | Remove-AppxPackage -AllUsers
if ($Appx) {
+15
View File
@@ -30,3 +30,18 @@ In these cases, the power plan may fail to apply, This is expected behavior on u
Revert start menu tweak stops working starting with **Windows 11 update KB5089573** (released in May 2026).
In this update, Microsoft completely removed the old Start Menu code from Windows, so we aren't able to bring it back.
### Issues with PowerShell 7 or Class not registered Error
Installing PowerShell 7 from the Microsoft Store (MSIX package) is known to cause issues with DISM cmdlets such as `Get-WindowsOptionalFeature` and `Enable-WindowsOptionalFeature`, resulting in a `Class not registered` COM error.
This might also make it so running the "pre-installed app removal" will take a indefinite amount of time
Instead, install PowerShell 7 using one of the following methods:
**winget (recommended):**
```powershell
winget install --id Microsoft.PowerShell --source winget --installer-type wix
```
**Direct MSI from GitHub Releases:** Download the `.msi` installer from the [PowerShell GitHub Releases](https://github.com/PowerShell/PowerShell/releases) page.
For more details see https://github.com/PowerShell/PowerShell/issues/13866
@@ -14,7 +14,7 @@ function Invoke-WinUtilInstallPSProfile {
if (-not (Get-Command pwsh)) {
Write-Host "PowerShell 7 not found. Installing..."
Install-WinUtilWinget
winget install Microsoft.PowerShell --source winget --silent
winget install Microsoft.PowerShell --source winget --installer-type wix --silent
}
wt new-tab pwsh -NoExit -Command "irm https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1 | iex"
@@ -3,7 +3,7 @@ title: "System Tray Battery Percentage"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1251}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1252}
"WPFToggleBatteryPercentage": {
"Content": "System Tray Battery Percentage",
"Description": "Shows numeric battery percentage next to the battery icon in the system tray.",
@@ -3,7 +3,7 @@ title: "Start Menu Bing Search"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1586}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1587}
"WPFToggleBingSearch": {
"Content": "Start Menu Bing Search",
"Description": "Toggles Bing web search results in Windows Search.",
@@ -3,7 +3,7 @@ title: "Dark Theme for Windows"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1269}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1270}
"WPFToggleDarkMode": {
"Content": "Dark Theme for Windows",
"Description": "Dark Mode for the system and applications.",
@@ -3,7 +3,7 @@ title: "BSoD Verbose Mode"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1225}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1226}
"WPFToggleDetailedBSoD": {
"Content": "BSoD Verbose Mode",
"Description": "Gives more information when you blue screen.",
@@ -3,7 +3,7 @@ title: "Lock Screen - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1622}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1623}
"WPFTweaksDisableLockscreen": {
"Content": "Lock Screen - Disable",
"Description": "Skips the lock screen entirely and goes directly to the sign-in screen on boot and wake.",
@@ -3,7 +3,7 @@ title: "Game Mode"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1765}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1766}
"WPFToggleGameMode": {
"Content": "Game Mode",
"Description": "Toggles Windows prioritizes gaming performance by allocating system resources to games.",
@@ -3,7 +3,7 @@ title: "File Explorer Hidden Files"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1339}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1340}
"WPFToggleHiddenFiles": {
"Content": "File Explorer Hidden Files",
"Description": "Reveals hidden files in Explorer.",
@@ -3,7 +3,7 @@ title: "Settings Home Page"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1568}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1569}
"WPFToggleHideSettingsHome": {
"Content": "Settings Home Page",
"Description": "Toggles the Home Page in the Windows Settings app.",
@@ -3,7 +3,7 @@ title: "Logon Screen Acrylic Blur"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1604}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1605}
"WPFToggleLoginBlur": {
"Content": "Logon Screen Acrylic Blur",
"Description": "Toggles the acrylic blur effect on login screen background.",
@@ -3,7 +3,7 @@ title: "Enable Long Paths"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1791}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1792}
"WPFToggleLongPaths": {
"Content": "Enable Long Paths",
"Description": "Toggles support for file paths longer than 260 characters in Explorer.",
@@ -3,7 +3,7 @@ title: "Mouse Acceleration"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1472}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1473}
"WPFToggleMouseAcceleration": {
"Content": "Mouse Acceleration",
"Description": "Makes it so Cursor movement is affected by the speed of your physical mouse movements.",
@@ -3,7 +3,7 @@ title: "Multiplane Overlay"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1446}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1447}
"WPFToggleMultiplaneOverlay": {
"Content": "Multiplane Overlay",
"Description": "Multiplane Overlay compose multiple image layers, which can sometimes cause issues with graphics cards.",
@@ -3,7 +3,7 @@ title: "Microsoft Outlook New Version"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1385}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1386}
"WPFToggleNewOutlook": {
"Content": "Microsoft Outlook New Version",
"Description": "This will ensures the classic Outlook application is used.",
@@ -3,7 +3,7 @@ title: "Num Lock on Startup"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1506}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1507}
"WPFToggleNumLock": {
"Content": "Num Lock on Startup",
"Description": "Toggle the Num Lock key state when your computer starts.",
@@ -3,7 +3,7 @@ title: "S3 Sleep"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1550}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1551}
"WPFToggleS3Sleep": {
"Content": "S3 Sleep",
"Description": "Toggles between Modern Standby and S3 Sleep, which cuts off power to the CPU while continuing to refresh the memory.",
@@ -3,7 +3,7 @@ title: "Scrollbars Always Visible"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1427}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1428}
"WPFToggleScrollbars": {
"Content": "Scrollbars Always Visible",
"Description": "If enabled, scrollbars will always be visible. If disabled, Windows will automatically hide scrollbars when not in use.",
@@ -3,7 +3,7 @@ title: "File Explorer File Extensions"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1311}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1312}
"WPFToggleShowExt": {
"Content": "File Explorer File Extensions",
"Description": "Shows .file extensions in Explorer (.exe, .png, etc.)",
@@ -3,7 +3,7 @@ title: "S0 Sleep Network Connectivity"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1532}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1533}
"WPFToggleStandbyFix": {
"Content": "S0 Sleep Network Connectivity",
"Description": "Toggles network connectivity during S0 Sleep which is low power idle in modern laptops.",
@@ -3,7 +3,7 @@ title: "Start Menu Recommendations"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1639}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1640}
"WPFToggleStartMenuRecommendations": {
"Content": "Start Menu Recommendations",
"Description": "Toggles the recommendations section in the Start Menu. WARNING: This will also disable Windows Spotlight on your Lock Screen as a side effect.",
@@ -3,7 +3,7 @@ title: "Sticky Keys"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1683}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1684}
"WPFToggleStickyKeys": {
"Content": "Sticky Keys",
"Description": "Toggles the Sticky Keys, which activate when clicking shift rapidly.",
@@ -3,7 +3,7 @@ title: "Taskbar Task View Icon"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1747}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1748}
"WPFToggleTaskView": {
"Content": "Taskbar Task View Icon",
"Description": "Toggles the Task View Button in the Taskbar.",
@@ -3,7 +3,7 @@ title: "Taskbar Centered Icons"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1701}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1702}
"WPFToggleTaskbarAlignment": {
"Content": "Taskbar Centered Icons",
"Description": "Toggles the Taskbar alignment either to the left or center.",
@@ -3,7 +3,7 @@ title: "Taskbar Search Icon"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1729}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1730}
"WPFToggleTaskbarSearch": {
"Content": "Taskbar Search Icon",
"Description": "Toggles the Search Button on the Taskbar.",
@@ -3,7 +3,7 @@ title: "Logon Verbose Mode"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1367}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1368}
"WPFToggleVerboseLogon": {
"Content": "Logon Verbose Mode",
"Description": "Show detailed messages during startup/shutdown.",
@@ -3,7 +3,7 @@ title: "Temporary Files - Remove"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1065}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1066}
"WPFTweaksDeleteTempFiles": {
"Content": "Temporary Files - Remove",
"Description": "Erases TEMP Folders.",
@@ -3,7 +3,7 @@ title: "File Explorer Automatic Folder Discovery - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1170}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1171}
"WPFTweaksDisableExplorerAutoDiscovery": {
"Content": "File Explorer Automatic Folder Discovery - Disable",
"Description": "Windows Explorer automatically tries to guess the type of the folder based on its contents, slowing down the browsing experience. WARNING! Will disable File Explorer grouping.",
@@ -3,7 +3,7 @@ title: "Disk Cleanup - Run"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1052}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1053}
"WPFTweaksDiskCleanup": {
"Content": "Disk Cleanup - Run",
"Description": "Runs Disk Cleanup on Drive C: and removes old Windows Updates.",
@@ -3,7 +3,7 @@ title: "Windows Platform Binary Table (WPBT) - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=930}
```json {filename="config/tweaks.json",linenos=inline,linenostart=931}
"WPFTweaksWPBT": {
"Content": "Windows Platform Binary Table (WPBT) - Disable",
"Description": "If enabled, WPBT allows your computer vendor to execute programs at boot time, such as anti-theft software, software drivers, as well as force install software without user consent. Poses potential security risk.",
@@ -3,7 +3,7 @@ title: "Adobe URL Block List - Enable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1010}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1011}
"WPFTweaksBlockAdobeNet": {
"Content": "Adobe URL Block List - Enable",
"Description": "Reduces user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs",
@@ -3,7 +3,7 @@ title: "Background Apps - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1138}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1139}
"WPFTweaksDisableBGapps": {
"Content": "Background Apps - Disable",
"Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Windows 11.",
@@ -3,7 +3,7 @@ title: "Fullscreen Optimizations - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1154}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1155}
"WPFTweaksDisableFSO": {
"Content": "Fullscreen Optimizations - Disable",
"Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen.",
@@ -3,7 +3,7 @@ title: "IPv6 - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1116}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1117}
"WPFTweaksDisableIPv6": {
"Content": "IPv6 - Disable",
"Description": "Disables IPv6.",
@@ -3,7 +3,7 @@ title: "System Tray Notifications & Calendar - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=987}
```json {filename="config/tweaks.json",linenos=inline,linenostart=988}
"WPFTweaksDisableNotifications": {
"Content": "System Tray Notifications & Calendar - Disable",
"Description": "Disables all Notifications INCLUDING Calendar.",
@@ -3,7 +3,7 @@ title: "IPv6 - Set IPv4 as Preferred"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1078}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1079}
"WPFTweaksIPv46": {
"Content": "IPv6 - Set IPv4 as Preferred",
"Description": "Setting the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
@@ -3,7 +3,7 @@ title: "Razer Software Auto-Install - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=946}
```json {filename="config/tweaks.json",linenos=inline,linenostart=947}
"WPFTweaksRazerBlock": {
"Content": "Razer Software Auto-Install - Disable",
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
@@ -3,7 +3,7 @@ title: "Right-Click Menu Previous Layout - Enable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1036}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1037}
"WPFTweaksRightClickMenu": {
"Content": "Right-Click Menu Previous Layout - Enable",
"Description": "Restores the classic context menu when right-clicking in File Explorer, replacing the simplified Windows 11 version.",
@@ -3,7 +3,7 @@ title: "Teredo - Disable"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1094}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1095}
"WPFTweaksTeredo": {
"Content": "Teredo - Disable",
"Description": "Teredo network tunneling is an IPv6 feature that can cause additional latency, but may cause problems with some games.",
@@ -33,6 +33,7 @@ description: ""
New-Item \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\EndOfLife\\$Sid\\$Appx\" -Force
Get-AppxPackage -AllUsers \"*Copilot*\" | Remove-AppxPackage -AllUsers
winget uninstall -e --name \"Copilot\" --silent --force --accept-source-agreements 2>$null
Get-AppxPackage -AllUsers Microsoft.MicrosoftOfficeHub | Remove-AppxPackage -AllUsers
if ($Appx) {
@@ -3,7 +3,7 @@ title: "DNS - Set to:"
description: ""
---
```json {filename="config/tweaks.json",linenos=inline,linenostart=1816}
```json {filename="config/tweaks.json",linenos=inline,linenostart=1817}
"WPFchangedns": {
"Content": "DNS - Set to:",
"category": "z__Advanced Tweaks - CAUTION",
@@ -83,9 +83,9 @@ function Find-AppsByNameOrDescription {
$categoryLabel.Visibility = [Windows.Visibility]::Visible
# Search through apps in this category
$wrapPanel.Children | ForEach-Object {
foreach ($appControl in $wrapPanel.Children) {
# Safely retrieve app entry from hashtable
$appTag = $_.Tag
$appTag = $appControl.Tag
$appEntry = $null
if (-not [string]::IsNullOrWhiteSpace($appTag) -and $sync.configs.applicationsHashtable.ContainsKey($appTag)) {
@@ -99,16 +99,16 @@ function Find-AppsByNameOrDescription {
if ($contentMatch -or $descriptionMatch) {
# Show the App and mark that this category has a match
$_.Visibility = [Windows.Visibility]::Visible
$appControl.Visibility = [Windows.Visibility]::Visible
$categoryHasMatch = $true
}
else {
$_.Visibility = [Windows.Visibility]::Collapsed
$appControl.Visibility = [Windows.Visibility]::Collapsed
}
}
else {
# Hide app if no entry found (data integrity issue)
$_.Visibility = [Windows.Visibility]::Collapsed
$appControl.Visibility = [Windows.Visibility]::Collapsed
}
}
@@ -114,6 +114,7 @@ function Find-TweaksByNameOrDescription {
}
catch {
# Silent catch - UI element may be disposed
$null = $_
}
return
@@ -303,5 +304,6 @@ function Find-TweaksByNameOrDescription {
catch {
# Silent catch - UI elements may be disposed or in unexpected state
# Do not log to terminal as this function is called on every keystroke
$null = $_
}
}
@@ -4,7 +4,7 @@ function Get-WinUtilPackageLogSummary {
[object[]]$Packages,
[Parameter(Mandatory = $true)]
[PackageManagers]$Preference
[string]$Preference
)
@($Packages | ForEach-Object {
@@ -17,7 +17,7 @@ function Get-WinUtilPackageLogSummary {
$packageName = "Unknown package"
}
if ($Preference -eq [PackageManagers]::Choco -and -not [string]::IsNullOrWhiteSpace([string]$package.choco) -and $package.choco -ne "na") {
if ($Preference -eq "Choco" -and -not [string]::IsNullOrWhiteSpace([string]$package.choco) -and $package.choco -ne "na") {
"$packageName (choco: $($package.choco))"
} elseif (-not [string]::IsNullOrWhiteSpace([string]$package.winget) -and $package.winget -ne "na") {
"$packageName (winget: $($package.winget))"
@@ -3,9 +3,9 @@ function Get-WinUtilSelectedPackages {
param(
[Parameter(Mandatory = $true)]
[object] $PackageList,
[Parameter(Mandatory = $true)]
[PackageManagers] $Preference
[string] $Preference
)
if ($PackageList.count -eq 1) {
@@ -14,12 +14,12 @@ function Get-WinUtilSelectedPackages {
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
}
$packages = [System.Collections.Hashtable]::new()
$packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
$packages[[PackageManagers]::Winget] = $packagesWinget
$packages[[PackageManagers]::Choco] = $packagesChoco
$packages = @{
Winget = $packagesWinget
Choco = $packagesChoco
}
function Add-PackageId {
param(
+3 -2
View File
@@ -19,8 +19,9 @@ function Get-WinUtilVariables {
if ($Type -contains $objType) {
Write-Output $psitem
}
} catch {
<#I am here so errors don't get outputted for a couple variables that don't have the .GetType() attribute#>
}
catch {
$null = $_
}
}
return $output
@@ -34,6 +34,5 @@ function Initialize-WinUtilRunspacePool {
)
$sync.runspace.Open()
Write-WinUtilPerformanceCheckpoint -Name "Runspace pool initialized"
return $sync.runspace
}
@@ -16,28 +16,22 @@ function Initialize-WinUtilTabContent {
"Install" {
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
Initialize-WPFUI -targetGridName "appscategory"
Write-WinUtilPerformanceCheckpoint -Name "App navigation UI created"
Initialize-WPFUI -targetGridName "appspanel"
Write-WinUtilPerformanceCheckpoint -Name "Install UI created"
}
"Tweaks" {
Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2
Write-WinUtilPerformanceCheckpoint -Name "Tweaks UI created"
}
"Config" {
Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2
Write-WinUtilPerformanceCheckpoint -Name "Features UI created"
}
"AppX" {
Invoke-WPFUIElements -configVariable $sync.configs.appx -targetGridName "appxpanel" -columncount 2
Write-WinUtilPerformanceCheckpoint -Name "AppX UI created"
}
"Win11 Creator" {
if ($sync.Form -and $sync.Form.Dispatcher) {
$sync.Form.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null
}
Write-WinUtilPerformanceCheckpoint -Name "Win11 ISO tab initialized"
}
}
@@ -6,16 +6,13 @@ function Initialize-WinUtilTaskbarOverlayAssets {
if ($IncludeLogo -and -not $sync["logorender"]) {
$sync["logorender"] = (Invoke-WinUtilAssets -Type "Logo" -Size 90 -Render)
Write-WinUtilPerformanceCheckpoint -Name "Taskbar logo asset rendered"
}
if ($IncludeStatusAssets -and -not $sync["checkmarkrender"]) {
$sync["checkmarkrender"] = (Invoke-WinUtilAssets -Type "checkmark" -Size 512 -Render)
Write-WinUtilPerformanceCheckpoint -Name "Taskbar checkmark asset rendered"
}
if ($IncludeStatusAssets -and -not $sync["warningrender"]) {
$sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render)
Write-WinUtilPerformanceCheckpoint -Name "Taskbar warning asset rendered"
}
}
+4 -12
View File
@@ -1,15 +1,7 @@
function Install-WinUtilChoco {
<#
.SYNOPSIS
Installs Chocolatey if it is not already installed
#>
if ((Test-WinUtilPackageManager -choco) -eq "installed") {
return
if (-not (Get-Command -Name choco)) {
Write-Host "Chocolatey is not installed. Installing now..."
$installScript = Invoke-WebRequest -Uri https://community.chocolatey.org/install.ps1 -UseBasicParsing
Invoke-Command -ScriptBlock ([scriptblock]::Create($installScript.Content))
}
Write-Host "Chocolatey is not installed. Installing now..."
Invoke-WebRequest -Uri https://community.chocolatey.org/install.ps1 -UseBasicParsing | Invoke-Expression
}
@@ -55,8 +55,6 @@ Function Invoke-WinUtilCurrentSystem {
$entry = $sync.configs.tweaks.$Config
$registryKeys = $entry.registry
$serviceKeys = $entry.service
$appxKeys = $entry.appx
$invokeScript = $entry.InvokeScript
$entryType = $entry.Type
if ($registryKeys -or $serviceKeys) {
+17 -16
View File
@@ -1,12 +1,13 @@
function Write-Win11ISOLog {
param([string]$Message)
$ts = (Get-Date).ToString("HH:mm:ss")
$logLine = "[$ts] $Message"
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
$current = $sync["WPFWin11ISOStatusLog"].Text
if ($current -eq "Ready. Please select a Windows 11 ISO to begin.") {
$sync["WPFWin11ISOStatusLog"].Text = "[$ts] $Message"
$sync["WPFWin11ISOStatusLog"].Text = $logLine
} else {
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $Message"
$sync["WPFWin11ISOStatusLog"].Text += "`n$logLine"
}
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
@@ -151,14 +152,9 @@ function Invoke-WinUtilISOModify {
$sync["WPFWin11ISOModifyButton"].IsEnabled = $false
$sync["Win11ISOModifying"] = $true
$existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") |
Where-Object { $_.PSIsContainer } | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$workDir = if ($existingWorkDir) {
Write-Win11ISOLog "Reusing existing temp directory: $($existingWorkDir.FullName)"
$existingWorkDir.FullName
} else {
Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
if (Test-Path $workDir) {
$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')_$(([guid]::NewGuid()).ToString('N').Substring(0, 8))"
}
$autounattendContent = if ($WinUtilAutounattendXml) {
@@ -293,9 +289,11 @@ function Invoke-WinUtilISOModify {
[scriptblock]$Logger
)
$metadataLogger = $Logger
function LogMeta([string]$Message) {
if ($Logger) {
$null = $Logger.Invoke($Message)
if ($metadataLogger) {
$null = $metadataLogger.Invoke($Message)
}
}
@@ -368,8 +366,11 @@ function Invoke-WinUtilISOModify {
Log "ISO contents copied."
SetProgress "Mounting install.wim..." 25
$localWim = Join-Path $isoContents "sources\install.wim"
if (-not (Test-Path $localWim)) { $localWim = Join-Path $isoContents "sources\install.esd" }
$sourceImageFileName = Split-Path $wimPath -Leaf
$localWim = Join-Path $isoContents "sources\$sourceImageFileName"
if (-not (Test-Path $localWim)) {
throw "Copied ISO image file not found: sources\$sourceImageFileName"
}
Set-ItemProperty -Path $localWim -Name IsReadOnly -Value $false
Log "Mounting install.wim (Index ${selectedWimIndex}: $selectedEditionName) at $mountDir..."
@@ -590,10 +591,10 @@ function Invoke-WinUtilISOCleanAndReset {
}
foreach ($d in $allDirs) {
try { Remove-Item -Path $d.FullName -Force } catch {}
try { Remove-Item -Path $d.FullName -Force } catch { Log "WARNING: could not delete $($d.FullName): $_" }
}
try { Remove-Item -Path $workDir -Recurse -Force } catch {}
try { Remove-Item -Path $workDir -Recurse -Force } catch { Log "WARNING: could not delete temp directory ${workDir}: $_" }
if (Test-Path $workDir) {
Log "WARNING: some items could not be deleted in $workDir"
+71 -75
View File
@@ -70,15 +70,11 @@ function Invoke-WinUtilISOScript {
[int]$InstallImageIndex = 1,
[scriptblock]$Log = { param($m) Write-Output $m }
)
$adminSID = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544')
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
function Set-ISOScriptReg {
param ([string]$path, [string]$name, [string]$type, [string]$value)
param ([string]$Path, [string]$Name, [string]$Type, [string]$Value)
try {
& reg add $path /v $name /t $type /d $value /f
& $Log "Set registry value: $path\$name"
& reg add $Path /v $Name /t $Type /d $Value /f
& $Log "Set registry value: $Path\$Name"
} catch {
& $Log "Error setting registry value: $_"
}
@@ -114,7 +110,7 @@ function Invoke-WinUtilISOScript {
& $Logger "boot.wim driver injection complete."
} catch {
& $Logger "Warning: boot.wim driver injection failed: $_"
try { Dismount-WindowsImage -Path $mountDir -Discard } catch {}
try { Dismount-WindowsImage -Path $mountDir -Discard } catch { & $Logger "Warning: could not discard boot.wim mount: $_" }
} finally {
Remove-Item -Path $mountDir -Recurse -Force
}
@@ -330,44 +326,44 @@ Retail
reg load HKLM\zSYSTEM "$ScratchDir\Windows\System32\config\SYSTEM"
& $Log "Bypassing system requirements..."
Set-ISOScriptReg 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassCPUCheck' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassRAMCheck' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassSecureBootCheck' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassStorageCheck' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassTPMCheck' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\MoSetup' 'AllowUpgradesWithUnsupportedTPMOrCPU' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV1' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV2' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV1' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV2' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassCPUCheck' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassRAMCheck' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassSecureBootCheck' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassStorageCheck' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassTPMCheck' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\MoSetup' -Name 'AllowUpgradesWithUnsupportedTPMOrCPU' -Type 'REG_DWORD' -Value '1'
& $Log "Disabling sponsored apps..."
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'OemPreInstalledAppsEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SilentInstalledAppsEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableWindowsConsumerFeatures' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'ContentDeliveryAllowed' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' 'ConfigureStartPins' 'REG_SZ' '{"pinnedList": [{}]}'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'FeatureManagementEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEverEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SoftLandingEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContentEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-310093Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338388Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338389Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338393Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-353694Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-353696Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SystemPaneSuggestionsEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' 'DisablePushToInstall' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' 'DontOfferThroughWUAU' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'OemPreInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'PreInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SilentInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableWindowsConsumerFeatures' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'ContentDeliveryAllowed' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' -Name 'ConfigureStartPins' -Type 'REG_SZ' -Value '{"pinnedList": [{}]}'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'FeatureManagementEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'PreInstalledAppsEverEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SoftLandingEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContentEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-310093Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338388Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338389Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338393Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-353694Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-353696Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SystemPaneSuggestionsEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' -Name 'DisablePushToInstall' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' -Name 'DontOfferThroughWUAU' -Type 'REG_DWORD' -Value '1'
Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\Subscriptions'
Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\SuggestedApps'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableConsumerAccountStateContent' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableCloudOptimizedContent' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableConsumerAccountStateContent' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableCloudOptimizedContent' -Type 'REG_DWORD' -Value '1'
& $Log "Enabling local accounts on OOBE..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' 'BypassNRO' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' -Name 'BypassNRO' -Type 'REG_DWORD' -Value '1'
if ($AutoUnattendXml) {
$preparedAutoUnattendXml = $AutoUnattendXml
@@ -423,62 +419,62 @@ Retail
}
& $Log "Disabling reserved storage..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' 'ShippedWithReserves' 'REG_DWORD' '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' -Name 'ShippedWithReserves' -Type 'REG_DWORD' -Value '0'
& $Log "Disabling BitLocker device encryption..."
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' 'PreventDeviceEncryption' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' -Name 'PreventDeviceEncryption' -Type 'REG_DWORD' -Value '1'
& $Log "Disabling Chat icon..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' 'ChatIcon' 'REG_DWORD' '3'
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' 'TaskbarMn' 'REG_DWORD' '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' -Name 'ChatIcon' -Type 'REG_DWORD' -Value '3'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name 'TaskbarMn' -Type 'REG_DWORD' -Value '0'
& $Log "Disabling OneDrive folder backup..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive' 'DisableFileSyncNGSC' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive' -Name 'DisableFileSyncNGSC' -Type 'REG_DWORD' -Value '1'
& $Log "Disabling telemetry..."
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' 'Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' 'TailoredExperiencesWithDiagnosticDataEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' 'HasAccepted' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' 'Enabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' 'RestrictImplicitInkCollection' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' 'RestrictImplicitTextCollection' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' 'HarvestContacts' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' 'AcceptedPrivacyPolicy' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' 'AllowTelemetry' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' 'Start' 'REG_DWORD' '4'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' -Name 'Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' -Name 'TailoredExperiencesWithDiagnosticDataEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' -Name 'HasAccepted' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' -Name 'Enabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -Name 'RestrictImplicitInkCollection' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -Name 'RestrictImplicitTextCollection' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' -Name 'HarvestContacts' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' -Name 'AcceptedPrivacyPolicy' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' -Name 'AllowTelemetry' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' -Name 'Start' -Type 'REG_DWORD' -Value '4'
& $Log "Preventing installation of DevHome and Outlook..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' 'workCompleted' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate'
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate'
& $Log "Disabling Copilot..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' 'TurnOffWindowsCopilot' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' 'HubsSidebarEnabled' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' 'DisableSearchBoxSuggestions' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' -Name 'TurnOffWindowsCopilot' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' -Name 'HubsSidebarEnabled' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' -Name 'DisableSearchBoxSuggestions' -Type 'REG_DWORD' -Value '1'
& $Log "Disabling Windows Update during OOBE (re-enabled on first logon via FirstLogon.ps1)..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'NoAutoUpdate' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'AUOptions' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'UseWUServer' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'DisableWindowsUpdateAccess' 'REG_DWORD' '1'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'WUServer' 'REG_SZ' 'http://localhost:8080'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'WUStatusServer' 'REG_SZ' 'http://localhost:8080'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' 'workCompleted' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'NoAutoUpdate' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'AUOptions' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'UseWUServer' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'DisableWindowsUpdateAccess' -Type 'REG_DWORD' -Value '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'WUServer' -Type 'REG_SZ' -Value 'http://localhost:8080'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'WUStatusServer' -Type 'REG_SZ' -Value 'http://localhost:8080'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1'
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate'
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config' 'DODownloadMode' 'REG_DWORD' '0'
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\BITS' 'Start' 'REG_DWORD' '4'
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' 'Start' 'REG_DWORD' '4'
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' 'Start' 'REG_DWORD' '4'
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSvc' 'Start' 'REG_DWORD' '4'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config' -Name 'DODownloadMode' -Type 'REG_DWORD' -Value '0'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\BITS' -Name 'Start' -Type 'REG_DWORD' -Value '4'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' -Name 'Start' -Type 'REG_DWORD' -Value '4'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' -Name 'Start' -Type 'REG_DWORD' -Value '4'
Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSvc' -Name 'Start' -Type 'REG_DWORD' -Value '4'
& $Log "Preventing installation of Teams..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' 'DisableInstallation' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' -Name 'DisableInstallation' -Type 'REG_DWORD' -Value '1'
& $Log "Preventing installation of new Outlook..."
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' 'PreventRun' 'REG_DWORD' '1'
Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' -Name 'PreventRun' -Type 'REG_DWORD' -Value '1'
& $Log "Unloading offline registry hives..."
reg unload HKLM\zCOMPONENTS
+1 -1
View File
@@ -180,7 +180,7 @@ function Invoke-WinUtilISOWriteUSB {
Start-Sleep -Seconds 2
Update-Disk -Number $diskNum
try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" } catch {}
try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" } catch { Log "Warning: could not remove existing partition access path: $_" }
$usbLetter = Get-FreeDriveLetter
if (-not $usbLetter) { throw "No free drive letters (D-Z) available to assign to the USB data partition." }
Set-Partition -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -NewDriveLetter $usbLetter
@@ -8,7 +8,7 @@ function Invoke-WinUtilInstallPSProfile {
if (-not (Get-Command pwsh)) {
Write-Host "PowerShell 7 not found. Installing..."
Install-WinUtilWinget
winget install Microsoft.PowerShell --source winget --silent
winget install Microsoft.PowerShell --source winget --installer-type wix --silent
}
wt new-tab pwsh -NoExit -Command "irm https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1 | iex"
+1 -1
View File
@@ -1,4 +1,4 @@
Function Invoke-WinUtilSponsors {
$sponsors = ([regex]::Matches(([regex]::Match((irm https://github.com/sponsors/ChrisTitusTech),'(?s)(?<=Current sponsors).*?(?=Past sponsors)')).Value,'(?<=alt="@)[^"]+')).Value | Where-Object {$_ -ne "ChrisTitusTech"}
$sponsors = ([regex]::Matches(([regex]::Match((Invoke-RestMethod https://github.com/sponsors/ChrisTitusTech),'(?s)(?<=Current sponsors).*?(?=Past sponsors)')).Value,'(?<=alt="@)[^"]+')).Value | Where-Object {$_ -ne "ChrisTitusTech"}
return $sponsors
}
+14 -15
View File
@@ -91,40 +91,39 @@ function Invoke-WinutilThemeChange {
# Retrieve all theme properties from the theme configuration
$themeProperties = $sync.configs.themes.$currentTheme.PSObject.Properties
foreach ($_ in $themeProperties) {
foreach ($themeProperty in $themeProperties) {
# Apply properties that deal with colors
if ($_.Name -like "*color*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "ColorBrush"
if ($themeProperty.Name -like "*color*") {
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "ColorBrush"
# For certain color properties, also set complementary values (e.g., BorderColor -> CBorderColor) This is required because e.g DropShadowEffect requires a <Color> and not a <SolidColorBrush> object
if ($_.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
Set-ThemeResourceProperty -Name "C$($_.Name)" -Value $_.Value -Type "Color"
if ($themeProperty.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
Set-ThemeResourceProperty -Name "C$($themeProperty.Name)" -Value $themeProperty.Value -Type "Color"
}
}
# Apply corner radius properties
elseif ($_.Name -like "*Radius*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "CornerRadius"
elseif ($themeProperty.Name -like "*Radius*") {
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "CornerRadius"
}
# Apply row height properties
elseif ($_.Name -like "*RowHeight*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "GridLength"
elseif ($themeProperty.Name -like "*RowHeight*") {
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "GridLength"
}
# Apply thickness or margin properties
elseif (($_.Name -like "*Thickness*") -or ($_.Name -like "*margin")) {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Thickness"
elseif (($themeProperty.Name -like "*Thickness*") -or ($themeProperty.Name -like "*margin")) {
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "Thickness"
}
# Apply font family properties
elseif ($_.Name -like "*FontFamily*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "FontFamily"
elseif ($themeProperty.Name -like "*FontFamily*") {
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "FontFamily"
}
# Apply any other properties as doubles (numerical values)
else {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Double"
Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "Double"
}
}
}
$sync.preferences.theme = $theme
Set-Preferences -save
Set-WinutilTheme -currentTheme "shared"
switch ($sync.preferences.theme) {
+5 -1
View File
@@ -22,7 +22,11 @@ function Reset-WPFCheckBoxes {
)
$CheckBoxesToCheck = $sync.selectedApps + $sync.selectedTweaks + $sync.selectedFeatures + $sync.selectedAppx
$CheckBoxes = ($sync.GetEnumerator()).where{ $_.Value -is [System.Windows.Controls.CheckBox] -and $_.Name -notlike "WPFToggle*" -and $_.Name -like "$checkboxfilterpattern"}
$CheckBoxes = foreach ($syncEntry in $sync.GetEnumerator()) {
if ($syncEntry.Value -is [System.Windows.Controls.CheckBox] -and $syncEntry.Name -notlike "WPFToggle*" -and $syncEntry.Name -like $checkboxfilterpattern) {
$syncEntry
}
}
foreach ($CheckBox in $CheckBoxes) {
$checkboxName = $CheckBox.Key
-81
View File
@@ -1,81 +0,0 @@
function Set-Preferences{
param(
[switch]$save=$false
)
# TODO delete this function sometime later
function Clean-OldPrefs{
if (Test-Path -Path "$winutildir\LightTheme.ini") {
$sync.preferences.theme = "Light"
Remove-Item -Path "$winutildir\LightTheme.ini"
}
if (Test-Path -Path "$winutildir\DarkTheme.ini") {
$sync.preferences.theme = "Dark"
Remove-Item -Path "$winutildir\DarkTheme.ini"
}
# check old prefs, if its first line has no =, then absorb it as pm
if (Test-Path -Path $iniPath) {
$oldPM = Get-Content $iniPath
if ($oldPM -notlike "*=*") {
$sync.preferences.packagemanager = $oldPM
}
}
if (Test-Path -Path "$winutildir\preferChocolatey.ini") {
$sync.preferences.packagemanager = "Choco"
Remove-Item -Path "$winutildir\preferChocolatey.ini"
}
}
function Save-Preferences{
$ini = ""
foreach($key in $sync.preferences.Keys) {
$pref = "$($key)=$($sync.preferences.$key)"
$ini = $ini + $pref + "`r`n"
}
$ini | Out-File $iniPath
}
function Load-Preferences{
Clean-OldPrefs
if (Test-Path -Path $iniPath) {
$iniData = Get-Content "$winutildir\preferences.ini"
foreach ($line in $iniData) {
if ($line -like "*=*") {
$arr = $line -split "=",-2
$key = $arr[0] -replace "\s",""
$value = $arr[1] -replace "\s",""
$sync.preferences.$key = $value
}
}
}
# write defaults in case preferences dont exist
if ($null -eq $sync.preferences.theme) {
$sync.preferences.theme = "Auto"
}
if ($null -eq $sync.preferences.packagemanager) {
$sync.preferences.packagemanager = "Winget"
}
# convert packagemanager to enum
if ($sync.preferences.packagemanager -eq "Choco") {
$sync.preferences.packagemanager = [PackageManagers]::Choco
}
elseif ($sync.preferences.packagemanager -eq "Winget") {
$sync.preferences.packagemanager = [PackageManagers]::Winget
}
}
$iniPath = "$winutildir\preferences.ini"
if ($save) {
Save-Preferences
}
else {
Load-Preferences
}
}
+17 -4
View File
@@ -12,25 +12,38 @@ function Set-WinUtilDNS {
#>
param($DNSProvider)
if($DNSProvider -eq "Default") {
Write-WinUtilLog -Component "DNS" -Message "DNS provider is Default; no DNS changes applied."
return
}
try {
$Adapters = Get-NetAdapter | Where-Object {$_.Status -eq "Up"}
Write-Host "Ensuring DNS is set to $DNSProvider on the following interfaces:"
Write-Host $($Adapters | Out-String)
Write-WinUtilLog -Component "DNS" -Message "Setting DNS provider to $DNSProvider for $(@($Adapters).Count) active adapter(s)."
if($DNSProvider -ne "DHCP") {
$dns = $sync.configs.dns.$DNSProvider
if($null -eq $dns) {
Write-Warning "DNS provider $DNSProvider was not found in configuration."
Write-WinUtilLog -Level "ERROR" -Component "DNS" -Message "DNS provider $DNSProvider was not found in configuration."
return
}
}
Foreach ($Adapter in $Adapters) {
if($DNSProvider -eq "DHCP") {
Write-WinUtilLog -Component "DNS" -Message "Resetting DNS to DHCP on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex))."
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ResetServerAddresses
netsh interface ip set dnsservers name="$($Adapter.Name)" source=dhcp
netsh interface ipv6 set dnsservers name="$($Adapter.Name)" source=dhcp
} else {
Write-WinUtilLog -Component "DNS" -Message "Setting IPv4 DNS on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex)) to $($sync.configs.dns.$DNSProvider.Primary), $($sync.configs.dns.$DNSProvider.Secondary)."
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ("$($sync.configs.dns.$DNSProvider.Primary)", "$($sync.configs.dns.$DNSProvider.Secondary)")
Write-WinUtilLog -Component "DNS" -Message "Setting IPv6 DNS on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex)) to $($sync.configs.dns.$DNSProvider.Primary6), $($sync.configs.dns.$DNSProvider.Secondary6)."
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ("$($sync.configs.dns.$DNSProvider.Primary6)", "$($sync.configs.dns.$DNSProvider.Secondary6)")
Write-WinUtilLog -Component "DNS" -Message "Setting IPv4 DNS on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex)) to $($dns.Primary), $($dns.Secondary)."
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ($dns.Primary, $dns.Secondary)
Write-WinUtilLog -Component "DNS" -Message "Setting IPv6 DNS on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex)) to $($dns.Primary6), $($dns.Secondary6)."
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ($dns.Primary6, $dns.Secondary6)
}
}
Write-WinUtilLog -Component "DNS" -Message "DNS provider change completed: $DNSProvider"
+7 -5
View File
@@ -14,11 +14,13 @@ function Set-WinUtilProgressbar{
[int]$Percent
)
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $label}
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $label}
if ($percent -lt 5 ) {
$percent = 5 # Ensure the progress bar is not empty, as it looks weird
$progressLabel = $Label
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $progressLabel}
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $progressLabel}
if ($Percent -lt 5 ) {
$Percent = 5 # Ensure the progress bar is not empty, as it looks weird
}
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $percent}
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $Percent}
}
+14 -10
View File
@@ -193,6 +193,7 @@ function Show-CustomDialog {
# Define the Regex to find hyperlinks formatted as HTML <a> tags
$regex = [regex]::new('<a href="([^"]+)">([^<]+)</a>')
$lastPos = 0
$linkHoverBrush = $LinkHoverForegroundColor
# Iterate through each match and add regular text and hyperlinks
foreach ($match in $regex.Matches($Message)) {
@@ -210,20 +211,23 @@ function Show-CustomDialog {
$hyperlink.Foreground = $LinkForegroundColor
$hyperlink.Add_Click({
param($sender, $args)
Start-Process $sender.NavigateUri.AbsoluteUri
param($eventSender, $routedEvent)
$null = $routedEvent
Start-Process $eventSender.NavigateUri.AbsoluteUri
})
$hyperlink.Add_MouseEnter({
param($sender, $args)
$sender.Foreground = $LinkHoverForegroundColor
$sender.FontSize = ($FontSize + ($FontSize / 4))
$sender.FontWeight = "SemiBold"
param($eventSender, $routedEvent)
$null = $routedEvent
$eventSender.Foreground = $linkHoverBrush
$eventSender.FontSize = ($FontSize + ($FontSize / 4))
$eventSender.FontWeight = "SemiBold"
})
$hyperlink.Add_MouseLeave({
param($sender, $args)
$sender.Foreground = $LinkForegroundColor
$sender.FontSize = $FontSize
$sender.FontWeight = "Normal"
param($eventSender, $routedEvent)
$null = $routedEvent
$eventSender.Foreground = $LinkForegroundColor
$eventSender.FontSize = $FontSize
$eventSender.FontWeight = "Normal"
})
$messageTextBlock.Inlines.Add($hyperlink)
+3 -1
View File
@@ -10,11 +10,13 @@ function Show-WPFInstallAppBusy {
param (
$text = "Installing apps..."
)
$overlayText = $text
Invoke-WPFUIThread -ScriptBlock {
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
$sync.InstallAppAreaOverlayText.Text = $text
$sync.InstallAppAreaOverlayText.Text = $overlayText
$sync.InstallAppAreaBorder.IsEnabled = $false
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
}
@@ -15,7 +15,6 @@ function Invoke-WinUtilInstallAppRenderBatch {
function Complete-WinUtilInstallAppRendering {
$sync.InstallAppEntriesRendered = $true
Write-WinUtilPerformanceCheckpoint -Name "Install app entries rendered"
}
function Invoke-WinUtilInstallAppRenderNextBatch {
+1 -1
View File
@@ -7,7 +7,7 @@ function Invoke-WPFAppxRemoval {
$selected = $sync.selectedAppx
$apps = $sync.configs.appxHashtable
$handle = Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock {
Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock {
param($selected, $apps)
$sync.ProcessRunning = $true
+1 -1
View File
@@ -35,7 +35,7 @@ function Invoke-WPFButton {
if ($buttonConfig.InvokeScript -and $buttonConfig.InvokeScript.Count -gt 0) {
foreach ($script in $buttonConfig.InvokeScript) {
if (-not [string]::IsNullOrWhiteSpace($script)) {
Invoke-Expression $script
Invoke-Command -ScriptBlock ([scriptblock]::Create($script)) -ErrorAction Stop
}
}
return
@@ -12,7 +12,7 @@ function Invoke-WPFFeatureInstall {
return
}
$handle = Invoke-WPFRunspace -ScriptBlock {
Invoke-WPFRunspace -ScriptBlock {
$Features = $sync.selectedFeatures
$sync.ProcessRunning = $true
if ($Features.count -eq 1) {
@@ -26,7 +26,7 @@ function Invoke-WPFFeatureInstall {
$Features | ForEach-Object {
Invoke-WinUtilFeatureInstall $_
$X++
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) }
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$Features.Count) }
}
$sync.ProcessRunning = $false
+1 -1
View File
@@ -23,7 +23,7 @@ function Invoke-WPFGetInstalled {
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -ScriptBlock {
param (
[string]$checkbox,
[PackageManagers]$managerPreference
[string]$managerPreference
)
$sync.ProcessRunning = $true
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" }
+3 -3
View File
@@ -24,13 +24,13 @@ function Invoke-WPFInstall {
$packageSummary = Get-WinUtilPackageLogSummary -Packages $PackagesToInstall -Preference $ManagerPreference
Write-WinUtilLog -Component "Install" -Message "Install selected package(s): $($packageSummary -join '; ')"
$handle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
param($PackagesToInstall, $ManagerPreference)
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
$packagesChoco = $packagesSorted[[PackageManagers]::Choco]
$packagesWinget = $packagesSorted['Winget']
$packagesChoco = $packagesSorted['Choco']
Write-WinUtilLog -Component "Install" -Message "Install package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)"
try {
+1
View File
@@ -24,6 +24,7 @@ function Invoke-WPFRunspace {
#>
[CmdletBinding()]
[OutputType([System.IAsyncResult])]
Param (
$ScriptBlock,
$ArgumentList,
+24
View File
@@ -223,6 +223,18 @@ function Invoke-WPFUIElements {
$sync[$entryInfo.Name].Add_Unchecked({
$this.Content = $this.Tag.contentOff
})
if ($null -eq $sync.Buttons) {
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
}
if ($sync.Buttons -notcontains $toggleButton.Name) {
$toggleButton.Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
$sync.Buttons.Add($toggleButton.Name) | Out-Null
}
}
"Combobox" {
@@ -294,6 +306,18 @@ function Invoke-WPFUIElements {
$itemsControl.Items.Add($button) | Out-Null
$sync[$entryInfo.Name] = $button
if ($null -eq $sync.Buttons) {
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
}
if ($sync.Buttons -notcontains $button.Name) {
$button.Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
$sync.Buttons.Add($button.Name) | Out-Null
}
}
"RadioButton" {
+3 -2
View File
@@ -39,8 +39,9 @@ function Invoke-WPFUnInstall {
param($PackagesToUninstall, $ManagerPreference)
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToUninstall -Preference $ManagerPreference
$packagesWinget = $packagesSorted[[PackageManagers]::Winget]
$packagesChoco = $packagesSorted[[PackageManagers]::Choco]
$packagesWinget = $packagesSorted['Winget']
$packagesChoco = $packagesSorted['Choco']
Write-WinUtilLog -Component "Uninstall" -Message "Uninstall package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)"
try {
+4 -2
View File
@@ -57,7 +57,7 @@ function Invoke-WPFtweaksbutton {
}
# The leading "," in the ParameterList is necessary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise
$handle = Invoke-WPFRunspace -ParameterList @(("tweaks", $tweaksToRun), ("dnsProvider", $dnsProvider), ("completedSteps", $completedSteps), ("totalSteps", $totalSteps)) -ScriptBlock {
Invoke-WPFRunspace -ParameterList @(("tweaks", $tweaksToRun), ("dnsProvider", $dnsProvider), ("completedSteps", $completedSteps), ("totalSteps", $totalSteps)) -ScriptBlock {
param($tweaks, $dnsProvider, $completedSteps, $totalSteps)
$sync.ProcessRunning = $true
@@ -70,7 +70,9 @@ function Invoke-WPFtweaksbutton {
}
}
Set-WinUtilDNS -DNSProvider $dnsProvider
if ($dnsProvider -ne "Default") {
Set-WinUtilDNS -DNSProvider $dnsProvider
}
for ($i = 0; $i -lt $tweaks.Count; $i++) {
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($completedSteps / $totalSteps * 100)
-13
View File
@@ -1,13 +0,0 @@
An error has occurred that was not properly handled. Additional information is shown below. The PowerShell process will exit.
Unhandled exception. System.ComponentModel.Win32Exception (1816): Not enough quota is available to process this command.
at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
[process exited with code 3221226525 (0xc000041d)]
You can now close this terminal with Ctrl+D, or press Enter to restart.
+2
View File
@@ -39,9 +39,11 @@ BeforeAll {
process { }
}
function Get-Package {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '', Justification='Test shim is intentionally mocked by Pester.')]
param($Name, $ErrorAction)
}
function Uninstall-Package {
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '', Justification='Test shim is intentionally mocked by Pester.')]
param(
[Parameter(ValueFromPipeline = $true)]
$InputObject,
-7
View File
@@ -32,11 +32,4 @@ Describe "Rendered asset caching" {
$taskbarScript | Should -Match 'Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo \$false -IncludeStatusAssets \$true'
}
It "records individual taskbar overlay render checkpoints" {
$overlayScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTaskbarOverlayAssets.ps1") -Raw
$overlayScript | Should -Match 'Taskbar logo asset rendered'
$overlayScript | Should -Match 'Taskbar checkmark asset rendered'
$overlayScript | Should -Match 'Taskbar warning asset rendered'
}
}
+118
View File
@@ -0,0 +1,118 @@
#===========================================================================
# Tests - DNS
#===========================================================================
BeforeAll {
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
function Get-NetAdapter { }
function Set-DnsClientServerAddress {
param(
$InterfaceIndex,
$ServerAddresses,
[switch]$ResetServerAddresses
)
}
function netsh {
param(
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Arguments
)
}
function Write-WinUtilLog {
param($Message, $Level, $Component)
}
. (Join-Path $script:repoRoot "functions\private\Set-WinUtilDNS.ps1")
}
Describe "Set-WinUtilDNS" {
BeforeEach {
$script:sync = [Hashtable]::Synchronized(@{
configs = @{
dns = @{
Cloudflare = [pscustomobject]@{
Primary = "1.1.1.1"
Secondary = "1.0.0.1"
Primary6 = "2606:4700:4700::1111"
Secondary6 = "2606:4700:4700::1001"
}
}
}
})
Mock Get-NetAdapter {
[pscustomobject]@{
Name = "Ethernet"
Status = "Up"
ifIndex = 7
}
}
Mock Set-DnsClientServerAddress { }
Mock netsh { }
Mock Write-WinUtilLog { }
Mock Write-Warning { }
Mock Write-Host { }
}
AfterEach {
Remove-Variable -Name sync -Scope Script -ErrorAction SilentlyContinue
}
It "sets IPv4 and IPv6 DNS server addresses separately" {
Set-WinUtilDNS -DNSProvider "Cloudflare"
Should -Invoke -CommandName Set-DnsClientServerAddress -Times 1 -Exactly -ParameterFilter {
$InterfaceIndex -eq 7 -and
$ServerAddresses.Count -eq 2 -and
$ServerAddresses[0] -eq "1.1.1.1" -and
$ServerAddresses[1] -eq "1.0.0.1"
}
Should -Invoke -CommandName Set-DnsClientServerAddress -Times 1 -Exactly -ParameterFilter {
$InterfaceIndex -eq 7 -and
$ServerAddresses.Count -eq 2 -and
$ServerAddresses[0] -eq "2606:4700:4700::1111" -and
$ServerAddresses[1] -eq "2606:4700:4700::1001"
}
Should -Invoke -CommandName Set-DnsClientServerAddress -Times 0 -Exactly -ParameterFilter {
$ServerAddresses.Count -eq 4
}
}
It "resets DNS to DHCP for IPv4 and IPv6" {
Set-WinUtilDNS -DNSProvider "DHCP"
Should -Invoke -CommandName Set-DnsClientServerAddress -Times 1 -Exactly -ParameterFilter {
$InterfaceIndex -eq 7 -and
$ResetServerAddresses -eq $true
}
Should -Invoke -CommandName netsh -Times 1 -Exactly -ParameterFilter {
$Arguments[0] -eq "interface" -and
$Arguments[1] -eq "ip" -and
$Arguments[2] -eq "set" -and
$Arguments[3] -eq "dnsservers" -and
$Arguments[4] -eq "name=Ethernet" -and
$Arguments[5] -eq "source=dhcp"
}
Should -Invoke -CommandName netsh -Times 1 -Exactly -ParameterFilter {
$Arguments[0] -eq "interface" -and
$Arguments[1] -eq "ipv6" -and
$Arguments[2] -eq "set" -and
$Arguments[3] -eq "dnsservers" -and
$Arguments[4] -eq "name=Ethernet" -and
$Arguments[5] -eq "source=dhcp"
}
}
It "catches DNS setter failures so the tweak runspace can continue" {
Mock Set-DnsClientServerAddress { throw "DNS failed" }
{ Set-WinUtilDNS -DNSProvider "Cloudflare" } | Should -Not -Throw
Should -Invoke -CommandName Write-WinUtilLog -Times 1 -Exactly -ParameterFilter {
$Level -eq "ERROR" -and
$Component -eq "DNS" -and
$Message -like "Unable to set DNS provider Cloudflare*"
}
}
}
+4 -13
View File
@@ -21,7 +21,7 @@ Describe "Install app rendering startup contract" {
$renderScript | Should -Match 'Dispatcher\.BeginInvoke'
$renderScript | Should -Match 'Invoke-WinUtilInstallAppRenderNextBatch'
$renderScript | Should -Match 'Initialize-InstallAppEntry'
$renderScript | Should -Match 'Install app entries rendered'
$renderScript | Should -Match '\$sync\.InstallAppEntriesRendered = \$true'
}
It "does not use dispatcher timers for deferred install rendering" {
@@ -41,7 +41,6 @@ Describe "Install app rendering startup contract" {
$previousSync = Get-Variable -Name sync -Scope Global -ErrorAction SilentlyContinue
$previousInitializeAppEntry = Get-Item -Path Function:\Initialize-InstallAppEntry -ErrorAction SilentlyContinue
$previousSearch = Get-Item -Path Function:\Find-AppsByNameOrDescription -ErrorAction SilentlyContinue
$previousCheckpoint = Get-Item -Path Function:\Write-WinUtilPerformanceCheckpoint -ErrorAction SilentlyContinue
$errorCountBefore = $global:Error.Count
try {
@@ -52,7 +51,6 @@ Describe "Install app rendering startup contract" {
$global:sync.InstallAppRenderQueue = [System.Collections.Queue]::new()
$renderedApps = [System.Collections.Generic.List[string]]::new()
$checkpoints = [System.Collections.Generic.List[string]]::new()
function global:Initialize-InstallAppEntry {
param($TargetElement, $AppKey)
@@ -65,11 +63,6 @@ Describe "Install app rendering startup contract" {
throw "Search should not run for an empty search box in this test."
}
function global:Write-WinUtilPerformanceCheckpoint {
param([string]$Name)
$checkpoints.Add($Name)
}
$global:sync.InstallAppRenderQueue.Enqueue([pscustomobject]@{ TargetElement = [pscustomobject]@{}; AppKeys = @("AppA", "AppB") })
$global:sync.InstallAppRenderQueue.Enqueue([pscustomobject]@{ TargetElement = [pscustomobject]@{}; AppKeys = @("AppC") })
@@ -80,8 +73,8 @@ Describe "Install app rendering startup contract" {
$closeTimer = New-Object System.Windows.Threading.DispatcherTimer
$closeTimer.Interval = [TimeSpan]::FromMilliseconds(25)
$closeTimer.Add_Tick({
param($sender)
$timer = [System.Windows.Threading.DispatcherTimer]$sender
param($eventSender)
$timer = [System.Windows.Threading.DispatcherTimer]$eventSender
if ($global:sync.InstallAppEntriesRendered -or $timeout.Elapsed.TotalSeconds -gt 5) {
$timer.Stop()
@@ -95,7 +88,6 @@ Describe "Install app rendering startup contract" {
$global:sync.InstallAppEntriesRendered | Should -BeTrue
$global:sync.InstallAppRenderQueue.Count | Should -Be 0
@($renderedApps) | Should -Be @("AppA", "AppB", "AppC")
@($checkpoints) | Should -Contain "Install app entries rendered"
$global:Error.Count | Should -Be $errorCountBefore
} finally {
if ($previousSync) {
@@ -106,8 +98,7 @@ Describe "Install app rendering startup contract" {
foreach ($functionBackup in @(
@{ Name = "Initialize-InstallAppEntry"; Backup = $previousInitializeAppEntry },
@{ Name = "Find-AppsByNameOrDescription"; Backup = $previousSearch },
@{ Name = "Write-WinUtilPerformanceCheckpoint"; Backup = $previousCheckpoint }
@{ Name = "Find-AppsByNameOrDescription"; Backup = $previousSearch }
)) {
if ($functionBackup.Backup) {
Set-Item -Path "Function:\$($functionBackup.Name)" -Value $functionBackup.Backup.ScriptBlock
+14 -24
View File
@@ -5,16 +5,6 @@
BeforeAll {
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
if (-not ("PackageManagers" -as [type])) {
Add-Type @"
public enum PackageManagers
{
Winget,
Choco
}
"@
}
. (Join-Path $script:repoRoot "functions\private\Get-WinUtilPackageLogSummary.ps1")
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFInstall.ps1")
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFUnInstall.ps1")
@@ -26,7 +16,7 @@ public enum PackageManagers
param($ArgumentList, $ParameterList, [scriptblock]$ScriptBlock)
}
function Get-WinUtilSelectedPackages {
param($PackageList, [PackageManagers]$Preference)
param($PackageList, [string]$Preference)
}
function Show-WPFInstallAppBusy {
param($text)
@@ -82,7 +72,7 @@ public enum PackageManagers
ProcessRunning = $ProcessRunning
selectedApps = $selectedApps
preferences = [pscustomobject]@{
packagemanager = [PackageManagers]::Winget
packagemanager = "Winget"
}
configs = @{
applicationsHashtable = $applications
@@ -97,15 +87,15 @@ public enum PackageManagers
)
$packages = @{}
$packages[[PackageManagers]::Winget] = [System.Collections.Generic.List[string]]::new()
$packages[[PackageManagers]::Choco] = [System.Collections.Generic.List[string]]::new()
$packages["Winget"] = [System.Collections.Generic.List[string]]::new()
$packages["Choco"] = [System.Collections.Generic.List[string]]::new()
foreach ($package in $Winget) {
$null = $packages[[PackageManagers]::Winget].Add($package)
$null = $packages["Winget"].Add($package)
}
foreach ($package in $Choco) {
$null = $packages[[PackageManagers]::Choco].Add($package)
$null = $packages["Choco"].Add($package)
}
$packages
@@ -145,7 +135,7 @@ Describe "Invoke-WPFInstall entrypoint" {
@($ParameterList[0][1]).Count -eq 1 -and
@($ParameterList[0][1])[0].winget -eq "Git.Git" -and
$ParameterList[1][0] -eq "ManagerPreference" -and
$ParameterList[1][1] -eq [PackageManagers]::Winget
$ParameterList[1][1] -eq "Winget"
}
Should -Invoke -CommandName Show-WinUtilMessage -Times 0 -Exactly
Should -Invoke -CommandName Write-WinUtilLog -Times 1 -Exactly -ParameterFilter {
@@ -217,10 +207,10 @@ Describe "Invoke-WPFInstall runspace body" {
It "installs split winget and choco packages and cleans up on success" {
Invoke-WPFInstall
& $script:capturedInstallScriptBlock -PackagesToInstall @($script:package) -ManagerPreference ([PackageManagers]::Winget)
& $script:capturedInstallScriptBlock -PackagesToInstall @($script:package) -ManagerPreference "Winget"
Should -Invoke -CommandName Get-WinUtilSelectedPackages -Times 1 -Exactly -ParameterFilter {
@($PackageList).Count -eq 1 -and $Preference -eq [PackageManagers]::Winget
@($PackageList).Count -eq 1 -and $Preference -eq "Winget"
}
Should -Invoke -CommandName Show-WPFInstallAppBusy -Times 1 -Exactly -ParameterFilter {
$text -eq "Installing apps..."
@@ -245,7 +235,7 @@ Describe "Invoke-WPFInstall runspace body" {
Invoke-WPFInstall
& $script:capturedInstallScriptBlock -PackagesToInstall @($script:package) -ManagerPreference ([PackageManagers]::Winget)
& $script:capturedInstallScriptBlock -PackagesToInstall @($script:package) -ManagerPreference "Winget"
Should -Invoke -CommandName Hide-WPFInstallAppBusy -Times 1 -Exactly
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
@@ -298,7 +288,7 @@ Describe "Invoke-WPFUnInstall entrypoint" {
@($ParameterList[0][1]).Count -eq 1 -and
@($ParameterList[0][1])[0].winget -eq "Git.Git" -and
$ParameterList[1][0] -eq "ManagerPreference" -and
$ParameterList[1][1] -eq [PackageManagers]::Winget
$ParameterList[1][1] -eq "Winget"
}
Should -Invoke -CommandName Write-WinUtilLog -Times 1 -Exactly -ParameterFilter {
$Component -eq "Uninstall" -and
@@ -374,10 +364,10 @@ Describe "Invoke-WPFUnInstall runspace body" {
It "uninstalls split winget and choco packages and cleans up on success" {
Invoke-WPFUnInstall -PackagesToUninstall @($script:package)
& $script:capturedUninstallScriptBlock -PackagesToUninstall @($script:package) -ManagerPreference ([PackageManagers]::Winget)
& $script:capturedUninstallScriptBlock -PackagesToUninstall @($script:package) -ManagerPreference "Winget"
Should -Invoke -CommandName Get-WinUtilSelectedPackages -Times 1 -Exactly -ParameterFilter {
@($PackageList).Count -eq 1 -and $Preference -eq [PackageManagers]::Winget
@($PackageList).Count -eq 1 -and $Preference -eq "Winget"
}
Should -Invoke -CommandName Show-WPFInstallAppBusy -Times 1 -Exactly -ParameterFilter {
$text -eq "Uninstalling apps..."
@@ -400,7 +390,7 @@ Describe "Invoke-WPFUnInstall runspace body" {
Invoke-WPFUnInstall -PackagesToUninstall @($script:package)
& $script:capturedUninstallScriptBlock -PackagesToUninstall @($script:package) -ManagerPreference ([PackageManagers]::Winget)
& $script:capturedUninstallScriptBlock -PackagesToUninstall @($script:package) -ManagerPreference "Winget"
Should -Invoke -CommandName Hide-WPFInstallAppBusy -Times 1 -Exactly
Should -Invoke -CommandName Invoke-WPFUIThread -Times 1 -Exactly -ParameterFilter {
+9 -4
View File
@@ -11,9 +11,6 @@ BeforeAll {
function Initialize-WPFUI {
param([string]$TargetGridName)
}
function Write-WinUtilPerformanceCheckpoint {
param([string]$Name)
}
function Invoke-WinUtilISOCheckExistingWork { }
. (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTabContent.ps1")
@@ -32,7 +29,6 @@ Describe "Initialize-WinUtilTabContent" {
Mock Invoke-WPFUIElements { }
Mock Initialize-WPFUI { }
Mock Write-WinUtilPerformanceCheckpoint { }
}
AfterEach {
@@ -91,4 +87,13 @@ Describe "Startup lazy tab wiring" {
$tabScript | Should -Match 'Initialize-WinUtilTabContent -TabName \$sync\.currentTab'
}
It "binds generated button clicks when lazy panels are rendered" {
$rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw
$mainScript = Get-Content -Path (Join-Path $script:repoRoot "scripts\main.ps1") -Raw
$rendererScript | Should -Match '(?s)"Button"\s*\{.*\$button\.Add_Click\(\{.*Invoke-WPFButton \$Sender\.name'
$rendererScript | Should -Match '\$sync\.Buttons\.Add\(\$button\.Name\)'
$mainScript | Should -Match '\$sync\.Buttons -notcontains \$psitem'
}
}
+15 -25
View File
@@ -5,16 +5,6 @@
BeforeAll {
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
if (-not ("PackageManagers" -as [type])) {
Add-Type @"
public enum PackageManagers
{
Winget,
Choco
}
"@
}
. (Join-Path $script:repoRoot "functions\private\Get-WinUtilSelectedPackages.ps1")
. (Join-Path $script:repoRoot "functions\private\Test-WinUtilPackageManager.ps1")
. (Join-Path $script:repoRoot "functions\private\Install-WinUtilProgramWinget.ps1")
@@ -35,10 +25,10 @@ Describe "Get-WinUtilSelectedPackages" {
[pscustomobject]@{ winget = "VideoLAN.VLC"; choco = "vlc" }
)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference ([PackageManagers]::Winget)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference "Winget"
(@($result[[PackageManagers]::Winget]) -join "|") | Should -Be "Git.Git|VideoLAN.VLC"
@($result[[PackageManagers]::Choco]).Count | Should -Be 0
(@($result["Winget"]) -join "|") | Should -Be "Git.Git|VideoLAN.VLC"
@($result["Choco"]).Count | Should -Be 0
}
It "uses choco IDs and falls back to winget for na or missing choco IDs" {
@@ -48,10 +38,10 @@ Describe "Get-WinUtilSelectedPackages" {
[pscustomobject]@{ winget = "Mozilla.Firefox" }
)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference ([PackageManagers]::Choco)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference "Choco"
(@($result[[PackageManagers]::Choco]) -join "|") | Should -Be "git"
(@($result[[PackageManagers]::Winget]) -join "|") | Should -Be "VideoLAN.VLC|Mozilla.Firefox"
(@($result["Choco"]) -join "|") | Should -Be "git"
(@($result["Winget"]) -join "|") | Should -Be "VideoLAN.VLC|Mozilla.Firefox"
}
It "skips blank, na, and missing package IDs" {
@@ -62,10 +52,10 @@ Describe "Get-WinUtilSelectedPackages" {
[pscustomobject]@{ winget = " " }
)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference ([PackageManagers]::Winget)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference "Winget"
@($result[[PackageManagers]::Winget]).Count | Should -Be 0
@($result[[PackageManagers]::Choco]).Count | Should -Be 0
@($result["Winget"]).Count | Should -Be 0
@($result["Choco"]).Count | Should -Be 0
}
It "deduplicates package IDs" {
@@ -75,17 +65,17 @@ Describe "Get-WinUtilSelectedPackages" {
[pscustomobject]@{ winget = "VideoLAN.VLC"; choco = "vlc" }
)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference ([PackageManagers]::Choco)
$result = Get-WinUtilSelectedPackages -PackageList $packages -Preference "Choco"
(@($result[[PackageManagers]::Choco]) -join "|") | Should -Be "git|vlc"
@($result[[PackageManagers]::Winget]).Count | Should -Be 0
(@($result["Choco"]) -join "|") | Should -Be "git|vlc"
@($result["Winget"]).Count | Should -Be 0
}
It "returns empty package lists for an empty selection" {
$result = Get-WinUtilSelectedPackages -PackageList @() -Preference ([PackageManagers]::Winget)
$result = Get-WinUtilSelectedPackages -PackageList @() -Preference "Winget"
@($result[[PackageManagers]::Winget]).Count | Should -Be 0
@($result[[PackageManagers]::Choco]).Count | Should -Be 0
@($result["Winget"]).Count | Should -Be 0
@($result["Choco"]).Count | Should -Be 0
}
}
-116
View File
@@ -1,116 +0,0 @@
#===========================================================================
# Tests - Performance tracing
#===========================================================================
BeforeAll {
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
. (Join-Path $script:repoRoot "functions\private\Write-WinUtilLog.ps1")
. (Join-Path $script:repoRoot "tools\perf\Test-WinUtilPerformanceTrace.ps1")
. (Join-Path $script:repoRoot "tools\perf\Write-WinUtilPerformanceCheckpoint.ps1")
. (Join-Path $script:repoRoot "tools\perf\Start-WinUtilPerformanceTrace.ps1")
. (Join-Path $script:repoRoot "tools\perf\Stop-WinUtilPerformanceTrace.ps1")
}
AfterAll {
& (Join-Path $script:repoRoot "Compile.ps1")
}
Describe "WinUtil performance tracing helpers" {
BeforeEach {
$script:originalPerfEnv = $env:WINUTIL_PERF_LOG
Remove-Item Env:\WINUTIL_PERF_LOG -ErrorAction SilentlyContinue
$script:sync = [Hashtable]::Synchronized(@{})
}
AfterEach {
if ($null -eq $script:originalPerfEnv) {
Remove-Item Env:\WINUTIL_PERF_LOG -ErrorAction SilentlyContinue
} else {
$env:WINUTIL_PERF_LOG = $script:originalPerfEnv
}
Remove-Variable -Name sync -Scope Script -ErrorAction SilentlyContinue
Remove-Variable -Name originalPerfEnv -Scope Script -ErrorAction SilentlyContinue
}
It "is disabled by default" {
Test-WinUtilPerformanceTrace | Should -BeFalse
}
It "can be enabled by environment variable" {
$env:WINUTIL_PERF_LOG = "1"
Test-WinUtilPerformanceTrace | Should -BeTrue
}
It "writes startup checkpoints through the normal WinUtil log helper" {
$env:WINUTIL_PERF_LOG = "1"
Mock Write-WinUtilLog { }
Start-WinUtilPerformanceTrace
Write-WinUtilPerformanceCheckpoint -Name "XAML loaded"
Stop-WinUtilPerformanceTrace
Should -Invoke -CommandName Write-WinUtilLog -Times 3 -Exactly -ParameterFilter {
$Component -eq "StartupPerf" -and $Level -eq "DEBUG"
}
Should -Invoke -CommandName Write-WinUtilLog -Times 1 -Exactly -ParameterFilter {
$Message -like "XAML loaded:*"
}
}
}
Describe "Startup performance checkpoints" {
It "keeps performance tracing out of normal compiled output" {
& (Join-Path $script:repoRoot "Compile.ps1")
$compiledScript = Get-Content -Path (Join-Path $script:repoRoot "winutil.ps1") -Raw
$compiledScript | Should -Not -Match "Test-WinUtilPerformanceTrace"
$compiledScript | Should -Not -Match "Start-WinUtilPerformanceTrace"
$compiledScript | Should -Not -Match "Write-WinUtilPerformanceCheckpoint"
$compiledScript | Should -Not -Match "Stop-WinUtilPerformanceTrace"
$compiledScript | Should -Not -Match "PerformanceTraceEnabled"
}
It "adds config-load checkpoints only to trace compiled output" {
$compileScript = Get-Content -Path (Join-Path $script:repoRoot "Compile.ps1") -Raw
$compileScript | Should -Match '\[switch\]\$Trace'
$compileScript | Should -Match "Start-WinUtilPerformanceTrace"
$compileScript | Should -Match "Config load start"
$compileScript | Should -Match "Config load complete"
$compileScript | Should -Match "Config .* loaded"
& (Join-Path $script:repoRoot "Compile.ps1") -Trace
$compiledScript = Get-Content -Path (Join-Path $script:repoRoot "winutil.ps1") -Raw
$compiledScript | Should -Match "function Test-WinUtilPerformanceTrace"
$compiledScript | Should -Match '\$sync\.PerformanceTraceEnabled = \$true'
$compiledScript | Should -Match "Config load start"
$compiledScript | Should -Match "Config load complete"
}
It "adds runtime checkpoints for startup hotspots" {
$mainScript = Get-Content -Path (Join-Path $script:repoRoot "scripts\main.ps1") -Raw
$lazyTabScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTabContent.ps1") -Raw
$runspaceScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilRunspacePool.ps1") -Raw
$overlayScript = Get-Content -Path (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilTaskbarOverlayAssets.ps1") -Raw
$startupText = "$mainScript`n$lazyTabScript`n$runspaceScript`n$overlayScript"
foreach ($checkpoint in @(
"Runspace pool initialized",
"XAML loaded",
"Theme applied",
"Install UI created",
"Tweaks UI created",
"Features UI created",
"AppX UI created",
"Taskbar logo asset rendered",
"First content rendered"
)) {
$startupText | Should -Match ([regex]::Escape($checkpoint))
}
}
}
+2 -92
View File
@@ -5,16 +5,6 @@
BeforeAll {
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
if (-not ("PackageManagers" -as [type])) {
Add-Type @"
public enum PackageManagers
{
Winget,
Choco
}
"@
}
if (-not ("Windows.Media.SolidColorBrush" -as [type])) {
Add-Type @"
namespace Windows.Media
@@ -139,7 +129,6 @@ namespace System.Windows
"@
}
. (Join-Path $script:repoRoot "functions\private\Set-Preferences.ps1")
. (Join-Path $script:repoRoot "functions\private\Invoke-WinutilThemeChange.ps1")
function Get-WinUtilToggleStatus {
@@ -196,84 +185,6 @@ namespace System.Windows
}
}
Describe "Set-Preferences" {
AfterEach {
if ($script:testRoot -and (Test-Path $script:testRoot)) {
Remove-Item -Path $script:testRoot -Recurse -Force -ErrorAction SilentlyContinue
}
$script:testRoot = $null
Remove-WinUtilPreferenceGlobals
}
It "loads default preferences when no preferences file exists" {
$script:testRoot = New-WinUtilPreferencesTestRoot
$global:winutildir = $script:testRoot
New-WinUtilPreferenceSync
Set-Preferences
$script:sync.preferences.theme | Should -Be "Auto"
$script:sync.preferences.packagemanager | Should -Be ([PackageManagers]::Winget)
}
It "loads saved preferences and converts the package manager to an enum" {
$script:testRoot = New-WinUtilPreferencesTestRoot
$global:winutildir = $script:testRoot
New-WinUtilPreferenceSync
Set-Content -Path (Join-Path $script:testRoot "preferences.ini") -Value @(
"theme = Dark"
"packagemanager = Choco"
)
Set-Preferences
$script:sync.preferences.theme | Should -Be "Dark"
$script:sync.preferences.packagemanager | Should -Be ([PackageManagers]::Choco)
}
It "saves current preferences to preferences.ini" {
$script:testRoot = New-WinUtilPreferencesTestRoot
$global:winutildir = $script:testRoot
New-WinUtilPreferenceSync -Preferences @{
theme = "Light"
packagemanager = [PackageManagers]::Winget
}
Set-Preferences -save
$preferencesText = Get-Content -Path (Join-Path $script:testRoot "preferences.ini") -Raw
$preferencesText | Should -Match "theme=Light"
$preferencesText | Should -Match "packagemanager=Winget"
}
It "absorbs legacy preference files and removes old markers" {
$script:testRoot = New-WinUtilPreferencesTestRoot
$global:winutildir = $script:testRoot
New-WinUtilPreferenceSync
Set-Content -Path (Join-Path $script:testRoot "LightTheme.ini") -Value ""
Set-Content -Path (Join-Path $script:testRoot "preferChocolatey.ini") -Value ""
Set-Preferences
$script:sync.preferences.theme | Should -Be "Light"
$script:sync.preferences.packagemanager | Should -Be ([PackageManagers]::Choco)
Test-Path (Join-Path $script:testRoot "LightTheme.ini") | Should -BeFalse
Test-Path (Join-Path $script:testRoot "preferChocolatey.ini") | Should -BeFalse
}
It "absorbs old package manager preferences stored without a key" {
$script:testRoot = New-WinUtilPreferencesTestRoot
$global:winutildir = $script:testRoot
New-WinUtilPreferenceSync
Set-Content -Path (Join-Path $script:testRoot "preferences.ini") -Value "Choco"
Set-Preferences
$script:sync.preferences.theme | Should -Be "Auto"
$script:sync.preferences.packagemanager | Should -Be ([PackageManagers]::Choco)
}
}
Describe "Invoke-WinutilThemeChange" {
AfterEach {
if ($script:testRoot -and (Test-Path $script:testRoot)) {
@@ -283,7 +194,7 @@ Describe "Invoke-WinutilThemeChange" {
Remove-WinUtilPreferenceGlobals
}
It "applies shared and selected theme resources, saves the preference, and updates the theme button" {
It "applies shared and selected theme resources, keeps the preference in memory, and updates the theme button" {
$script:testRoot = New-WinUtilPreferencesTestRoot
$global:winutildir = $script:testRoot
New-WinUtilPreferenceSync
@@ -297,8 +208,7 @@ Describe "Invoke-WinutilThemeChange" {
$script:sync.Form.Resources.ContainsKey("CBorderColor") | Should -BeTrue
$script:sync.Form.ThemeButton.Content | Should -Be ([string][char]0xE708)
$preferencesText = Get-Content -Path (Join-Path $script:testRoot "preferences.ini") -Raw
$preferencesText | Should -Match "theme=Dark"
Test-Path -Path (Join-Path $script:testRoot "preferences.ini") | Should -BeFalse
}
It "uses the system dark-mode toggle when Auto theme is selected" {
-6
View File
@@ -12,9 +12,6 @@ Describe "Initialize-WinUtilRunspacePool" {
BeforeEach {
$script:sync = [Hashtable]::Synchronized(@{})
$script:PARAM_OFFLINE = $false
function Write-WinUtilPerformanceCheckpoint { param($Name) }
Mock Write-WinUtilPerformanceCheckpoint { }
}
AfterEach {
@@ -29,9 +26,6 @@ Describe "Initialize-WinUtilRunspacePool" {
$firstPool.RunspacePoolStateInfo.State | Should -Be ([System.Management.Automation.Runspaces.RunspacePoolState]::Opened)
[object]::ReferenceEquals($firstPool, $secondPool) | Should -BeTrue
Should -Invoke -CommandName Write-WinUtilPerformanceCheckpoint -Times 1 -Exactly -ParameterFilter {
$Name -eq "Runspace pool initialized"
}
}
It "closes and removes the active runspace pool" {
-2
View File
@@ -20,8 +20,6 @@ BeforeAll {
$initialSessionState.Variables.Add($syncVariable)
$script:sync.runspace = [runspacefactory]::CreateRunspacePool(1, 2, $initialSessionState, $Host)
$script:sync.runspace.Open()
function Write-WinUtilPerformanceCheckpoint { param($Name) }
}
function script:Clear-WinUtilRunspaceTestContext {
-2
View File
@@ -208,8 +208,6 @@ Describe "Runspace sanity" {
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFRunspace.ps1")
. (Join-Path $script:repoRoot "functions\private\Close-WinUtilRunspacePool.ps1")
. (Join-Path $script:repoRoot "functions\private\Initialize-WinUtilRunspacePool.ps1")
function Write-WinUtilPerformanceCheckpoint { param($Name) }
}
It "returns a single async handle and runs a scriptblock with arguments in the shared runspace pool" {
+22
View File
@@ -35,6 +35,7 @@ Describe "Win11 Creator setup media" {
return $functionAst.Extent.Text
}
$script:modifyFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Invoke-WinUtilISOModify"
$script:editionIdFunction = Get-WinUtilFunctionText -Path $script:isoWorkflowPath -FunctionName "Get-WinUtilEditionIdFromName"
$script:addDriversFunction = Get-WinUtilFunctionText -Path $script:isoScriptPath -FunctionName "Add-DriversToImage"
$script:answerFileChildElementFunction = Get-WinUtilFunctionText -Path $script:isoScriptPath -FunctionName "Get-WinUtilISOScriptChildElement"
@@ -69,6 +70,27 @@ Describe "Win11 Creator setup media" {
}
}
It "starts each new ISO modification in a fresh working directory" {
foreach ($expectedText in @(
'$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format ''yyyyMMdd_HHmmss'')"',
'$workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format ''yyyyMMdd_HHmmss'')_$(([guid]::NewGuid()).ToString(''N'').Substring(0, 8))"'
)) {
$script:modifyFunction | Should -Match ([regex]::Escape($expectedText))
}
$script:modifyFunction | Should -Not -Match ([regex]::Escape("Reusing existing temp directory"))
}
It "mounts the copied image file that was verified from the ISO" {
foreach ($expectedText in @(
'$sourceImageFileName = Split-Path $wimPath -Leaf',
'$localWim = Join-Path $isoContents "sources\$sourceImageFileName"',
'Copied ISO image file not found: sources\$sourceImageFileName'
)) {
$script:modifyFunction | Should -Match ([regex]::Escape($expectedText))
}
}
It "maps Windows edition names to setup edition IDs" {
. ([scriptblock]::Create($script:editionIdFunction))
+20 -47
View File
@@ -20,32 +20,6 @@ CCC::::::::::::C T:::::::::T T:::::::::T
=====Windows Toolbox=====
"@
# Create enums
Add-Type @"
public enum PackageManagers
{
Winget,
Choco
}
"@
# Create classes for different exceptions
class WingetFailedInstall : Exception {
[string]$additionalData
WingetFailedInstall($Message) : base($Message) {}
}
class ChocoFailedInstall : Exception {
[string]$additionalData
ChocoFailedInstall($Message) : base($Message) {}
}
class GenericException : Exception {
[string]$additionalData
GenericException($Message) : base($Message) {}
}
# Load the configuration files
$sync.configs.applicationsHashtable = @{}
@@ -57,10 +31,8 @@ $sync.configs.appxHashtable = @{}
$sync.configs.appx.PSObject.Properties | ForEach-Object {
$sync.configs.appxHashtable[$_.Name] = $_.Value
}
Write-WinUtilPerformanceCheckpoint -Name "Config hashtables initialized"
Set-Preferences
Write-WinUtilPerformanceCheckpoint -Name "Preferences loaded"
$sync.preferences.theme = "Auto"
$sync.preferences.packagemanager = "Winget"
if ($Preset) {
Initialize-WinUtilRunspacePool | Out-Null
@@ -101,7 +73,6 @@ $reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
$sync["Form"] = [Windows.Markup.XamlReader]::Load( $reader )
$readerOperationSuccessful = $true
Write-WinUtilPerformanceCheckpoint -Name "XAML loaded"
} catch [System.Management.Automation.MethodInvocationException] {
Write-Host "We ran into a problem with the XAML code. Check the syntax for this control..." -ForegroundColor Red
Write-Host $error[0].Exception.Message -ForegroundColor Red
@@ -136,6 +107,7 @@ $sync.Form.Add_Loaded({
[System.IntPtr]$lParam,
[ref]$handled
)
$null = $hwnd, $wParam, $lParam
# Check for the Event WM_SETTINGCHANGE (0x1001A) and validate that Button shows the icon for "Auto" => [char]0xF08C
if (($msg -eq 0x001A) -and $sync.ThemeButton.Content -eq [char]0xF08C) {
$currentTime = [datetime]::Now
@@ -150,7 +122,6 @@ $sync.Form.Add_Loaded({
})
Invoke-WinutilThemeChange -theme $sync.preferences.theme
Write-WinUtilPerformanceCheckpoint -Name "Theme applied"
# Build only the default tab before first paint; other tabs initialize on first activation.
@@ -166,14 +137,11 @@ Initialize-WinUtilTabContent -TabName "Install"
$xaml.SelectNodes("//*[@Name]") | ForEach-Object {$sync["$("$($psitem.Name)")"] = $sync["Form"].FindName($psitem.Name)}
#Persist Package Manager preference across winutil restarts
$sync.ChocoRadioButton.Add_Checked({
$sync.preferences.packagemanager = [PackageManagers]::Choco
Set-Preferences -save
$sync.preferences.packagemanager = "Choco"
})
$sync.WingetRadioButton.Add_Checked({
$sync.preferences.packagemanager = [PackageManagers]::Winget
Set-Preferences -save
$sync.preferences.packagemanager = "Winget"
})
switch ($sync.preferences.packagemanager) {
@@ -184,17 +152,23 @@ switch ($sync.preferences.packagemanager) {
$sync.keys | ForEach-Object {
if($sync.$psitem) {
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "ToggleButton") {
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
if ($sync.Buttons -notcontains $psitem) {
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
$sync.Buttons.Add($psitem) | Out-Null
}
}
if($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "Button") {
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
if ($sync.Buttons -notcontains $psitem) {
$sync["$psitem"].Add_Click({
[System.Object]$Sender = $args[0]
Invoke-WPFButton $Sender.name
})
$sync.Buttons.Add($psitem) | Out-Null
}
}
if ($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "TextBlock") {
@@ -221,7 +195,6 @@ Set-WinUtilTaskbaritem -state "None"
$sync["Form"].title = $sync["Form"].title + " " + $sync.version
# Set the commands that will run when the form is closed
$sync["Form"].Add_Closing({
Stop-WinUtilPerformanceTrace -Name "Window closing"
Close-WinUtilRunspacePool
[System.GC]::Collect()
})
@@ -290,7 +263,6 @@ $sync["Form"].Add_Deactivated({
})
$sync["Form"].Add_ContentRendered({
Write-WinUtilPerformanceCheckpoint -Name "First content rendered"
# Load the Windows Forms assembly
Add-Type -AssemblyName System.Windows.Forms
$primaryScreen = [System.Windows.Forms.Screen]::PrimaryScreen
@@ -378,6 +350,7 @@ $sync["SearchBar"].Add_TextChanged({
$sync["Form"].Add_Loaded({
param($e)
$null = $e
$sync.Form.MinWidth = "1000"
$sync["Form"].MaxWidth = [Double]::PositiveInfinity
$sync["Form"].MaxHeight = [Double]::PositiveInfinity
+2 -14
View File
@@ -55,13 +55,8 @@ if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]:
break
}
# Load DLLs
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Windows.Forms
# Variable to sync between runspaces
$sync = [Hashtable]::Synchronized(@{})
$sync.PSScriptRoot = $PSScriptRoot
$sync.version = "#{replaceme}"
$sync.configs = @{}
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
@@ -73,22 +68,15 @@ $sync.selectedTweaks = [System.Collections.Generic.List[string]]::new()
$sync.selectedToggles = [System.Collections.Generic.List[string]]::new()
$sync.selectedFeatures = [System.Collections.Generic.List[string]]::new()
$sync.currentTab = "Install"
$sync.selectedAppsStackPanel
$sync.selectedAppsPopup
$dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
# Set the path for the winutil directory
$winutildir = "$env:LocalAppData\winutil"
New-Item $winutildir -ItemType Directory -Force | Out-Null
$sync.winutildir = $winutildir
$logdir = "$winutildir\logs"
New-Item $logdir -ItemType Directory -Force | Out-Null
$sync.logPath = "$logdir\winutil_$dateTime.log"
$sync.transcriptPath = $sync.logPath
Start-Transcript -Path $sync.logPath -Append -NoClobber | Out-Null
# Set PowerShell window title
$Host.UI.RawUI.WindowTitle = "WinUtil (Admin)"
clear-host
$Host.UI.RawUI.WindowTitle = "WinUtil"
Clear-Host
-66
View File
@@ -1,66 +0,0 @@
# Speed TODO
WinUtil currently does too much work before the first GUI paint. Work from the top down: measure first, improve perceived launch time next, then clean up deeper execution/runspace paths.
## P0 - Measure First
- [x] Add temporary startup timing checkpoints with `System.Diagnostics.Stopwatch`.
- [x] Measure config embedding/load, runspace pool initialization, XAML load, theme application, install UI creation, tweaks UI creation, feature UI creation, AppX UI creation, and asset rendering.
- [x] Record baseline launch timing on a clean run and a warm run.
- [x] Keep timing output in the existing WinUtil log/transcript path.
- [x] Remove or gate temporary timing noise after the optimization work is validated.
## P1 - Faster First Paint
- [x] Show the main window before building every non-visible panel.
- [x] Build only the default visible tab during startup.
- [x] Move Tweaks, Features, AppX, and Win11 ISO tab initialization to first tab activation.
- [x] Add one-time guards so each lazy tab initializes only once.
- [x] Preserve current behavior for `-Preset` and `-Config` automation paths.
## P2 - Install Tab Rendering
- [x] Reduce up-front creation of all install app entries.
- [x] Keep category/app grouping as pure data before touching WPF controls.
- [x] Create WPF controls only on the UI thread.
- [x] Investigate replacing eager app-entry creation with item templates or incremental category rendering.
- [x] Verify search, selected-app counts, right-click popup, install, uninstall, and import/export selection state still work.
## P3 - Toggle And Registry Startup Cost
- [x] Stop doing expensive registry-backed toggle status checks while constructing invisible UI.
- [x] Defer toggle state reads until the Tweaks tab is first opened.
- [x] Review `Get-WinUtilToggleStatus` so a status read does not create missing registry paths unless that behavior is explicitly required.
- [x] Batch or cache repeated registry checks where possible.
- [x] Verify toggle import, undo, preset, and manual click behavior still match current expectations.
## P4 - Runspace Cleanup
- [x] Refactor `Invoke-WPFRunspace` to avoid shared `$script:powershell` and `$script:handle` state for concurrent callers.
- [x] Keep the shared runspace pool alive for the app lifetime instead of disposing it from individual queued calls.
- [x] Add explicit completion cleanup for each PowerShell instance after `EndInvoke`.
- [x] Add focused Pester coverage for multiple queued runspace calls, failures, and cleanup.
- [x] Do not parallelize winget/choco package installs by default; package manager locking and prompts make that unsafe.
## P5 - Defer Runspace Pool Startup
- [x] Move GUI runspace pool creation after first render when no automation mode is active.
- [x] Keep synchronous runspace pool creation for `-Preset` and `-Config`.
- [x] Prewarm the pool shortly after `ContentRendered` so later actions do not feel delayed.
- [x] Ensure closing the form disposes the pool if it was created.
- [x] Verify buttons that queue work create or reuse the pool safely.
## P6 - Asset And Theme Cost
- [x] Measure `Invoke-WinUtilAssets -Render` calls during startup.
- [x] Cache rendered logo, checkmark, and warning images once per process.
- [x] Defer non-critical taskbar overlay assets until after first render if measurable.
- [x] Verify taskbar overlay success/error states still display correctly.
## P7 - Verification
- [x] Run `.\Compile.ps1`.
- [x] Run focused Pester tests for runspace, config, XAML wiring, install workflow, tweaks, and preferences/theme.
- [x] Run the full Pester gate before marking speed work complete.
- [ ] Manually launch with `.\Compile.ps1 -Run` and verify first paint, default tab, lazy tabs, search, install selection, tweak toggles, AppX tab, and Win11 ISO tab.
- [x] Check `git status --short` and do not stage or commit generated `winutil.ps1`.
+5 -7
View File
@@ -27,12 +27,10 @@ function Get-RawJsonBlock {
$escapedName = [regex]::Escape($ItemName)
$startIndex = -1
$startIndent = ""
for ($i = 0; $i -lt $JsonLines.Count; $i++) {
if ($JsonLines[$i] -match "^(\s*)`"$escapedName`"\s*:\s*\{") {
$startIndex = $i
$startIndent = $matches[1]
break
}
}
@@ -47,7 +45,7 @@ function Get-RawJsonBlock {
$depth = 1 # We're starting inside the opening brace
for ($i = ($startIndex + 1); $i -lt $JsonLines.Count; $i++) {
$line = $JsonLines[$i]
# Count braces in this line, ignoring those in strings
$inString = $false
$chars = $line.ToCharArray()
@@ -59,7 +57,7 @@ function Get-RawJsonBlock {
elseif ($chars[$k] -eq '}') { $depth-- }
}
}
# Found the closing brace of the item
if ($depth -eq 0) {
$endIndex = $i
@@ -173,14 +171,14 @@ function Add-LinkAttributeToJson {
for ($j = $startIdx + 1; $j -lt $lines.Count; $j++) {
$line = $lines[$j]
# Check for existing "link" property at top-level (depth 1 before processing braces on this line)
# Match at any indentation level (user may have manually changed indentation)
if ($depth -eq 1 -and $line -match '^\s*"link"\s*:') {
# Mark this line for removal
$linesToRemove += $j
}
# Count braces in this line, ignoring those in strings
$inString = $false
$chars = $line.ToCharArray()
@@ -192,7 +190,7 @@ function Add-LinkAttributeToJson {
elseif ($chars[$k] -eq '}') { $depth-- }
}
}
# Found the closing brace of the item
if ($depth -eq 0) {
$closeBraceIdx = $j
@@ -1,14 +0,0 @@
function Start-WinUtilPerformanceTrace {
if (-not (Test-WinUtilPerformanceTrace) -or $null -eq $sync) {
return
}
if (-not $sync.ContainsKey("PerformanceTrace")) {
$sync.PerformanceTrace = @{
Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
LastElapsedMs = 0.0
}
}
Write-WinUtilPerformanceCheckpoint -Name "Startup trace started"
}
@@ -1,15 +0,0 @@
function Stop-WinUtilPerformanceTrace {
param(
[string]$Name = "Startup trace complete"
)
if (-not (Test-WinUtilPerformanceTrace) -or $null -eq $sync -or -not $sync.ContainsKey("PerformanceTrace")) {
return
}
Write-WinUtilPerformanceCheckpoint -Name $Name
if ($null -ne $sync.PerformanceTrace.Stopwatch) {
$sync.PerformanceTrace.Stopwatch.Stop()
}
}
@@ -1,12 +0,0 @@
function Test-WinUtilPerformanceTrace {
$enabledValue = ([string]$env:WINUTIL_PERF_LOG).ToLowerInvariant()
if ($enabledValue -in @("1", "true", "yes", "on")) {
return $true
}
if ($null -ne $sync -and $sync.ContainsKey("PerformanceTraceEnabled")) {
return [bool]$sync.PerformanceTraceEnabled
}
return $false
}

Some files were not shown because too many files have changed in this diff Show More