# Chris Titus Tech's Windows Utility (WinUtil) — Admin & Developer Guide

This guide is for administrators, architects, and contributors who need to understand how WinUtil is built and how it behaves on a managed system. It covers the build pipeline, runtime architecture, the configuration-driven UI engine, every category of system change WinUtil makes, security considerations, deployment/automation, and the repository internals needed to extend or audit the tool.

For end-user installation and usage, see the companion **User Guide**.

---

## 1. Executive Summary

WinUtil is a single-file **PowerShell + WPF** desktop application for post-install Windows 11 administration. It is **configuration-driven**: the application catalog, tweaks, optional features, presets, themes, and DNS providers all live in JSON files under `config/`, and the GUI is generated dynamically from those JSON definitions at runtime. There is no compiled binary and no installer — distribution is a single `winutil.ps1` script fetched from GitHub releases and executed in memory.

| Attribute | Value |
|---|---|
| Language / UI | PowerShell 5.1+ / WPF (PresentationFramework) + WinForms helpers |
| Distribution | Single `winutil.ps1` (built by `Compile.ps1`); run via `irm https://christitus.com/win \| iex` |
| Target OS | Windows 11 (Windows 10 EOL 2025-10-14); Server/LTSC with caveats |
| Privileges | Requires Administrator; self-elevates on launch |
| Concurrency | `RunspacePool` (1 → `$env:NUMBER_OF_PROCESSORS` threads) with a synchronized `$sync` hashtable |
| Config model | JSON files in `config/` define apps, tweaks, features, presets, themes, DNS, navigation |
| Persistence | None on the host except logs and a working dir under `%LocalAppData%\winutil` |
| Source repo | <https://github.com/ChrisTitusTech/winutil> (MIT-licensed core) |
| This revision | Commit `e83033a`, 239 files, ~257 KB of source, medium complexity tier |

**Design philosophy:** keep the engine tiny and data-driven. Adding an app or a tweak means editing JSON, not PowerShell. The PowerShell layer is a generic interpreter that renders the JSON into WPF controls and dispatches each control's data (registry entries, services, appx names, scripts) to a small set of apply functions.

> [!IMPORTANT]
> WinUtil's user-facing surface area is defined almost entirely by `config/*.json` and `xaml/inputXML.xaml`. Static code analysis of the PowerShell alone will under-report what the tool does — the JSON *is* the specification. AST extraction over this repo yields essentially nothing; the configuration files are the source of truth.

---

## 2. Architecture

### 2.1 Build-time: compilation into a single script

WinUtil ships as one file, `winutil.ps1`, assembled by **`Compile.ps1`** at the repo root. The build concatenates, in order:

1. `scripts/start.ps1` — the preamble (parameters, elevation, `$sync` bootstrap, logging). The build replaces the `#{replaceme}` version token with the current date (`yy.MM.dd`).
2. Every `*.ps1` under `functions/` (recursively) — all private and public functions.
3. Each `config/*.json`, embedded as a here-string and parsed back with `ConvertFrom-Json` into `$sync.configs.<name>`. For `applications.json`, every key is prefixed with `WPFInstall` so app keys become control names (e.g. `chrome` → `WPFInstallchrome`).
4. `xaml/inputXML.xaml` — embedded as `$inputXML`.
5. `tools/autounattend.xml` — embedded as `$WinUtilAutounattendXml` (used by MicroWin).
6. `scripts/main.ps1` — the GUI bootstrapper and event wiring (runs last).

```text
Compile.ps1
  ├── scripts/start.ps1            (params, elevation, $sync, logging)
  ├── functions/**/*.ps1           (private + public functions)
  ├── config/*.json   ──embed──▶   $sync.configs.<name>
  ├── xaml/inputXML.xaml ─embed─▶   $inputXML
  ├── tools/autounattend.xml ──▶    $WinUtilAutounattendXml
  └── scripts/main.ps1             (load XAML, wire events, ShowDialog)
        └──▶ winutil.ps1  (single distributable file)
```

`Compile.ps1 -Run` builds and immediately launches the result. The `windev.ps1` helper fetches and runs the latest *pre-release* `winutil.ps1` from GitHub tags.

