Architecture & Design
Overview
Section titled “Overview”WinUtil is a PowerShell-based Windows utility with a WPF (Windows Presentation Foundation) GUI. This document explains the architecture, code structure, and how different components work together.
High-Level Architecture
Section titled “High-Level Architecture”┌─────────────────────────────────────────────────────┐│ Winutil GUI ││ (WPF XAML Interface) │└──────────────────┬──────────────────────────────────┘ │ ┌─────────┴─────────┐ │ │┌────────▼──────┐ ┌───────▼────────┐│ Public APIs │ │ Private APIs ││ (User-facing)│ │ (Internal) │└───────┬───────┘ └───────┬────────┘ │ │ └────────┬──────────┘ │ ┌────────────▼────────────┐ │ Configuration Files │ │ (JSON definitions) │ └────────────┬────────────┘ │ ┌────────────▼────────────┐ │ External Tools │ │ (WinGet, Chocolatey) │ └─────────────────────────┘Project Structure
Section titled “Project Structure”Directory Layout
Section titled “Directory Layout”winutil/├── Compile.ps1 # Build script that combines all files├── winutil.ps1 # Compiled output (generated)├── scripts/│ ├── main.ps1 # Entry point and GUI initialization│ └── start.ps1 # Startup logic├── functions/│ ├── private/ # Internal helper functions│ │ ├── Get-WinUtilVariables.ps1│ │ ├── Install-WinUtilWinget.ps1│ │ └── ...│ ├── public/ # User-facing functions│ │ ├── Initialize-WPFUI.ps1│ │ └── ...├── config/ # JSON configuration files│ ├── applications.json # Application definitions│ ├── tweaks.json # Tweak definitions│ ├── feature.json # Windows feature definitions│ └── preset.json # Preset configurations├── xaml/│ └── inputXML.xaml # GUI layout definition└── docs/ # DocumentationKey Components
Section titled “Key Components”1. Compile.ps1
Section titled “1. Compile.ps1”Purpose: Combines all separate script files into a single winutil.ps1 for distribution.
Process:
- Reads all function files from
/functions/ - Includes configuration JSON files
- Embeds XAML GUI definition
- Combines into a single script
- Outputs
winutil.ps1
Why: Makes distribution easier (single file) and improves load time.
2. scripts/main.ps1
Section titled “2. scripts/main.ps1”Purpose: Entry point that initializes the GUI and event system.
Responsibilities:
- Load XAML and create WPF window
- Initialize form elements
- Set up event handlers
- Load configurations
- Display the GUI
3. functions/public/
Section titled “3. functions/public/”Purpose: User-facing functions that implement main features.
Key Functions:
Initialize-WPFUI.ps1: Sets up the GUIInvoke-WPFTweak*: Applies system tweaksInvoke-WPFFeature*: Enables Windows featuresInstall-WinUtilProgram*: Installs applications
Naming Convention: Functions start with WPF or Winutil to be loaded into the runspace.
4. functions/private/
Section titled “4. functions/private/”Purpose: Internal helper functions not directly called by users.
Key Functions:
Get-WinUtilVariables.ps1: Retrieves UI element referencesInstall-WinUtilWinget.ps1: Ensures WinGet is installedGet-WinUtilCheckBoxes.ps1: Gets checkbox statesInvoke-WinUtilCurrentSystem.ps1: Gets system information
5. config/*.json
Section titled “5. config/*.json”Purpose: Define available applications, tweaks, and features declaratively.
Files:
applications.json: Application definitions with WinGet/Choco IDstweaks.json: Registry tweaks and their undo actionsfeature.json: Windows features that can be enabled/disabledpreset.json: Predefined tweak combinationsdns.json: DNS provider configurations
6. xaml/inputXML.xaml
Section titled “6. xaml/inputXML.xaml”Purpose: WPF GUI layout and design.
Structure:
- Buttons with event handlers
- TextBoxes for input
- CheckBoxes for options
- ListBoxes for selections
Win11 Creator Architecture
Section titled “Win11 Creator Architecture”The Win11 Creator is a specialized subsystem within Winutil that creates customized Windows 11 ISOs. It operates independently from the main package installation and tweak system.
Win11 Creator Components
Section titled “Win11 Creator Components”Core Functions (functions/private/):
-
Invoke-WinUtilISO.ps1: Main orchestrator containing all Win11 Creator functionsInvoke-WinUtilISOBrowse: ISO file selection dialogInvoke-WinUtilISOMountAndVerify: Validates and mounts ISO, verifies it’s official Windows 11Invoke-WinUtilISOModify: Launches modification in background runspaceInvoke-WinUtilISOExport: Handles ISO and USB exportInvoke-WinUtilISOCheckExistingWork: Recovers incomplete work sessionsInvoke-WinUtilISOCleanAndReset: Cleans up temp directories and resets UI
-
Invoke-WinUtilISOScript.ps1: Applies modifications to mounted install.wim- Removes provisioned AppX packages (40+ bloatware apps)
- Injects drivers (optional) from the current system
- Removes OneDrive setup files
- Applies offline registry tweaks (hardware bypass, privacy, telemetry, OOBE)
- Deletes telemetry scheduled task definitions
- Pre-stages setup scripts from autounattend.xml
- Removes unused Windows editions
- Cleans component store via DISM
Win11 Creator Data Flow
Section titled “Win11 Creator Data Flow”User selects official Windows 11 ISO ↓Invoke-WinUtilISOBrowse → OpenFileDialog, validates file size ↓Invoke-WinUtilISOMountAndVerify ├─ Mount ISO via Mount-DiskImage ├─ Verify install.wim or install.esd exists ├─ Check for "Windows 11" in image metadata ├─ Extract available editions (Home, Pro, Enterprise, etc.) └─ Store ISO path, drive letter, WIM path, image info in $sync ↓User optionally enables the Driver Injection checkbox ↓Invoke-WinUtilISOModify (runs in background runspace) ├─ Create work directory: ~WinUtil_Win11ISO_[timestamp] ├─ Copy ISO contents to disk (~5-6 GB) ├─ Mount install.wim at selected edition/index ├─ Invoke-WinUtilISOScript: │ ├─ Remove 40+ bloat AppX packages │ ├─ Export and inject drivers (if enabled) │ ├─ Remove OneDrive setup │ ├─ Load offline registry hives │ ├─ Apply 50+ registry tweaks (hardware bypass, privacy, telemetry, OOBE, etc.) │ ├─ Delete telemetry scheduled task files │ ├─ Pre-stage setup scripts from autounattend.xml to C:\Windows\Setup\Scripts\ │ └─ Unload registry hives ├─ DISM /Cleanup-Image /StartComponentCleanup /ResetBase (saves 300-800 MB) ├─ Dismount and save the modified install.wim (~10+ minutes, slowest step) ├─ Export selected edition only (removes all other editions, saves 1-2 GB each) ├─ Dismount source ISO └─ Report completion, enable export options ↓Invoke-WinUtilISOExport (user chooses output) ├─ Option 1: Save as ISO │ ├─ Build bootable ISO via oscdimg.exe (BIOS/UEFI dual-boot) │ └─ Output: Win11_Modified_[date].iso (2.5-3.5 GB) │ └─ Option 2: Write to USB ├─ Format USB as GPT ├─ Create 512 MB EFI partition ├─ Copy modified ISO contents └─ Output: Bootable USB (minimum 8 GB) ↓Invoke-WinUtilISOCleanAndReset (optional) └─ Delete temp working directory (~10-15 GB) └─ Reset UI to initial stateWin11 Creator Validation & Safety
Section titled “Win11 Creator Validation & Safety”ISO Validation:
- Only accepts official Microsoft Windows 11 ISOs
- Validates presence of install.wim or install.esd
- Checks image metadata for “Windows 11” string
- Rejects custom, modified, or non-Windows 11 ISOs
Work Session Recovery:
- Auto-detects incomplete work from previous sessions
- Allows resuming Step 4 (export) without re-running Steps 1-3
- Prevents redundant modifications
Modification Safety:
- All registry changes are documented in a script (reversible)
- Original ISO never modified; only working copy
- Logged to
WinUtil_Win11ISO.logfor debugging - DISM handles image dismount with automatic cleanup on error
Win11 Creator Registry Tweaks
Section titled “Win11 Creator Registry Tweaks”The Invoke-WinUtilISOScript function applies 50+ offline registry tweaks:
Hardware Bypass:
- TPM 2.0 check bypass
- Secure Boot requirement bypass
- CPU compatibility bypass
- RAM requirement bypass
- Storage check bypass
Privacy & Telemetry:
- Disable advertising ID
- Disable tailored experiences
- Disable input personalization
- Disable speech online privacy
- Disable cloud content suggestions
- Disable app suggestion subscriptions
- Remove CEIP, Appraiser, WaaSMedic, etc.
OOBE & Setup:
- Enable local account setup
- Skip Microsoft account requirement
- Dark mode by default
- Empty taskbar and Start Menu
Post-Setup Installations:
- Prevent DevHome auto-installation
- Prevent new Outlook Mail app installation
- Prevent Teams auto-installation
System Features:
- Disable BitLocker and device encryption
- Disable Chat icon from the Taskbar
- Disable OneDrive folder backup
- Disable Copilot
- Disable Windows Update during OOBE (re-enabled at first login)
Driver Injection Feature
Section titled “Driver Injection Feature”Optional Enhancement: When enabled, exports all drivers from the running system and injects them into both:
install.wim(main OS image)boot.wimindex 2 (Windows Setup PE environment)
Use Case: Enables offline installation on systems with missing drivers.
Disk Space Requirements
Section titled “Disk Space Requirements”- Temporary working directory: ~10-15 GB
- Original ISO: 4-6 GB
- Modified ISO: 2.5-3.5 GB
- Total needed: ~25 GB for safe operation
Data Flow
Section titled “Data Flow”Application Installation Flow
Section titled “Application Installation Flow”User clicks "Install" ↓Get-WinUtilCheckBoxes → Retrieves selected apps ↓For each selected app: ↓Check if WinGet/Choco is installed ↓Install-WinUtilWinget/Choco (if needed) ↓Install-WinUtilProgramWinget/Choco → Install app ↓Update UI with progress ↓Display completion messageTweak Application Flow
Section titled “Tweak Application Flow”User selects tweaks and clicks "Run Tweaks" ↓Get-WinUtilCheckBoxes → Get selected tweaks ↓For each selected tweak: ↓Load tweak definition from tweaks.json ↓Invoke-WPFTweak → Apply registry/service changes ↓Log changes ↓Store original values (for undo) ↓Update UI ↓Display completionUndo Tweak Flow
Section titled “Undo Tweak Flow”User selects tweaks and clicks "Undo" ↓Get-WinUtilCheckBoxes → Get selected tweaks ↓For each tweak: ↓Retrieve "OriginalState" from tweak definition ↓Invoke-WPFUndoTweak → Restore original values ↓Remove from the applied tweaks log ↓Update UIConfiguration File Format
Section titled “Configuration File Format”applications.json Structure
Section titled “applications.json Structure”{ "WPFInstall<AppName>": { "category": "Browsers", "choco": "googlechrome", "content": "Google Chrome", "description": "Google Chrome browser", "link": "https://chrome.google.com", "winget": "Google.Chrome" }}Fields:
category: Which section in the Install tabcontent: Display name in GUIdescription: Tooltip/description textwinget: WinGet package IDchoco: Chocolatey package namelink: Official website
tweaks.json Structure
Section titled “tweaks.json Structure”{ "WPFTweaksTelemetry": { "Content": "Disable Telemetry", "Description": "Disables Microsoft Telemetry", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\DataCollection", "Name": "AllowTelemetry", "Type": "DWord", "Value": "0", "OriginalValue": "1" } ] }}Fields:
Content: Display nameDescription: What it doescategory: Essential/Advanced/Customizeregistry: Registry changes to makeservice: Services to changeOriginalValue/State: For undo functionality
PowerShell Runspace
Section titled “PowerShell Runspace”Winutil uses PowerShell runspaces for the GUI to remain responsive:
# Create runspace$sync.runspace = [runspacefactory]::CreateRunspace()$sync.runspace.Open()$sync.runspace.SessionStateProxy.SetVariable("sync", $sync)
# Run code in background$powershell = [powershell]::Create().AddScript($scriptblock)$powershell.Runspace = $sync.runspace$handle = $powershell.BeginInvoke()Why: Prevents UI freezing during long-running operations.
WPF Event Handling
Section titled “WPF Event Handling”Events are wired up via XAML element names:
# Get all named elements$sync.keys | ForEach-Object { if($sync.$_.GetType().Name -eq "Button") { $sync.$_.Add_Click({ $button = $sync.$($args[0].Name) & "Invoke-$($args[0].Name)" }) }}Convention: Button named WPFInstallButton calls function Invoke-WPFInstallButton.
Package Manager Integration
Section titled “Package Manager Integration”WinGet Integration
Section titled “WinGet Integration”# Check if installedif (!(Get-Command winget -ErrorAction SilentlyContinue)) { Install-WinUtilWinget}
# Install packagewinget install --id $app.winget --silent --accept-source-agreementsChocolatey Integration
Section titled “Chocolatey Integration”# Check if installedif (!(Get-Command choco -ErrorAction SilentlyContinue)) { Install-WinUtilChoco}
# Install packagechoco install $app.choco -yError Handling
Section titled “Error Handling”Winutil uses PowerShell error handling:
try { # Attempt operation Invoke-SomeOperation}catch { Write-Host "Error: $_" -ForegroundColor Red # Log error Add-Content -Path $logfile -Value "ERROR: $_"}Logging: Errors and operations are logged for debugging.
Configuration Loading
Section titled “Configuration Loading”At startup, Winutil loads all configurations:
# Load JSON configs$sync.configs = @{}$sync.configs.applications = Get-Content "config/applications.json" | ConvertFrom-Json$sync.configs.tweaks = Get-Content "config/tweaks.json" | ConvertFrom-Json$sync.configs.features = Get-Content "config/feature.json" | ConvertFrom-JsonSync Hash: $sync hashtable shares state across runspaces.
UI Update Pattern
Section titled “UI Update Pattern”UI updates must happen on the UI thread:
$sync.form.Dispatcher.Invoke([action]{ $sync.WPFStatusLabel.Content = "Installing..."}, "Normal")Why: WPF requires UI updates on the main thread.
Adding New Features
Section titled “Adding New Features”Adding a New Application
Section titled “Adding a New Application”- Edit
config/applications.json:
{ "WPFInstallNewApp": { "category": "Utilities", "content": "New App", "description": "Description of new app", "winget": "Publisher.AppName", "choco": "appname" }}- Recompile:
.\Compile.ps1 - The app appears automatically in the Install tab
Adding a New Tweak
Section titled “Adding a New Tweak”- Edit
config/tweaks.json:
{ "WPFTweaksNewTweak": { "Content": "New Tweak", "Description": "What it does", "category": "Essential Tweaks", "registry": [ { "Path": "HKLM:\\Path\\To\\Key", "Name": "ValueName", "Type": "DWord", "Value": "1", "OriginalValue": "0" } ] }}- Recompile:
.\Compile.ps1 - Tweak appears in the Tweaks tab
Adding a New Function
Section titled “Adding a New Function”- Create file in
functions/public/orfunctions/private/:
function Invoke-WPFNewFeature { <# .SYNOPSIS Does something new #> # Implementation}- File naming must include “WPF” or “Winutil” to load
- Recompile:
.\Compile.ps1
Testing
Section titled “Testing”Manual Testing
Section titled “Manual Testing”# Compile and run with -run flag.\Compile.ps1 -runAutomated Tests
Section titled “Automated Tests”Tests are in /pester/:
configs.Tests.ps1: Validates JSON configurationsfunctions.Tests.ps1: Tests PowerShell functions
Run tests:
Install-Module -Name Pester -RequiredVersion 5.8.0 -Scope CurrentUser -Force -SkipPublisherCheckImport-Module Pester -RequiredVersion 5.8.0 -ForceInvoke-Pester -Path 'pester/*.Tests.ps1' -Output Detailed -CIBuild Process
Section titled “Build Process”Development Build
Section titled “Development Build”.\Compile.ps1Outputs winutil.ps1 in the root directory.
Production Release
Section titled “Production Release”- Tag release in Git
- GitHub Actions builds and uploads
winutil.ps1 - Release appears on GitHub Releases
- Users download via
irm christitus.com/win
Dependencies
Section titled “Dependencies”Required:
- PowerShell 5.1+
- .NET Framework 4.5+
- Windows 11
Optional (auto-installed):
- WinGet (Windows Package Manager)
- Chocolatey
Performance Considerations
Section titled “Performance Considerations”Optimization Strategies:
- Lazy-load configurations (only when needed)
- Use runspaces for long operations
- Cache expensive lookups
- Minimize registry reads/writes
- Batch operations when possible
Security Considerations
Section titled “Security Considerations”Safety Measures:
- All operations logged
- Registry backups for undo
- No credential storage
- Open source (auditable)
- Digitally signed (future)
Contributing Guidelines
Section titled “Contributing Guidelines”Code Standards:
- Use proper PowerShell cmdlet naming (Verb-Noun)
- Include comment-based help
- Follow existing code style
- Test thoroughly before PR
- Document significant changes
File Naming:
- Public functions:
Invoke-WPF*.ps1orInvoke-Winutil*.ps1 - Private functions:
Get-WinUtil*.ps1or verb-WinUtil*.ps1` - Must include “WPF” or “Winutil” to load
Future Architecture Plans
Section titled “Future Architecture Plans”Roadmap Considerations:
- Plugin system for community extensions
- Config import/export
- Cloud sync for configurations
- Enhanced logging dashboard
- Modular compilation (choose features)
Related Documentation
Section titled “Related Documentation”- Contributing Guide - How to contribute code
- User Guide - End-user documentation
- Win11 Creator Guide - Building customized Windows 11 ISOs
- FAQ - Common questions
Additional Resources
Section titled “Additional Resources”- GitHub Repository: ChrisTitusTech/winutil
- PowerShell Docs: Microsoft Docs
- WPF Guide: WPF Documentation
Last Updated: January 2026 Maintainers: Chris Titus Tech and contributors