> [!NOTE]
> Because the public release is a single generated file, the GitHub release `winutil.ps1` is the only artifact end users ever execute. The `config/`, `functions/`, and `xaml/` layout exists for development and is collapsed into that one file at build time.

### 2.2 Runtime: startup sequence

```text
irm christitus.com/win | iex
        │
        ▼
scripts/start.ps1
  • parse params (-Config / -Preset / -Noui / -Offline)
  • verify FullLanguage mode (abort if Constrained)
  • verify Administrator; relaunch elevated via wt.exe / pwsh / powershell if not
  • Add-Type PresentationFramework + System.Windows.Forms
  • build synchronized $sync hashtable (selections, prefs, version)
  • create %LocalAppData%\winutil + \logs, Start-Transcript
        │
        ▼
(function bodies + embedded JSON/XAML are defined inline here)
        │
        ▼
scripts/main.ps1
  • print CTT ASCII banner; define PackageManagers enum (Winget, Choco)
  • create RunspacePool (1..NUMBER_OF_PROCESSORS) seeded with all winutil/WPF functions + $sync
  • define exception classes (WingetFailedInstall, ChocoFailedInstall, GenericException)
  • build applicationsHashtable; Set-Preferences
  • IF -Preset:  apply preset → Invoke-WinUtilAutoRun → exit (no GUI)
  • IF -Noui:    require -Config → import → Invoke-WinUtilAutoRun → exit
  • else: load XAML → bind named controls into $sync → render panels
          (Invoke-WPFUIElements for apps/tweaks/features) → wire events → ShowDialog
```

### 2.3 The `$sync` synchronized hashtable

`$sync = [Hashtable]::Synchronized(@{})` is the single shared-state object across the main thread and all runspace threads. It holds:

- `$sync.configs.*` — parsed JSON (applications, tweaks, feature, preset, dns, themes, appnavigation) plus `applicationsHashtable`.
- `$sync.Form` and every named XAML element (each control with `Name="X"` is stored as `$sync.X` via `FindName`).
- Selection lists: `selectedApps`, `selectedTweaks`, `selectedToggles`, `selectedFeatures`.
- `$sync.preferences` (e.g. persisted `packagemanager`), `$sync.ProcessRunning`, `$sync.currentTab`, `$sync.runspace` (the RunspacePool), `$sync.version`.

Because it's a synchronized hashtable, background runspaces can safely read selections and update progress while the WPF thread owns the UI.

### 2.4 Concurrency model

Long-running work (installs, tweaks, feature installs) is dispatched to the RunspacePool via **`Invoke-WPFRunspace`**, which creates a `[powershell]` instance bound to `$sync.runspace` and `BeginInvoke()`s a scriptblock. UI updates from inside a runspace are marshaled back to the WPF dispatcher with **`Invoke-WPFUIThread`** (`$sync.form.Dispatcher.Invoke`). The `$sync.ProcessRunning` flag guards against starting overlapping operations and disables keyboard shortcuts while busy.

### 2.5 Component inventory

| Component | Location | Responsibility |
|---|---|---|
| Build script | `Compile.ps1` | Bundle config + xaml + functions → `winutil.ps1` |
| Entry preamble | `scripts/start.ps1` | Params, elevation, `$sync`, logging |
| GUI bootstrap | `scripts/main.ps1` | XAML load, event wiring, `ShowDialog` |
| UI definition | `xaml/inputXML.xaml` | WPF layout, styles, tab structure |
| App catalog | `config/applications.json` | Installable apps (winget/choco IDs, metadata) |
| Tweak definitions | `config/tweaks.json` | Registry/service/appx/script per tweak |
| Feature/Config buttons | `config/feature.json` | Config-tab features, fixes, panels |
| Presets | `config/preset.json` | Standard / Minimal / Advanced tweak sets |
| DNS providers | `config/dns.json` | IPv4/IPv6 server pairs |
| Themes | `config/themes.json` | Shared/Light/Dark color + sizing tokens |
| Install-tab nav | `config/appnavigation.json` | Action buttons, package-manager radios |
| UI engine | `functions/public/Invoke-WPFUIElements.ps1` | Render JSON → WPF controls |
| Tweak engine | `functions/private/Invoke-WinUtilTweaks.ps1` | Dispatch tweak data to apply functions |
| Apply primitives | `functions/private/Set-WinUtil*.ps1` | Registry, service, DNS writes; appx removal |
| Install engine | `functions/private/Install-WinUtil*.ps1` | winget/choco install/uninstall |
| MicroWin | `functions/private/Invoke-WinUtilISO*.ps1` | Build custom Windows 11 ISO/USB |
| Tests | `pester/*.Tests.ps1` | Pester validation of configs + functions |
| Lint config | `lint/PSScriptAnalyser.ps1` | PSScriptAnalyzer settings |
| Docs generator | `tools/devdocs-generator.ps1` | Generate Hugo docs from tweaks/feature JSON |

---

## 3. The Configuration-Driven UI Engine

The heart of WinUtil is **`Invoke-WPFUIElements`**, a generic renderer that turns a JSON config object into WPF controls inside a named grid. `main.ps1` calls it three times:

```powershell
Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1
Invoke-WPFUIElements -configVariable $sync.configs.tweaks        -targetGridName "tweakspanel"  -columncount 2
Invoke-WPFUIElements -configVariable $sync.configs.feature       -targetGridName "featurespanel" -columncount 2
```

The engine organizes entries by `Panel` then `Category`, sorts each category (checkboxes → buttons → comboboxes, then alphabetically by `Content`), and emits a control based on each entry's `Type`:

| `Type` | Rendered control | Behavior |
|---|---|---|
| *(default / none)* | CheckBox + optional `(?)` link | Adds/removes from a selection list on check |
| `Toggle` | Colorful toggle switch | Applies/undoes a tweak **immediately** via `Invoke-WinUtilTweaks` |
| `Button` | Button | Runs the mapped function/script on click |
| `Combobox` | Label + ComboBox | e.g. the DNS selector (`ComboItems` split on spaces) |
| `RadioButton` | RadioButton (grouped by `GroupName`) | e.g. WinGet/Chocolatey selector |
| `ToggleButton` | ToggleButton with on/off content | State-labeled buttons |

Panels use **virtualizing** stack panels (`VirtualizingStackPanel`, recycling mode) for performance with large lists. The Install tab's app area is built separately by `Initialize-InstallAppArea` / `Initialize-InstallCategoryAppList`, which also use virtualization and a `WrapPanel` for responsive columns.

> [!TIP]
> To add a tweak, app, or feature, you edit the relevant JSON file — no engine changes are needed. The control type, category placement, tooltip (`Description`), and docs link (`link`) all come from the JSON entry.

### 3.1 Button dispatch

`Invoke-WPFButton` resolves a clicked button in two stages:

1. If the button name exists in `config/feature.json` and has a `function` or `InvokeScript`, run that.
2. Otherwise fall back to a hard-coded `switch` mapping button names to functions (`WPFInstall` → `Invoke-WPFInstall`, `WPFtweaksbutton` → `Invoke-WPFtweaksbutton`, tab buttons → `Invoke-WPFTab`, preset buttons → `Invoke-WPFPresets`, etc.).

---

## 4. System Changes — What WinUtil Actually Does

This section is the audit-focused inventory of every category of change. All changes require Administrator rights.

### 4.1 Tweak application engine

**`Invoke-WinUtilTweaks -CheckBox <name> [-undo] [-KeepServiceStartup]`** reads the tweak's JSON definition and applies up to four kinds of change, choosing `Value`/`StartupType`/`InvokeScript` normally or `OriginalValue`/`OriginalType`/`UndoScript` when `-undo` is set:

| JSON key | Apply function | Effect |
|---|---|---|
| `service[]` | `Set-WinUtilService` | Set each service's `StartupType` (Manual/Disabled/Automatic/AutomaticDelayedStart) |
| `registry[]` | `Set-WinUtilRegistry` | Create/set/remove a registry value (`<RemoveEntry>` deletes it) |
| `InvokeScript[]` / `UndoScript[]` | `Invoke-WinUtilScript` | Run an embedded PowerShell scriptblock |
| `appx[]` | `Remove-WinUtilAPPX` | Remove AppX/provisioned packages (apply only; not undone) |

`-KeepServiceStartup` (default `$true`) skips changing a service whose current startup type no longer matches the recorded `OriginalType`, so WinUtil won't override a choice you (or another tool) deliberately made.

`Set-WinUtilRegistry` creates the key path if missing, mounts `HKU:` if needed, and either sets the value with the given `Type` (DWord/QWord/String/Binary) or removes it when the value is the sentinel `<RemoveEntry>`. Exceptions (security, unauthorized, not-found) are caught and logged as warnings rather than crashing the run.

### 4.2 Tweak catalog (config/tweaks.json)

Tweaks are grouped into four categories. Highlights of what each Essential tweak changes (all reversible via Undo unless noted):

| Tweak | Mechanism |
|---|---|
| Activity History – Disable | Removes `EnableActivityFeed`/`PublishUserActivities`/`UploadUserActivities` policies |
| Telemetry – Disable | ~12 registry values + disables DiagTrack/wermgr, opts out of PowerShell telemetry, Defender sample submission |
| Location Tracking – Disable | Disables `lfsvc`, denies location consent, blocks sensor |
| Services – Set to Manual | Manual/Disabled on several services + tunes `SvcHostSplitThresholdInKB` to RAM |
| Hibernation – Disable | `powercfg /hibernate off` + registry (Undo re-enables) |
| ConsumerFeatures – Disable | `DisableWindowsConsumerFeatures` policy |
| Delivery Optimization – Disable | `DODownloadMode=0` |
| Unwanted Pre-Installed Apps – Remove (DeBloat) | Removes ~19 AppX packages + uninstalls classic Teams |
| Disk Cleanup / Temporary Files | Run cleanup / clear temp |
| End Task With Right Click | Taskbar developer option |
| Restore Point – Create | Creates a System Restore point (applied first when selected) |
| Widgets / Start Menu layout / Store search / Explorer auto-discovery / WPBT | Various registry/appx/script changes |

Advanced ("z__Advanced Tweaks – CAUTION") tweaks include Brave/Edge debloat, Remove Edge, Remove OneDrive, Remove File Explorer Home, Visual Effects → performance, Xbox removal, IPv6 preferences/disable, Teredo disable, background apps disable, fullscreen optimizations disable, Razer auto-install block, notifications disable, Adobe URL block, classic right-click menu, UTC clock, storage sense disable, Windows AI disable, O&O ShutUp10++, and the DNS selector.

> [!CAUTION]
> Advanced tweaks make aggressive changes (removing Edge/OneDrive, disabling IPv6, blocking domains). Several download external helper tools at runtime (e.g. **Revert Start Menu** downloads ViVeTool; **O&O ShutUp10++** downloads OOSU10.exe). Review the `InvokeScript` body in `config/tweaks.json` before deploying to managed fleets.

### 4.3 Customize Preferences (live toggles)

Toggle-type entries apply immediately on flip (and reverse on un-flip) through the same `Invoke-WinUtilTweaks` path. Examples: Dark mode, show file extensions/hidden files, taskbar alignment/search/task-view icons, Bing search in Start, Start recommendations, battery percentage, mouse acceleration, sticky keys, NumLock on startup, Game Mode, long paths, verbose logon, verbose BSoD, new Outlook, scrollbars, S0/S3 sleep, settings home page, logon acrylic blur. Their on/off state is read at render time via `Get-WinUtilToggleStatus`, which compares the live registry against the JSON-defined value.

### 4.4 Config-tab features & fixes (config/feature.json)

| Entry | Function / mechanism |
|---|---|
| .NET Framework / Hyper-V / WSL / NFS / Sandbox | `Enable-WindowsOptionalFeature` via `Invoke-WinUtilFeatureInstall` (+ NFS InvokeScript for anonymous config) |
| Registry Backup / Legacy F8 Recovery | `bcdedit` / scheduled-task `InvokeScript` |
| Windows Update – Reset | `Invoke-WPFFixesUpdate` (stop services, clear caches, re-register 36 DLLs, reset policies, restart services) |
| Network – Reset | `Invoke-WPFFixesNetwork` (`netsh winsock reset`, `netsh int ip reset`) |
| System Corruption Scan | `Invoke-WPFSystemRepair` (`chkdsk /scan`, `sfc /scannow`, `DISM /RestoreHealth`) |
| WinGet – Reinstall | `Invoke-WPFFixesWinget` → `Install-WinUtilWinget` |
| NTP Server – Enable | `w32tm` repointed at `pool.ntp.org` |
| AutoLogon | Downloads Sysinternals `Autologon.exe` |
| Legacy Windows Panels | Launch `control`, `compmgmt.msc`, `ncpa.cpl`, `powercfg.cpl`, `intl.cpl`, `rstrui.exe`, `mmsys.cpl`, `sysdm.cpl`, `timedate.cpl`, printers shell |
| CTT PowerShell Profile – Install/Remove | `Invoke-WinUtilInstallPSProfile` / `...Uninstall...` (backs up existing `$Profile`) |
| OpenSSH Server – Enable | `Invoke-WinUtilSSHServer` |

### 4.5 Windows Update policies (Updates tab)

| Function | Behavior |
|---|---|
| `Invoke-WPFUpdatesdefault` | Removes WinUtil's WU policy keys, restores BITS/wuauserv/UsoSvc/WaaSMedicSvc startup, re-enables WU scheduled tasks, resets local policy. |
| `Invoke-WPFUpdatessecurity` | Defers feature updates **365 days**, quality updates **4 days**; sets `BranchReadinessLevel=20`; blocks driver offering; disables auto-restart with logged-on users. |
| `Invoke-WPFUpdatesdisable` | `NoAutoUpdate=1`, disables BITS/wuauserv/UsoSvc, clears `SoftwareDistribution`, disables WU scheduled tasks. **Blocks security updates.** |

### 4.6 Application install/uninstall

`Invoke-WPFInstall` / `Invoke-WPFUnInstall` resolve selected app keys to `applicationsHashtable` entries, sort them by manager via `Get-WinUtilSelectedPackages` (Chocolatey entries marked `na` fall back to WinGet), then run inside a runspace:

- WinGet path: `Install-WinUtilWinget` (ensures WinGet present) → `Install-WinUtilProgramWinget -Action Install/Uninstall`.
- Chocolatey path: `Install-WinUtilChoco` → `Install-WinUtilProgramChoco -Action Install/Uninstall`.

`Invoke-WPFInstallUpgrade` upgrades everything: `winget upgrade --all --include-unknown --silent --accept-source-agreements --accept-package-agreements` (or `choco upgrade all -y`). `Invoke-WPFGetInstalled` queries the system via `Invoke-WinUtilCurrentSystem` and ticks matching boxes.

### 4.7 DNS changes

`Set-WinUtilDNS -DNSProvider <name>` enumerates adapters in the **Up** state and calls `Set-DnsClientServerAddress` for both IPv4 and IPv6 using the pair from `config/dns.json`. `Default` is a no-op; `DHCP` resets to automatic. Providers: Google, Cloudflare (+ Malware / Malware+Adult), OpenDNS, Quad9, AdGuard (ads/trackers, and +malware+adult).

### 4.8 MicroWin (custom ISO builder)

`Invoke-WinUtilISO*` functions build a debloated Windows 11 image offline:

- Mount/verify a Windows 11 ISO; operate on `install.wim`.
- `Invoke-WinUtilISOScript` removes AppX bloatware and OneDrive, optionally **injects the running system's drivers** into `install.wim` and `boot.wim` (index 2), applies offline registry tweaks (hardware-requirement bypass, privacy, OOBE, telemetry, update suppression), and removes CEIP/WU scheduled-task definitions.
- Optionally writes `tools/autounattend.xml` to the ISO root for unattended OOBE; embeds setup scripts under `C:\Windows\Setup\Scripts\` so they survive Setup stripping unknown-namespace XML.
- Export to a new ISO or write directly to USB.

> [!IMPORTANT]
> MicroWin operates only on the mounted image, never the running OS. It requires substantial free disk space; driver injection significantly increases time and size. Known open issues include product-key verification failures on some debloated images ([#4145](https://github.com/ChrisTitusTech/winutil/issues/4145), [#4616](https://github.com/ChrisTitusTech/winutil/issues/4616)).

---

## 5. Security Analysis

| Area | Assessment |
|---|---|
| **Elevation** | Requires Administrator and self-elevates via `Start-Process … -Verb RunAs`. By design — every operation is system-level. |
| **Language mode** | Refuses to run outside `FullLanguage` mode, which is also the relevant control for AppLocker/Constrained-Language-locked environments. |
| **Remote code execution** | The standard entry point pipes a remotely fetched script into `iex`. Trust derives from HTTPS + the official GitHub release. Several tweaks/features also download external EXEs at runtime (Autologon, OOSU10, ViVeTool). |
| **Network egress** | App installs hit WinGet/Choco sources; specific tweaks/fixes fetch helper tools from `sysinternals`, `oo-software.com`, GitHub. |
| **Data handling** | WinUtil itself transmits no user data. The Sponsors panel scrapes the public GitHub sponsors page. |
| **Destructive operations** | Remove Edge/OneDrive, AppX removal, `SoftwareDistribution` deletion, registry deletes, DISM/SFC. Mitigated by Undo scripts and the optional Restore Point tweak. |
| **Error handling** | Apply primitives wrap operations in typed `try/catch` and log warnings; a single failed tweak does not abort the batch. |
| **Logging** | Full session transcript at `%LocalAppData%\winutil\logs\winutil_<timestamp>.log`. |

> [!WARNING]
> For managed/enterprise fleets, treat the `irm … | iex` pattern as remote code execution. Pin to a vetted `winutil.ps1` release, review the embedded `config/tweaks.json` and `config/feature.json` `InvokeScript` bodies, and prefer the `-Config` exported-profile path over ad-hoc GUI use so changes are reproducible and auditable.

> [!CAUTION]
> **Disable Updates** removes security patching and clears the update cache. **Remove Edge/OneDrive** and AppX removals are difficult to fully reverse. Always validate on a test machine and keep a restore point.

---

## 6. Operations

### 6.1 Running

| Mode | Command |
|---|---|
| Stable GUI | `irm https://christitus.com/win \| iex` |
| Dev GUI | `irm https://christitus.com/windev \| iex` |
| Direct from GitHub | `irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 \| iex` |
| Preset, no GUI | `& ([ScriptBlock]::Create((irm https://christitus.com/win))) -Preset Standard` |
| Config, no GUI | `& ([ScriptBlock]::Create((irm https://christitus.com/win))) -Config '<file-or-url>' -Noui` |

### 6.2 Command-line parameters (`scripts/start.ps1`)

| Parameter | Type | Effect |
|---|---|---|
| `-Config <path\|url>` | string | Import an exported selection JSON and apply it. |
| `-Preset <Standard\|Minimal\|Advanced>` | validated string | Apply a built-in preset's tweaks, then exit. |
| `-Noui` | switch | Headless run; requires `-Config`. |
| `-Offline` | switch | Disable the Install tab and install buttons. |

### 6.3 Unattended deployment

1. Configure selections in the GUI on a reference machine.
2. **Settings → Export** → save `winutil.json`. WinUtil copies a run command to the clipboard.
3. Deploy with `-Config` (+ `-Noui` for silent). `Invoke-WinUtilAutoRun` then applies tweaks, features, and installs in order, busy-waiting between phases.

### 6.4 Config file format

Exported configs are a flat JSON array of selected control keys (apps, tweaks, toggles, features), e.g. `["WPFInstallchrome","WPFTweaksTelemetry","WPFToggleDarkMode"]`. `Update-WinUtilSelections` re-checks the matching boxes; `Reset-WPFCheckBoxes` restores UI state without retriggering tweak writes (guarded by `$sync.ImportInProgress`).

### 6.5 Logs & working files

| Path | Purpose |
|---|---|
| `%LocalAppData%\winutil\` | Working directory (created at startup) |
| `%LocalAppData%\winutil\logs\winutil_<yyyy-MM-dd_HH-mm-ss>.log` | `Start-Transcript` session log |

### 6.6 Building from source

```powershell
# From the repo root, build winutil.ps1 and launch it
.\Compile.ps1 -Run

# Run the latest pre-release build
.\windev.ps1
```

---

## 7. Repository Structure

```text
winutil/
  Compile.ps1                 Build: bundle config+xaml+functions → winutil.ps1
  windev.ps1                  Run latest pre-release build
  sign.bat                    Code-signing helper
  config/                     SOURCE OF TRUTH (JSON)
    applications.json           App catalog (winget/choco IDs, metadata, foss flag)
    tweaks.json                 Tweak definitions (registry/service/appx/scripts)
    feature.json                Config-tab features, fixes, panels
    preset.json                 Standard / Minimal / Advanced
    dns.json                    DNS provider IPv4/IPv6 pairs
    themes.json                 Shared/Light/Dark tokens
    appnavigation.json          Install-tab actions + package-manager radios
  functions/
    private/                    Engine internals (Set-WinUtil*, Invoke-WinUtil*, ISO)
    public/                     UI-facing handlers (Invoke-WPF*)
  scripts/
    start.ps1                   Entry preamble (params, elevation, $sync, logging)
    main.ps1                    GUI bootstrap + event wiring
  xaml/inputXML.xaml           WPF layout + styles
  pester/                      *.Tests.ps1 (config + function tests)
  lint/PSScriptAnalyser.ps1    PSScriptAnalyzer settings
  tools/
    autounattend.xml            MicroWin OOBE answer file
    devdocs-generator.ps1       Generate Hugo docs from JSON
  docs/                        Hugo (hextra theme) documentation site
```

> [!NOTE]
> `docs/go.mod`/`go.sum` belong to the **documentation website** (Hugo + the `hextra` theme), not to WinUtil itself. The tool has no Go, Node, or compiled dependencies — it runs on in-box PowerShell and WPF.

### 7.1 Naming conventions

- `WPFInstall<app>` — app checkbox (app key from `applications.json`, prefixed at build time).
- `WPFTweaks<name>` — tweak checkbox; `WPFToggle<name>` — preference toggle.
- `WPFFeature*` / `WPFFix*` / `WPFPanel*` — Config-tab entries.
- `Invoke-WPF*` (public) — UI event handlers; `Invoke-WinUtil*` / `Set-WinUtil*` / `Get-WinUtil*` (private) — engine.

---

## 8. Code Quality & Conventions

- **Approved verbs & PSScriptAnalyzer.** Functions follow PowerShell verb-noun naming; `lint/PSScriptAnalyser.ps1` excludes only `PSAvoidUsingWriteHost` (Write-Host is used intentionally for console feedback).
- **Comment-based help.** Most functions carry `.SYNOPSIS`/`.PARAMETER`/`.EXAMPLE` blocks.
- **PowerShell 5.1 compatibility.** Search/filter code deliberately avoids ternaries and advanced syntax, with multi-level `$sync` fallback, to run on stock Windows PowerShell as well as PowerShell 7.
- **Defensive UI code.** High-frequency handlers (e.g. `Find-AppsByNameOrDescription`, `Find-TweaksByNameOrDescription`) null-check aggressively and swallow exceptions silently to avoid crashing the WPF thread on every keystroke.
- **Data over code.** New apps/tweaks/features are JSON edits; the engine is generic.
- **Testing.** `pester/configs.Tests.ps1` and `pester/functions.Tests.ps1` validate config integrity and function behavior.

---

## 9. Potential Improvements

These are observations from the current source, not defects:

- **`Invoke-WPFUIElements` is monolithic.** An inline `// TODO` notes it should be wrapped in a runspace to render all panels in parallel; it also mixes layout, event wiring, and control creation. Extracting per-control-type builders would aid testability.
- **`Initialize-WPFUI` partially stubbed.** The `appscategory` branch contains commented-out future work, and `default` returns "not yet implemented" — indicating an in-progress migration of sidebar generation into this function.
- **Import legacy-format handling is unfinished.** `Invoke-WPFImpex` has a `TODO` about detecting and flattening the old config JSON shape.
- **`Invoke-WPFGetInstalled`** has a `TODO` to support Chocolatey as the detection engine (currently winget-centric).
- **Driver/ISO operations are long and serial.** MicroWin steps could surface more granular progress and resumability (several open issues relate to mid-build failures).
- **External-download tweaks** (ViVeTool, OOSU10, Autologon) fetch from third-party URLs at runtime; pinning/hash-verification would harden them for enterprise use.
- **FAQ/config drift.** The shipped FAQ references a "Desktop" preset and a "Clear Tweaks Selection" wording that don't match `preset.json` (which defines only Standard/Minimal/Advanced) — keep user docs synchronized with the JSON ground truth.

---

## 10. Contributing

- **Add an app:** add an entry to `config/applications.json` with `category`, `content`, `description`, `link`, `winget`, `choco` (use `na` if none), and `foss`. The build prefixes the key with `WPFInstall`.
- **Add a tweak:** add to `config/tweaks.json` with `Content`, `Description`, `category`, `panel`, and any of `registry[]` / `service[]` / `appx[]` / `InvokeScript[]` / `UndoScript[]`. Provide `OriginalValue`/`OriginalType` (or `UndoScript`) so it can be reverted.
- **Add a feature/fix:** add to `config/feature.json`; either point `function` at a public function or supply `InvokeScript[]`. Map buttons in `Invoke-WPFButton.ps1` if not function-driven.
- **Regenerate docs:** `tools/devdocs-generator.ps1` emits Hugo pages from `tweaks.json`/`feature.json`.
- **Test & lint:** run the Pester suites in `pester/` and PSScriptAnalyzer with `lint/PSScriptAnalyser.ps1` before submitting.

See the [CONTRIBUTING guide](https://github.com/ChrisTitusTech/winutil/blob/main/.github/CONTRIBUTING.md).

---

## 11. Quick Reference

### Engine functions

| Function | Role |
|---|---|
| `Invoke-WPFUIElements` | Render a JSON config into WPF controls |
| `Invoke-WPFButton` | Dispatch a clicked button to its function/script |
| `Invoke-WinUtilTweaks` | Apply/undo a tweak (service/registry/script/appx) |
| `Set-WinUtilRegistry` | Create/set/remove a registry value |
| `Set-WinUtilService` | Set a service startup type |
| `Set-WinUtilDNS` | Set adapter DNS from `dns.json` |
| `Remove-WinUtilAPPX` | Remove AppX/provisioned packages |
| `Invoke-WPFInstall` / `Invoke-WPFUnInstall` | Install/uninstall selected apps |
| `Invoke-WPFRunspace` / `Invoke-WPFUIThread` | Background work / UI-thread marshaling |
| `Invoke-WinUtilAutoRun` | Headless apply (tweaks → features → installs) |
| `Invoke-WinUtilISOScript` | Apply MicroWin modifications to a mounted WIM |

### Config files

| File | Defines |
|---|---|
| `applications.json` | Installable apps |
| `tweaks.json` | Tweaks & toggles |
| `feature.json` | Config-tab features/fixes/panels |
| `preset.json` | Standard / Minimal / Advanced |
| `dns.json` | DNS providers |
| `themes.json` | Theme tokens |
| `appnavigation.json` | Install-tab actions |

### Key paths & links

| Item | Value |
|---|---|
| Working dir | `%LocalAppData%\winutil\` |
| Logs | `%LocalAppData%\winutil\logs\winutil_<timestamp>.log` |
| Build script | `Compile.ps1` (`-Run` to build + launch) |
| Source | <https://github.com/ChrisTitusTech/winutil> |
| Docs | <https://winutil.christitus.com/> |

---

_Generated June 2026 from ChrisTitusTech/winutil at e83033a. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
