mirror of
https://github.com/ChrisTitusTech/winutil
synced 2026-04-06 06:38:31 +00:00
Compare commits
32 Commits
7ceb303f00
...
26.03.13
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a05034381d | ||
|
|
b1d4eb022c | ||
|
|
3dbd993cb4 | ||
|
|
ec17c085df | ||
|
|
7da4e78d4b | ||
|
|
1943b30ec9 | ||
|
|
6df8ae900c | ||
|
|
a16f4b7d07 | ||
|
|
adaab0ab36 | ||
|
|
c270d25460 | ||
|
|
2bb007b6ff | ||
|
|
34f29dd04c | ||
|
|
ccb43bfe91 | ||
|
|
1d401b2e02 | ||
|
|
d8f6a8c50b | ||
|
|
3da0221fb4 | ||
|
|
a30664002b | ||
|
|
5e78391518 | ||
|
|
2d2497408f | ||
|
|
d2dbf03572 | ||
|
|
88c68fd411 | ||
|
|
e82aaf03f0 | ||
|
|
9a77fed09b | ||
|
|
336ac6fb8f | ||
|
|
72ad35bbd8 | ||
|
|
df17ca4695 | ||
|
|
7f46e8d60d | ||
|
|
9769cafa7d | ||
|
|
42dfc8c82b | ||
|
|
d13295bdd8 | ||
|
|
5fc566b46f | ||
|
|
b493737982 |
52
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
52
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -6,57 +6,31 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
# 🐞 **Issue Report**
|
- Remember, we only support Windows 11. If you encounter problems on Windows 10, please consider upgrading to Windows 11.
|
||||||
Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
|
- For general questions, join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
|
||||||
|
|
||||||
## ⚠️ **IMPORTANT**
|
- type: dropdown
|
||||||
- 🛠️ **Supported environments only:** We only support Windows 11.
|
|
||||||
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
|
|
||||||
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: ⚙️ Issue Checklist
|
|
||||||
options:
|
|
||||||
- label: I have read the guidelines.
|
|
||||||
- label: I checked for duplicate issues.
|
|
||||||
- label: I searched for existing discussions.
|
|
||||||
- label: I checked for an existing pull request that addresses this issue.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: affected_part
|
id: affected_part
|
||||||
attributes:
|
attributes:
|
||||||
label: 📜 What part of Winutil are you having issues with?
|
label: What part of Winutil are you having issues with?
|
||||||
placeholder: "e.g., Tweaks, etc."
|
options:
|
||||||
|
- Program Install Tab
|
||||||
|
- Tweaks Tab
|
||||||
|
- Config Tab
|
||||||
|
- Updates Tab
|
||||||
|
- Win11 Creator Tab
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: false
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: issue_description
|
id: issue_description
|
||||||
attributes:
|
attributes:
|
||||||
label: 📝 Provide a clear and concise description of the issue.
|
label: Provide a clear and concise description of the issue.
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: steps_to_reproduce
|
|
||||||
attributes:
|
|
||||||
label: 🔄 Steps to reproduce the issue.
|
|
||||||
placeholder: "e.g., Step 1: ..., Step 2: ..."
|
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: error_output
|
id: error_output
|
||||||
attributes:
|
attributes:
|
||||||
label: ❌ Paste the full error output (if available).
|
label: Paste the full error output (if available) or Screenshot.
|
||||||
placeholder: "Include any relevant logs or error messages."
|
placeholder: "Include any relevant logs or error messages."
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: additional_context
|
|
||||||
attributes:
|
|
||||||
label: 🖼️ Additional context.
|
|
||||||
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|||||||
37
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
37
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@@ -13,45 +13,10 @@ body:
|
|||||||
- 🛠️ **Supported environments only:** We only support Windows 11.
|
- 🛠️ **Supported environments only:** We only support Windows 11.
|
||||||
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
|
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
|
||||||
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: ⚙️ Issue Checklist
|
|
||||||
options:
|
|
||||||
- label: I have read the guidelines.
|
|
||||||
- label: I checked for duplicate issues.
|
|
||||||
- label: I searched for existing discussions.
|
|
||||||
- label: I checked for an existing pull request that addresses this request.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: problem_statement
|
|
||||||
attributes:
|
|
||||||
label: ❓ Is your feature request related to a problem?
|
|
||||||
placeholder: "Provide a clear and concise description of the issue you're facing. Example: 'I'm always frustrated when [...]'"
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: proposed_solution
|
id: proposed_solution
|
||||||
attributes:
|
attributes:
|
||||||
label: 💡 Describe the solution you'd like
|
label: 💡 Describe the solution you'd like
|
||||||
placeholder: "Provide a clear and concise description of what you want to happen."
|
placeholder: "Provide a clear and concise description."
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: alternatives
|
|
||||||
attributes:
|
|
||||||
label: 🔄 Describe alternatives you've considered
|
|
||||||
placeholder: "Provide details on any alternative solutions or features you've thought about."
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: additional_context
|
|
||||||
attributes:
|
|
||||||
label: 🖼️ Additional context
|
|
||||||
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|||||||
2
.github/workflows/docs.yaml
vendored
2
.github/workflows/docs.yaml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
if: github.repository == 'ChrisTitusTech/winutil'
|
if: github.repository == 'ChrisTitusTech/winutil'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
HUGO_VERSION: 0.147.7
|
HUGO_VERSION: 0.156.0
|
||||||
HUGO_ENVIRONMENT: production
|
HUGO_ENVIRONMENT: production
|
||||||
TZ: America/Chicago
|
TZ: America/Chicago
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -41,6 +41,15 @@
|
|||||||
"winget": "ToEverything.AFFiNE",
|
"winget": "ToEverything.AFFiNE",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"ai-as-workspace": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "AI as Workspace",
|
||||||
|
"description": "Workspace-style AI chat client with multiple workspaces, plugins, and local-first design; open-source (BSD-3-Clause).",
|
||||||
|
"link": "https://aiaw.app/",
|
||||||
|
"winget": "NitroRCr.AIasWorkspace",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
"aimp": {
|
"aimp": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "aimp",
|
"choco": "aimp",
|
||||||
@@ -92,6 +101,15 @@
|
|||||||
"link": "https://anydesk.com/",
|
"link": "https://anydesk.com/",
|
||||||
"winget": "AnyDesk.AnyDesk"
|
"winget": "AnyDesk.AnyDesk"
|
||||||
},
|
},
|
||||||
|
"anythingllm": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "AnythingLLM",
|
||||||
|
"description": "Desktop AI application for chat with documents (RAG) and agent workflows; offers a Windows installer and an open-source codebase.",
|
||||||
|
"link": "https://anythingllm.com/",
|
||||||
|
"winget": "na",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
"audacity": {
|
"audacity": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "audacity",
|
"choco": "audacity",
|
||||||
@@ -126,6 +144,15 @@
|
|||||||
"winget": "AutoHotkey.AutoHotkey",
|
"winget": "AutoHotkey.AutoHotkey",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"autoit": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "autoit.install",
|
||||||
|
"content": "AutoIt",
|
||||||
|
"description": "Windows GUI automation scripting tool (freeware) used to automate keystrokes, mouse actions, and window/control interactions.",
|
||||||
|
"link": "https://www.autoitscript.com/site/autoit/",
|
||||||
|
"winget": "na",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"azuredatastudio": {
|
"azuredatastudio": {
|
||||||
"category": "Microsoft Tools",
|
"category": "Microsoft Tools",
|
||||||
"choco": "azure-data-studio",
|
"choco": "azure-data-studio",
|
||||||
@@ -213,6 +240,15 @@
|
|||||||
"link": "https://www.bulkrenameutility.co.uk",
|
"link": "https://www.bulkrenameutility.co.uk",
|
||||||
"winget": "TGRMNSoftware.BulkRenameUtility"
|
"winget": "TGRMNSoftware.BulkRenameUtility"
|
||||||
},
|
},
|
||||||
|
"buzz": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Buzz",
|
||||||
|
"description": "Offline audio transcription and translation desktop app powered by Whisper, packaged for Windows and available via WinGet.",
|
||||||
|
"link": "https://github.com/chidiwilliams/buzz",
|
||||||
|
"winget": "ChidiWilliams.Buzz",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
"AdvancedRenamer": {
|
"AdvancedRenamer": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "advanced-renamer",
|
"choco": "advanced-renamer",
|
||||||
@@ -221,6 +257,14 @@
|
|||||||
"link": "https://www.advancedrenamer.com/",
|
"link": "https://www.advancedrenamer.com/",
|
||||||
"winget": "HulubuluSoftware.AdvancedRenamer"
|
"winget": "HulubuluSoftware.AdvancedRenamer"
|
||||||
},
|
},
|
||||||
|
"citrixworkspaceapp": {
|
||||||
|
"category": "Utilities",
|
||||||
|
"choco": "citrix-workspace",
|
||||||
|
"content": "Citrix Workspace app",
|
||||||
|
"description": "a secure, unified client application that provides instant access to virtual desktops, SaaS, web, and Windows apps from any device (Windows, macOS, Linux, iOS, Android) or browser.",
|
||||||
|
"link": "https://www.citrix.com/downloads/workspace-app/",
|
||||||
|
"winget": "Citrix.Workspace",
|
||||||
|
},
|
||||||
"calibre": {
|
"calibre": {
|
||||||
"category": "Document",
|
"category": "Document",
|
||||||
"choco": "calibre",
|
"choco": "calibre",
|
||||||
@@ -248,6 +292,14 @@
|
|||||||
"winget": "Cemu.Cemu",
|
"winget": "Cemu.Cemu",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"chatgpt": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "ChatGPT",
|
||||||
|
"description": "ChatGPT desktop app provides direct access to OpenAI's conversational AI assistant for writing, analysis, and productivity tasks.",
|
||||||
|
"link": "https://openai.com/chatgpt/desktop/",
|
||||||
|
"winget": "OpenAI.ChatGPT"
|
||||||
|
},
|
||||||
"chatterino": {
|
"chatterino": {
|
||||||
"category": "Communications",
|
"category": "Communications",
|
||||||
"choco": "chatterino",
|
"choco": "chatterino",
|
||||||
@@ -274,6 +326,24 @@
|
|||||||
"winget": "Hibbiki.Chromium",
|
"winget": "Hibbiki.Chromium",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"claude": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "claude",
|
||||||
|
"content": "Claude",
|
||||||
|
"description": "Anthropic's Claude desktop application for Windows, designed for focused AI-assisted work and chat.",
|
||||||
|
"link": "https://claude.ai/",
|
||||||
|
"winget": "Anthropic.Claude",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
|
"claude-code": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "claude-code",
|
||||||
|
"content": "Claude Code",
|
||||||
|
"description": "Anthropic's agentic coding tool for the terminal/IDE workflows, available on Windows and distributed via WinGet.",
|
||||||
|
"link": "https://code.claude.com/",
|
||||||
|
"winget": "Anthropic.ClaudeCode",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"clementine": {
|
"clementine": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "clementine",
|
"choco": "clementine",
|
||||||
@@ -353,6 +423,15 @@
|
|||||||
"winget": "CrystalDewWorld.CrystalDiskMark",
|
"winget": "CrystalDewWorld.CrystalDiskMark",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"cursor": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "cursoride",
|
||||||
|
"content": "Cursor",
|
||||||
|
"description": "AI-powered code editor (VS Code-based) with agentic coding features and integrated AI assistance for development workflows.",
|
||||||
|
"link": "https://cursor.com/",
|
||||||
|
"winget": "Anysphere.Cursor",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"darktable": {
|
"darktable": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "darktable",
|
"choco": "darktable",
|
||||||
@@ -379,6 +458,15 @@
|
|||||||
"link": "https://www.wagnardsoft.com/display-driver-uninstaller-DDU-",
|
"link": "https://www.wagnardsoft.com/display-driver-uninstaller-DDU-",
|
||||||
"winget": "Wagnardsoft.DisplayDriverUninstaller"
|
"winget": "Wagnardsoft.DisplayDriverUninstaller"
|
||||||
},
|
},
|
||||||
|
"deepl": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "deepl",
|
||||||
|
"content": "DeepL",
|
||||||
|
"description": "DeepL desktop translation and writing assistant for Windows, including shortcuts and in-app writing improvement features.",
|
||||||
|
"link": "https://www.deepl.com/en/windows-app",
|
||||||
|
"winget": "DeepL.DeepL",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"deluge": {
|
"deluge": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "deluge",
|
"choco": "deluge",
|
||||||
@@ -831,6 +919,15 @@
|
|||||||
"winget": "GitHub.cli",
|
"winget": "GitHub.cli",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"github-copilot-cli": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "GitHub Copilot CLI",
|
||||||
|
"description": "GitHub Copilot experience for the command line: natural-language assistance for commands and development tasks; distributed via WinGet.",
|
||||||
|
"link": "https://github.com/github/copilot-cli",
|
||||||
|
"winget": "GitHub.Copilot",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"githubdesktop": {
|
"githubdesktop": {
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"choco": "git;github-desktop",
|
"choco": "git;github-desktop",
|
||||||
@@ -899,6 +996,15 @@
|
|||||||
"link": "https://www.google.com/drive/",
|
"link": "https://www.google.com/drive/",
|
||||||
"winget": "Google.GoogleDrive"
|
"winget": "Google.GoogleDrive"
|
||||||
},
|
},
|
||||||
|
"gpt4all": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "gpt4all",
|
||||||
|
"content": "GPT4All",
|
||||||
|
"description": "Open-source desktop application to run LLMs locally with an emphasis on privacy (MIT-licensed codebase).",
|
||||||
|
"link": "https://nomic.ai/gpt4all",
|
||||||
|
"winget": "nomic.gpt4all",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
"gpuz": {
|
"gpuz": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "gpu-z",
|
"choco": "gpu-z",
|
||||||
@@ -1055,6 +1161,15 @@
|
|||||||
"winget": "SFLinux.Jami",
|
"winget": "SFLinux.Jami",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"jan": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "jan",
|
||||||
|
"content": "Jan",
|
||||||
|
"description": "Open-source ChatGPT alternative that runs on your computer (offline-first desktop AI assistant / local model runner).",
|
||||||
|
"link": "https://jan.ai/",
|
||||||
|
"winget": "Jan.Jan",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
"java8": {
|
"java8": {
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"choco": "corretto8jdk",
|
"choco": "corretto8jdk",
|
||||||
@@ -1258,6 +1373,15 @@
|
|||||||
"winget": "rocksdanister.LivelyWallpaper",
|
"winget": "rocksdanister.LivelyWallpaper",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"lm-studio": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "lm-studio",
|
||||||
|
"content": "LM Studio",
|
||||||
|
"description": "Desktop app to discover, download, and run local LLMs on your machine, with a built-in chat UI and local inference tooling.",
|
||||||
|
"link": "https://lmstudio.ai/",
|
||||||
|
"winget": "ElementLabs.LMStudio",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"localsend": {
|
"localsend": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "localsend.install",
|
"choco": "localsend.install",
|
||||||
@@ -1284,6 +1408,14 @@
|
|||||||
"winget": "Logseq.Logseq",
|
"winget": "Logseq.Logseq",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"logitechghub": {
|
||||||
|
"category": "Utilities",
|
||||||
|
"choco": "lghub",
|
||||||
|
"content": "Logitech G Hub",
|
||||||
|
"description": "Official software for managing Logitech gaming peripherals (mice, keyboards, headsets, lighting profiles, etc.).",
|
||||||
|
"link": "https://www.logitechg.com/en-us/software/ghub",
|
||||||
|
"winget": "Logitech.GHUB"
|
||||||
|
},
|
||||||
"malwarebytes": {
|
"malwarebytes": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "malwarebytes",
|
"choco": "malwarebytes",
|
||||||
@@ -1318,6 +1450,24 @@
|
|||||||
"link": "https://meldmerge.org/",
|
"link": "https://meldmerge.org/",
|
||||||
"winget": "Meld.Meld",
|
"winget": "Meld.Meld",
|
||||||
"foss": true
|
"foss": true
|
||||||
|
},
|
||||||
|
"microsoft-aishell": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Microsoft AI Shell",
|
||||||
|
"description": "CLI shell that connects to AI assistance providers ('agents') for command-line productivity; distributed via WinGet.",
|
||||||
|
"link": "https://github.com/PowerShell/AIShell",
|
||||||
|
"winget": "Microsoft.AIShell",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
|
"microsoft-copilot": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Microsoft Copilot",
|
||||||
|
"description": "Microsoft Copilot desktop app for Windows (consumer Copilot), distributed via Microsoft Store and commonly installed via its Store ID.",
|
||||||
|
"link": "https://apps.microsoft.com/detail/9nht9rb2f4hd",
|
||||||
|
"winget": "9NHT9RB2F4HD",
|
||||||
|
"foss": false
|
||||||
},
|
},
|
||||||
"ModernFlyouts": {
|
"ModernFlyouts": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
@@ -1643,6 +1793,15 @@
|
|||||||
"winget": "KDE.Okular",
|
"winget": "KDE.Okular",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
|
"ollama": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Ollama",
|
||||||
|
"description": "Ollama lets you run and manage local large language models on your desktop.",
|
||||||
|
"link": "https://ollama.com/",
|
||||||
|
"winget": "Ollama.Ollama",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
"onedrive": {
|
"onedrive": {
|
||||||
"category": "Microsoft Tools",
|
"category": "Microsoft Tools",
|
||||||
"choco": "onedrive",
|
"choco": "onedrive",
|
||||||
@@ -1748,6 +1907,15 @@
|
|||||||
"link": "https://potplayer.tv/",
|
"link": "https://potplayer.tv/",
|
||||||
"winget": "Daum.PotPlayer"
|
"winget": "Daum.PotPlayer"
|
||||||
},
|
},
|
||||||
|
"power-automate-desktop": {
|
||||||
|
"category": "AI-Automation",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Power Automate for desktop",
|
||||||
|
"description": "Microsoft's Windows RPA tool for building desktop flows to automate repetitive tasks across apps and services.",
|
||||||
|
"link": "https://powerautomate.microsoft.com/desktop/",
|
||||||
|
"winget": "na",
|
||||||
|
"foss": false
|
||||||
|
},
|
||||||
"processexplorer": {
|
"processexplorer": {
|
||||||
"category": "Microsoft Tools",
|
"category": "Microsoft Tools",
|
||||||
"choco": "na",
|
"choco": "na",
|
||||||
@@ -1772,6 +1940,14 @@
|
|||||||
"link": "https://parsec.app/",
|
"link": "https://parsec.app/",
|
||||||
"winget": "Parsec.Parsec"
|
"winget": "Parsec.Parsec"
|
||||||
},
|
},
|
||||||
|
"pdf-xchange": {
|
||||||
|
"category": "Document",
|
||||||
|
"choco": "pdfxchangeeditor",
|
||||||
|
"content": "PDF-XChangeEditor",
|
||||||
|
"description": "a comprehensive Windows-based software suite and editor for creating, viewing, editing, annotating, and signing PDF files.",
|
||||||
|
"link": "https://www.pdf-xchange.com/",
|
||||||
|
"winget": "TrackerSoftware.PDF-XChangeEditor"
|
||||||
|
},
|
||||||
"pdf24creator": {
|
"pdf24creator": {
|
||||||
"category": "Document",
|
"category": "Document",
|
||||||
"choco": "pdf24",
|
"choco": "pdf24",
|
||||||
@@ -2584,7 +2760,7 @@
|
|||||||
"winget": "GianlucaPernigotto.Videomass",
|
"winget": "GianlucaPernigotto.Videomass",
|
||||||
"foss": true
|
"foss": true
|
||||||
},
|
},
|
||||||
"visualstudio": {
|
"visualstudio2022": {
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"choco": "visualstudio2022community",
|
"choco": "visualstudio2022community",
|
||||||
"content": "Visual Studio 2022",
|
"content": "Visual Studio 2022",
|
||||||
@@ -2592,6 +2768,14 @@
|
|||||||
"link": "https://visualstudio.microsoft.com/",
|
"link": "https://visualstudio.microsoft.com/",
|
||||||
"winget": "Microsoft.VisualStudio.2022.Community"
|
"winget": "Microsoft.VisualStudio.2022.Community"
|
||||||
},
|
},
|
||||||
|
"visualstudio2026": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "visualstudio2026community",
|
||||||
|
"content": "Visual Studio 2026",
|
||||||
|
"description": "Visual Studio 2026 is an integrated development environment (IDE) for building, debugging, and deploying applications.",
|
||||||
|
"link": "https://visualstudio.microsoft.com/",
|
||||||
|
"winget": "Microsoft.VisualStudio.2026.Community"
|
||||||
|
},
|
||||||
"vivaldi": {
|
"vivaldi": {
|
||||||
"category": "Browsers",
|
"category": "Browsers",
|
||||||
"choco": "vivaldi",
|
"choco": "vivaldi",
|
||||||
@@ -3146,6 +3330,14 @@
|
|||||||
"link": "https://www.dropbox.com/en_GB/desktop",
|
"link": "https://www.dropbox.com/en_GB/desktop",
|
||||||
"winget": "Dropbox.Dropbox"
|
"winget": "Dropbox.Dropbox"
|
||||||
},
|
},
|
||||||
|
"Overwolf": {
|
||||||
|
"category": "Games",
|
||||||
|
"choco": "overwolf",
|
||||||
|
"content": "Overwolf",
|
||||||
|
"description": "Popular platform for game overlays and companion apps (mod managers, trackers, etc.), widely used by gamers.",
|
||||||
|
"link": "https://www.overwolf.com/app/overwolf-curseforge",
|
||||||
|
"winget": "Overwolf.CurseForge"
|
||||||
|
},
|
||||||
"OFGB": {
|
"OFGB": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "ofgb",
|
"choco": "ofgb",
|
||||||
|
|||||||
@@ -88,9 +88,9 @@
|
|||||||
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/widget"
|
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/widget"
|
||||||
},
|
},
|
||||||
"WPFTweaksRevertStartMenu": {
|
"WPFTweaksRevertStartMenu": {
|
||||||
"Content": "Revert the new start menu",
|
"Content": "Revert Start Menu layout",
|
||||||
"Description": "Uses vivetool to revert to the original start menu from 24H2.",
|
"Description": "Bring back the old Start Menu layout from before the gradual rollout of the new one in 25H2.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "Essential Tweaks",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
@@ -120,7 +120,20 @@
|
|||||||
Write-Host 'New start menu reverted please restart your computer to take effect'
|
Write-Host 'New start menu reverted please restart your computer to take effect'
|
||||||
"
|
"
|
||||||
],
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/revertstartmenu"
|
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/revertstartmenu"
|
||||||
|
},
|
||||||
|
"WPFTweaksDisableStoreSearch": {
|
||||||
|
"Content": "Disable Microsoft Store search results",
|
||||||
|
"Description": "Will not display recommended Microsoft Store apps when searching for apps in the Start menu.",
|
||||||
|
"category": "Essential Tweaks",
|
||||||
|
"panel": "1",
|
||||||
|
"InvokeScript": [
|
||||||
|
"icacls \"$Env:LocalAppData\\Packages\\Microsoft.WindowsStore_8wekyb3d8bbwe\\LocalState\\store.db\" /deny Everyone:F"
|
||||||
|
],
|
||||||
|
"UndoScript": [
|
||||||
|
"icacls \"$Env:LocalAppData\\Packages\\Microsoft.WindowsStore_8wekyb3d8bbwe\\LocalState\\store.db\" /grant Everyone:F"
|
||||||
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/disablestoresearch"
|
||||||
},
|
},
|
||||||
"WPFTweaksLocation": {
|
"WPFTweaksLocation": {
|
||||||
"Content": "Disable Location Tracking",
|
"Content": "Disable Location Tracking",
|
||||||
@@ -1635,6 +1648,15 @@
|
|||||||
"Description": "Removes Xbox services, the Xbox app, Game Bar, and related authentication components.",
|
"Description": "Removes Xbox services, the Xbox app, Game Bar, and related authentication components.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
|
"registry": [
|
||||||
|
{
|
||||||
|
"Path": "KCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\GameDVR",
|
||||||
|
"Name": "AppCaptureEnabled",
|
||||||
|
"Value": "0",
|
||||||
|
"Type": "DWord",
|
||||||
|
"OriginalValue": "1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"appx": [
|
"appx": [
|
||||||
"Microsoft.XboxIdentityProvider",
|
"Microsoft.XboxIdentityProvider",
|
||||||
"Microsoft.XboxSpeechToTextOverlay",
|
"Microsoft.XboxSpeechToTextOverlay",
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ graph TD
|
|||||||
|
|
||||||
### Testing your changes
|
### Testing your changes
|
||||||
|
|
||||||
* To test to see if your changes work as intended run following commands in a powershell teminal as admin:
|
* To test to see if your changes work as intended run following commands in a powershell terminal as admin:
|
||||||
|
|
||||||
* Change the directory where you are running the commands to the forked project.
|
* Change the directory where you are running the commands to the forked project.
|
||||||
* `cd {path to the folder with the compile.ps1}`
|
* `cd {path to the folder with the compile.ps1}`
|
||||||
|
|||||||
@@ -11,14 +11,7 @@ If `https://christitus.com/win` is not working, or you want to download the code
|
|||||||
irm https://github.com/ChrisTitusTech/Winutil/releases/latest/download/Winutil.ps1 | iex
|
irm https://github.com/ChrisTitusTech/Winutil/releases/latest/download/Winutil.ps1 | iex
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are seeing errors referencing TLS or security, you may be running an older version of Windows where TLS 1.2 is not the default security protocol used for network connections. The following commands will force .NET to use TLS 1.2, and download the script directly using .NET instead of PowerShell:
|
If it still isn't working in your region, it may be due to temporary ISP or network filtering of GitHub content domains. This has been reported by some users in India in the past. See: [Times of India](https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms).
|
||||||
|
|
||||||
```
|
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
|
||||||
iex https://christitus.com/win | iex
|
|
||||||
```
|
|
||||||
|
|
||||||
If it still isn't working and you live in India, it might be due to India blocking GitHub's content domain and preventing downloads. See more on [Times of India](https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms).
|
|
||||||
|
|
||||||
If you are still having issues, try using a **VPN**, or changing your **DNS provider** to one of following two providers:
|
If you are still having issues, try using a **VPN**, or changing your **DNS provider** to one of following two providers:
|
||||||
|
|
||||||
@@ -34,160 +27,3 @@ If your PowerShell session is running in **Constrained Language Mode**, some scr
|
|||||||
$ExecutionContext.SessionState.LanguageMode
|
$ExecutionContext.SessionState.LanguageMode
|
||||||
```
|
```
|
||||||
If it returns `ConstrainedLanguage`, you may need to switch to `FullLanguage` mode or run the script in a session with administrative privileges. Be aware that some security policies may enforce Constrained Language Mode, especially in corporate or managed environments.
|
If it returns `ConstrainedLanguage`, you may need to switch to `FullLanguage` mode or run the script in a session with administrative privileges. Be aware that some security policies may enforce Constrained Language Mode, especially in corporate or managed environments.
|
||||||
|
|
||||||
### Script blocked by Execution Policy
|
|
||||||
|
|
||||||
1. Ensure you are running PowerShell as admin: Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
|
|
||||||
2. In the PowerShell window, type this to allow unsigned code to execute and run the installation script:
|
|
||||||
|
|
||||||
```
|
|
||||||
Set-ExecutionPolicy Unrestricted -Scope Process -Force
|
|
||||||
irm https://christitus.com/win | iex
|
|
||||||
```
|
|
||||||
|
|
||||||
## Runtime Issues
|
|
||||||
|
|
||||||
### WinGet configuration
|
|
||||||
|
|
||||||
If you have not installed anything using PowerShell before, you may be prompted to configure WinGet. This requires user interaction on first run. You will need to manually type `y` into the PowerShell console and press enter to continue. Once you do it the first time, you will not be prompted again.
|
|
||||||
|
|
||||||
## Windows Issues
|
|
||||||
|
|
||||||
### Windows takes longer to shut down
|
|
||||||
|
|
||||||
This could be for a number of reasons:
|
|
||||||
|
|
||||||
- Turn on fast startup: Press `Windows key`+`R`, then type:
|
|
||||||
|
|
||||||
```bat
|
|
||||||
control /name Microsoft.PowerOptions /page pageGlobalSettings
|
|
||||||
```
|
|
||||||
|
|
||||||
If that doesn't work, disable Hibernation:
|
|
||||||
|
|
||||||
- Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11. then type:
|
|
||||||
|
|
||||||
```bat
|
|
||||||
powercfg /H off
|
|
||||||
```
|
|
||||||
|
|
||||||
Related issue: [#69](https://github.com/ChrisTitusTech/Winutil/issues/69)
|
|
||||||
|
|
||||||
### Windows Search does not work
|
|
||||||
|
|
||||||
Enable Background Apps. Related issues: [#69](https://github.com/ChrisTitusTech/Winutil/issues/69) [#95](https://github.com/ChrisTitusTech/Winutil/issues/95) [#232](https://github.com/ChrisTitusTech/Winutil/issues/232)
|
|
||||||
|
|
||||||
### Xbox Game Bar Activation Broken
|
|
||||||
|
|
||||||
Set the Xbox Accessory Management Service to Automatic:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
Get-Service -Name "XboxGipSvc" | Set-Service -StartupType Automatic
|
|
||||||
```
|
|
||||||
|
|
||||||
Related issue: [#198](https://github.com/ChrisTitusTech/Winutil/issues/198)
|
|
||||||
|
|
||||||
### Windows 11: Quick Settings no longer works
|
|
||||||
|
|
||||||
Launch the Script and click _Enable Action Center_.
|
|
||||||
|
|
||||||
### Explorer (file browser) no longer launches
|
|
||||||
|
|
||||||
- Press `Windows key`+`R` then type:
|
|
||||||
|
|
||||||
```bat
|
|
||||||
control /name Microsoft.FolderOptions
|
|
||||||
```
|
|
||||||
|
|
||||||
- Change the _Open File Explorer to_ option to _This PC_.
|
|
||||||
|
|
||||||
### Battery drains too fast
|
|
||||||
|
|
||||||
If you're using a laptop or tablet and find your battery drains too fast, please try the below troubleshooting steps, and report the results back to the Winutil community.
|
|
||||||
|
|
||||||
1. **Check Battery Health:**
|
|
||||||
- Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
|
|
||||||
- Run the following command to generate a battery report:
|
|
||||||
```powershell
|
|
||||||
powercfg /batteryreport /output "C:\battery_report.html"
|
|
||||||
```
|
|
||||||
- Open the generated HTML report to review information about battery health and usage. A battery with poor health may hold less charge, discharge faster, or cause other issues.
|
|
||||||
|
|
||||||
2. **Review Power Settings:**
|
|
||||||
- Open the Settings app, and go to _System_ > _Power & sleep_.
|
|
||||||
- Adjust power plan settings based on your preferences and usage patterns.
|
|
||||||
- Click on _Additional power settings_ to access advanced power settings that may help.
|
|
||||||
|
|
||||||
3. **Identify Power-Hungry Apps:**
|
|
||||||
- Right-click on the taskbar and select _Task Manager_.
|
|
||||||
- Navigate to the _Processes_ tab to identify applications with high CPU or memory usage.
|
|
||||||
- Consider reconfiguring, closing, disabling, or uninstalling applications that use a lot of resources.
|
|
||||||
|
|
||||||
4. **Update Drivers:**
|
|
||||||
- Visit your device manufacturer's website or use Windows Update to check for driver updates.
|
|
||||||
- Ensure graphics, chipset, and other essential drivers are up to date.
|
|
||||||
|
|
||||||
5. **Check for Windows Updates:**
|
|
||||||
- Open the Settings app, and go to _Update & Security_ > _Windows Update_.
|
|
||||||
- Check for and install any available updates for your operating system.
|
|
||||||
|
|
||||||
6. **Reduce Screen Brightness:**
|
|
||||||
- Open the Settings app, and go to _System_ > _Display_.
|
|
||||||
- Adjust screen brightness based on your preferences and lighting conditions.
|
|
||||||
|
|
||||||
7. **Enable Battery Saver:**
|
|
||||||
- Open the Settings app, and go to _System_ > _Battery_.
|
|
||||||
- Turn on _Battery saver_ to limit background activity and conserve power.
|
|
||||||
|
|
||||||
8. **Check Power Usage in Settings:**
|
|
||||||
- Open the Settings app, and go to _System_ > _Battery_ > _Battery usage by app_.
|
|
||||||
- Review the list of apps and their power usage. Disable or uninstall any you don't need.
|
|
||||||
|
|
||||||
9. **Check Background Apps:**
|
|
||||||
- Open the Settings app, and go to _Privacy_ > _Background apps_.
|
|
||||||
- Disable or uninstall unnecessary apps running in the background.
|
|
||||||
|
|
||||||
10. **Use `powercfg` for Analysis:**
|
|
||||||
- Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
|
|
||||||
- Run the following command to analyze energy usage and generate a report:
|
|
||||||
```powershell
|
|
||||||
powercfg /energy /output "C:\energy_report.html"
|
|
||||||
```
|
|
||||||
- Open the generated HTML report to identify energy consumption patterns.
|
|
||||||
|
|
||||||
11. **Review Event Logs:**
|
|
||||||
- Open Event Viewer by searching for it in the Start menu.
|
|
||||||
- Navigate to _Windows Logs_ > _System_.
|
|
||||||
- Look for events with the source _Power-Troubleshooter_ to identify power-related events. These may highlight battery, input power, and other issues.
|
|
||||||
|
|
||||||
12. **Check Wake-up Sources:**
|
|
||||||
- Press `Windows Key`+`X` and select _PowerShell (Admin)_ in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
|
|
||||||
- Use the command `powercfg /requests` to identify processes preventing sleep.
|
|
||||||
- Use the command `powercfg /waketimers` to view active wake timers.
|
|
||||||
- Check Task Scheduler to see if any of the discovered processes are scheduled to start on boot or at regular intervals.
|
|
||||||
|
|
||||||
13. **Advanced Identification of Power-Hungry Apps:**
|
|
||||||
- Open Resource Monitor from the Start menu.
|
|
||||||
- Navigate to the _CPU_, _Memory_, _Network_, and other tabs to identify processes with high resource usage.
|
|
||||||
- Consider reconfiguring, closing, disabling, or uninstalling applications that use a lot of resources.
|
|
||||||
|
|
||||||
14. **Disable Activity History:**
|
|
||||||
- Open the Settings app, and go to _Privacy_ > _Activity history_.
|
|
||||||
- Turn off _Let Windows collect my activities from this PC_.
|
|
||||||
|
|
||||||
15. **Prevent Network Adapters From Waking PC:**
|
|
||||||
- Open Device Manager by searching for it in the Start menu.
|
|
||||||
- Locate your network adapter, right-click, and go to _Properties_.
|
|
||||||
- Under the _Power Management_ tab, uncheck the option that allows the device to wake the computer.
|
|
||||||
|
|
||||||
16. **Review Installed Applications:**
|
|
||||||
- Manually review installed applications by searching for _Add or remove programs_ in the Start menu.
|
|
||||||
- Check settings/preferences of individual applications for power-related options.
|
|
||||||
- Uninstall unnecessary or problematic software.
|
|
||||||
|
|
||||||
These troubleshooting steps are generic, but should help in most situations. You should have these key takeaways:
|
|
||||||
|
|
||||||
- Battery health is the most significant limiter on your device's runtime. A battery in poor health usually cannot be made to last like it used to, simply by closing some applications. Consider replacing your battery.
|
|
||||||
- Background applications that use CPU and memory, make lots of or large network requests, read/write to disk frequently, or that keep your PC awake when it could be conserving energy are the next major concern. Avoid installing programs you don't need, only use programs you trust, and configure applications to use as little power and run as infrequently as possible.
|
|
||||||
- Windows performs a lot of tasks that may affect battery life by default. Changing settings, stopping scheduled tasks, and disabling features can help the system stay in lower power states to conserve battery.
|
|
||||||
- Bad chargers, inconsistent power input, and high temperatures will cause batteries to degrade and discharge faster. Use trusted high-quality chargers, ensure input power is steady, clean any fans or airflow ports, and keep the battery/PC cool.
|
|
||||||
|
|||||||
@@ -128,6 +128,154 @@ winutil/
|
|||||||
- CheckBoxes for options
|
- CheckBoxes for options
|
||||||
- ListBoxes for selections
|
- ListBoxes for selections
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
**Core Functions** (`functions/private/`):
|
||||||
|
- `Invoke-WinUtilISO.ps1`: Main orchestrator containing all Win11 Creator functions
|
||||||
|
- `Invoke-WinUtilISOBrowse`: ISO file selection dialog
|
||||||
|
- `Invoke-WinUtilISOMountAndVerify`: Validates and mounts ISO, verifies it's official Windows 11
|
||||||
|
- `Invoke-WinUtilISOModify`: Launches modification in background runspace
|
||||||
|
- `Invoke-WinUtilISOExport`: Handles ISO and USB export
|
||||||
|
- `Invoke-WinUtilISOCheckExistingWork`: Recovers incomplete work sessions
|
||||||
|
- `Invoke-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 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
|
||||||
|
|
||||||
|
```
|
||||||
|
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 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 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 state
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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 script (reversible)
|
||||||
|
- Original ISO never modified; only working copy
|
||||||
|
- Logged to `WinUtil_Win11ISO.log` for debugging
|
||||||
|
- DISM handles image dismount with automatic cleanup on error
|
||||||
|
|
||||||
|
### 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 taskbar
|
||||||
|
- Disable OneDrive folder backup
|
||||||
|
- Disable Copilot
|
||||||
|
- Disable Windows Update during OOBE (re-enabled at first login)
|
||||||
|
|
||||||
|
### 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.wim` index 2 (Windows Setup PE environment)
|
||||||
|
|
||||||
|
**Use Case**: Enables offline installation on systems with missing drivers.
|
||||||
|
|
||||||
|
### 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
|
## Data Flow
|
||||||
|
|
||||||
### Application Installation Flow
|
### Application Installation Flow
|
||||||
@@ -463,7 +611,7 @@ Outputs `winutil.ps1` in the root directory.
|
|||||||
**Required**:
|
**Required**:
|
||||||
- PowerShell 5.1+
|
- PowerShell 5.1+
|
||||||
- .NET Framework 4.5+
|
- .NET Framework 4.5+
|
||||||
- Windows 10 1809+
|
- Windows 11
|
||||||
|
|
||||||
**Optional (auto-installed)**:
|
**Optional (auto-installed)**:
|
||||||
- WinGet (Windows Package Manager)
|
- WinGet (Windows Package Manager)
|
||||||
@@ -514,6 +662,7 @@ Outputs `winutil.ps1` in the root directory.
|
|||||||
|
|
||||||
- [Contributing Guide](../../contributing/) - How to contribute code
|
- [Contributing Guide](../../contributing/) - How to contribute code
|
||||||
- [User Guide](../../userguide/) - End-user documentation
|
- [User Guide](../../userguide/) - End-user documentation
|
||||||
|
- [Win11 Creator Guide](../../userguide/win11Creator/) - Building customized Windows 11 ISOs
|
||||||
- [FAQ](../../faq/) - Common questions
|
- [FAQ](../../faq/) - Common questions
|
||||||
|
|
||||||
## Additional Resources
|
## Additional Resources
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function Invoke-WPFFixesWinget {
|
|||||||
try {
|
try {
|
||||||
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||||
Write-Host "==> Starting Winget Repair"
|
Write-Host "==> Starting Winget Repair"
|
||||||
Install-WinUtilWinget -Force
|
Install-WinUtilWinget
|
||||||
} catch {
|
} catch {
|
||||||
Write-Error "Failed to install winget: $_"
|
Write-Error "Failed to install winget: $_"
|
||||||
Set-WinUtilTaskbaritem -state "Error" -overlay "warning"
|
Set-WinUtilTaskbaritem -state "Error" -overlay "warning"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Bing Search in Start Menu"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2185}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2207}
|
||||||
"WPFToggleBingSearch": {
|
"WPFToggleBingSearch": {
|
||||||
"Content": "Bing Search in Start Menu",
|
"Content": "Bing Search in Start Menu",
|
||||||
"Description": "If enabled, Bing web search results will be included in your Start Menu search.",
|
"Description": "If enabled, Bing web search results will be included in your Start Menu search.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Dark Theme for Windows"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2143}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2165}
|
||||||
"WPFToggleDarkMode": {
|
"WPFToggleDarkMode": {
|
||||||
"Content": "Dark Theme for Windows",
|
"Content": "Dark Theme for Windows",
|
||||||
"Description": "Enable/Disable Dark Mode.",
|
"Description": "Enable/Disable Dark Mode.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Detailed BSoD"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2559}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2581}
|
||||||
"WPFToggleDetailedBSoD": {
|
"WPFToggleDetailedBSoD": {
|
||||||
"Content": "Detailed BSoD",
|
"Content": "Detailed BSoD",
|
||||||
"Description": "If enabled, you will see a detailed Blue Screen of Death (BSOD) with more information.",
|
"Description": "If enabled, you will see a detailed Blue Screen of Death (BSOD) with more information.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Cross-Device Resume"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2689}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2711}
|
||||||
"WPFToggleDisableCrossDeviceResume": {
|
"WPFToggleDisableCrossDeviceResume": {
|
||||||
"Content": "Cross-Device Resume",
|
"Content": "Cross-Device Resume",
|
||||||
"Description": "This tweak controls the Resume function in Windows 11 24H2 and later, which allows you to resume an activity from a mobile device and vice-versa.",
|
"Description": "This tweak controls the Resume function in Windows 11 24H2 and later, which allows you to resume an activity from a mobile device and vice-versa.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Show Hidden Files"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2439}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2461}
|
||||||
"WPFToggleHiddenFiles": {
|
"WPFToggleHiddenFiles": {
|
||||||
"Content": "Show Hidden Files",
|
"Content": "Show Hidden Files",
|
||||||
"Description": "If enabled, Hidden Files will be shown.",
|
"Description": "If enabled, Hidden Files will be shown.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove Settings Home Page"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2309}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2331}
|
||||||
"WPFToggleHideSettingsHome": {
|
"WPFToggleHideSettingsHome": {
|
||||||
"Content": "Remove Settings Home Page",
|
"Content": "Remove Settings Home Page",
|
||||||
"Description": "Removes the Home Page in the Windows Settings app.",
|
"Description": "Removes the Home Page in the Windows Settings app.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Mouse Acceleration"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2327}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2349}
|
||||||
"WPFToggleMouseAcceleration": {
|
"WPFToggleMouseAcceleration": {
|
||||||
"Content": "Mouse Acceleration",
|
"Content": "Mouse Acceleration",
|
||||||
"Description": "If enabled, the Cursor movement is affected by the speed of your physical mouse movements.",
|
"Description": "If enabled, the Cursor movement is affected by the speed of your physical mouse movements.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Multiplane Overlay"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2421}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2443}
|
||||||
"WPFToggleMultiplaneOverlay": {
|
"WPFToggleMultiplaneOverlay": {
|
||||||
"Content": "Disable Multiplane Overlay",
|
"Content": "Disable Multiplane Overlay",
|
||||||
"Description": "Disable the Multiplane Overlay which can sometimes cause issues with Graphics Cards.",
|
"Description": "Disable the Multiplane Overlay which can sometimes cause issues with Graphics Cards.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "New Outlook"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2379}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2401}
|
||||||
"WPFToggleNewOutlook": {
|
"WPFToggleNewOutlook": {
|
||||||
"Content": "New Outlook",
|
"Content": "New Outlook",
|
||||||
"Description": "If disabled, it removes the new Outlook toggle, disables the new Outlook migration, and ensures the classic Outlook application is used.",
|
"Description": "If disabled, it removes the new Outlook toggle, disables the new Outlook migration, and ensures the classic Outlook application is used.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Num Lock on Startup"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2221}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2243}
|
||||||
"WPFToggleNumLock": {
|
"WPFToggleNumLock": {
|
||||||
"Content": "Num Lock on Startup",
|
"Content": "Num Lock on Startup",
|
||||||
"Description": "Toggle the Num Lock key state when your computer starts.",
|
"Description": "Toggle the Num Lock key state when your computer starts.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "S3 Sleep"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2585}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2607}
|
||||||
"WPFToggleS3Sleep": {
|
"WPFToggleS3Sleep": {
|
||||||
"Content": "S3 Sleep",
|
"Content": "S3 Sleep",
|
||||||
"Description": "Toggles between Modern Standby and S3 Sleep.",
|
"Description": "Toggles between Modern Standby and S3 Sleep.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Show File Extensions"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2467}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2489}
|
||||||
"WPFToggleShowExt": {
|
"WPFToggleShowExt": {
|
||||||
"Content": "Show File Extensions",
|
"Content": "Show File Extensions",
|
||||||
"Description": "If enabled, File extensions (e.g., .txt, .jpg) are visible.",
|
"Description": "If enabled, File extensions (e.g., .txt, .jpg) are visible.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Modern Standby fix"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2203}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2225}
|
||||||
"WPFToggleStandbyFix": {
|
"WPFToggleStandbyFix": {
|
||||||
"Content": "Modern Standby fix",
|
"Content": "Modern Standby fix",
|
||||||
"Description": "Disable network connection during S0 sleep. If network connectivity is turned on during S0 sleep it could cause overheating on modern laptops",
|
"Description": "Disable network connection during S0 sleep. If network connectivity is turned on during S0 sleep it could cause overheating on modern laptops",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Recommendations in Start Menu"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2265}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2287}
|
||||||
"WPFToggleStartMenuRecommendations": {
|
"WPFToggleStartMenuRecommendations": {
|
||||||
"Content": "Recommendations in Start Menu",
|
"Content": "Recommendations in Start Menu",
|
||||||
"Description": "If disabled, then you will not see recommendations in the Start Menu. WARNING: This will also disable Windows Spotlight on your Lock Screen as a side effect.",
|
"Description": "If disabled, then you will not see recommendations 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: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2361}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2383}
|
||||||
"WPFToggleStickyKeys": {
|
"WPFToggleStickyKeys": {
|
||||||
"Content": "Sticky Keys",
|
"Content": "Sticky Keys",
|
||||||
"Description": "If enabled, Sticky Keys is activated. Sticky keys is an accessibility feature of some graphical user interfaces which assists users who have physical disabilities or help users reduce repetitive strain injury.",
|
"Description": "If enabled, Sticky Keys is activated. Sticky keys is an accessibility feature of some graphical user interfaces which assists users who have physical disabilities or help users reduce repetitive strain injury.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Task View Button in Taskbar"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2513}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2535}
|
||||||
"WPFToggleTaskView": {
|
"WPFToggleTaskView": {
|
||||||
"Content": "Task View Button in Taskbar",
|
"Content": "Task View Button in Taskbar",
|
||||||
"Description": "If enabled, Task View Button in Taskbar will be shown.",
|
"Description": "If enabled, Task View Button in Taskbar will be shown.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Center Taskbar Items"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2531}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2553}
|
||||||
"WPFToggleTaskbarAlignment": {
|
"WPFToggleTaskbarAlignment": {
|
||||||
"Content": "Center Taskbar Items",
|
"Content": "Center Taskbar Items",
|
||||||
"Description": "[Windows 11] If enabled, the Taskbar Items will be shown on the Center, otherwise the Taskbar Items will be shown on the Left.",
|
"Description": "[Windows 11] If enabled, the Taskbar Items will be shown on the Center, otherwise the Taskbar Items will be shown on the Left.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Search Button in Taskbar"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2495}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2517}
|
||||||
"WPFToggleTaskbarSearch": {
|
"WPFToggleTaskbarSearch": {
|
||||||
"Content": "Search Button in Taskbar",
|
"Content": "Search Button in Taskbar",
|
||||||
"Description": "If enabled, Search Button will be on the Taskbar.",
|
"Description": "If enabled, Search Button will be on the Taskbar.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Verbose Messages During Logon"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2247}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2269}
|
||||||
"WPFToggleVerboseLogon": {
|
"WPFToggleVerboseLogon": {
|
||||||
"Content": "Verbose Messages During Logon",
|
"Content": "Verbose Messages During Logon",
|
||||||
"Description": "Show detailed messages during the login process for troubleshooting and diagnostics.",
|
"Description": "Show detailed messages during the login process for troubleshooting and diagnostics.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable ConsumerFeatures"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1291}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1304}
|
||||||
"WPFTweaksConsumerFeatures": {
|
"WPFTweaksConsumerFeatures": {
|
||||||
"Content": "Disable ConsumerFeatures",
|
"Content": "Disable ConsumerFeatures",
|
||||||
"Description": "Windows will not automatically install any games, third-party apps, or application links from the Windows Store for the signed-in user. Some default Apps will be inaccessible (eg. Phone Link).",
|
"Description": "Windows will not automatically install any games, third-party apps, or application links from the Windows Store for the signed-in user. Some default Apps will be inaccessible (eg. Phone Link).",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Delete Temporary Files"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2038}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2060}
|
||||||
"WPFTweaksDeleteTempFiles": {
|
"WPFTweaksDeleteTempFiles": {
|
||||||
"Content": "Delete Temporary Files",
|
"Content": "Delete Temporary Files",
|
||||||
"Description": "Erases TEMP Folders.",
|
"Description": "Erases TEMP Folders.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Explorer Automatic Folder Discovery"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2634}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2656}
|
||||||
"WPFTweaksDisableExplorerAutoDiscovery": {
|
"WPFTweaksDisableExplorerAutoDiscovery": {
|
||||||
"Content": "Disable Explorer Automatic Folder Discovery",
|
"Content": "Disable Explorer Automatic Folder Discovery",
|
||||||
"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.",
|
"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.",
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: "Disable Microsoft Store search results"
|
||||||
|
description: ""
|
||||||
|
---
|
||||||
|
|
||||||
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=125}
|
||||||
|
"WPFTweaksDisableStoreSearch": {
|
||||||
|
"Content": "Disable Microsoft Store search results",
|
||||||
|
"Description": "Will not display recommended Microsoft Store apps when searching for apps in the Start menu.",
|
||||||
|
"category": "Essential Tweaks",
|
||||||
|
"panel": "1",
|
||||||
|
"InvokeScript": [
|
||||||
|
"icacls \"$Env:LocalAppData\\Packages\\Microsoft.WindowsStore_8wekyb3d8bbwe\\LocalState\\store.db\" /deny Everyone:F"
|
||||||
|
],
|
||||||
|
"UndoScript": [
|
||||||
|
"icacls \"$Env:LocalAppData\\Packages\\Microsoft.WindowsStore_8wekyb3d8bbwe\\LocalState\\store.db\" /grant Everyone:F"
|
||||||
|
],
|
||||||
|
```
|
||||||
@@ -3,7 +3,7 @@ title: "Run Disk Cleanup"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2025}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2047}
|
||||||
"WPFTweaksDiskCleanup": {
|
"WPFTweaksDiskCleanup": {
|
||||||
"Content": "Run Disk Cleanup",
|
"Content": "Run Disk Cleanup",
|
||||||
"Description": "Runs Disk Cleanup on Drive C: and removes old Windows Updates.",
|
"Description": "Runs Disk Cleanup on Drive C: and removes old Windows Updates.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Enable End Task With Right Click"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1763}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1785}
|
||||||
"WPFTweaksEndTaskOnTaskbar": {
|
"WPFTweaksEndTaskOnTaskbar": {
|
||||||
"Content": "Enable End Task With Right Click",
|
"Content": "Enable End Task With Right Click",
|
||||||
"Description": "Enables option to end task when right clicking a program in the taskbar.",
|
"Description": "Enables option to end task when right clicking a program in the taskbar.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Location Tracking"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=125}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=138}
|
||||||
"WPFTweaksLocation": {
|
"WPFTweaksLocation": {
|
||||||
"Content": "Disable Location Tracking",
|
"Content": "Disable Location Tracking",
|
||||||
"Description": "Disables Location Tracking.",
|
"Description": "Disables Location Tracking.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Powershell 7 Telemetry"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1779}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1801}
|
||||||
"WPFTweaksPowershell7Tele": {
|
"WPFTweaksPowershell7Tele": {
|
||||||
"Content": "Disable Powershell 7 Telemetry",
|
"Content": "Disable Powershell 7 Telemetry",
|
||||||
"Description": "Creates an Environment Variable called 'POWERSHELL_TELEMETRY_OPTOUT' with a value of '1' which will tell PowerShell 7 to not send Telemetry Data.",
|
"Description": "Creates an Environment Variable called 'POWERSHELL_TELEMETRY_OPTOUT' with a value of '1' which will tell PowerShell 7 to not send Telemetry Data.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Create Restore Point"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1736}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1758}
|
||||||
"WPFTweaksRestorePoint": {
|
"WPFTweaksRestorePoint": {
|
||||||
"Content": "Create Restore Point",
|
"Content": "Create Restore Point",
|
||||||
"Description": "Creates a restore point at runtime in case a revert is needed from WinUtil modifications.",
|
"Description": "Creates a restore point at runtime in case a revert is needed from WinUtil modifications.",
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: "Revert the new start menu"
|
title: "Revert Start Menu layout"
|
||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=90}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=90}
|
||||||
"WPFTweaksRevertStartMenu": {
|
"WPFTweaksRevertStartMenu": {
|
||||||
"Content": "Revert the new start menu",
|
"Content": "Revert Start Menu layout",
|
||||||
"Description": "Uses vivetool to revert to the original start menu from 24H2.",
|
"Description": "Bring back the old Start Menu layout from before the gradual rollout of the new one in 25H2.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "Essential Tweaks",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
@@ -3,7 +3,7 @@ title: "Set Services to Manual"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=162}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=175}
|
||||||
"WPFTweaksServices": {
|
"WPFTweaksServices": {
|
||||||
"Content": "Set Services to Manual",
|
"Content": "Set Services to Manual",
|
||||||
"Description": "Turns a bunch of system services to manual that don't need to be running all the time. This is pretty harmless as if the service is needed, it will simply start on demand.",
|
"Description": "Turns a bunch of system services to manual that don't need to be running all the time. This is pretty harmless as if the service is needed, it will simply start on demand.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Telemetry"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1307}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1320}
|
||||||
"WPFTweaksTelemetry": {
|
"WPFTweaksTelemetry": {
|
||||||
"Content": "Disable Telemetry",
|
"Content": "Disable Telemetry",
|
||||||
"Description": "Disables Microsoft Telemetry.",
|
"Description": "Disables Microsoft Telemetry.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Windows Platform Binary Table (WPBT)"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1892}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1914}
|
||||||
"WPFTweaksWPBT": {
|
"WPFTweaksWPBT": {
|
||||||
"Content": "Disable Windows Platform Binary Table (WPBT)",
|
"Content": "Disable Windows Platform Binary Table (WPBT)",
|
||||||
"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.",
|
"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 Network Block"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1973}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1995}
|
||||||
"WPFTweaksBlockAdobeNet": {
|
"WPFTweaksBlockAdobeNet": {
|
||||||
"Content": "Adobe Network Block",
|
"Content": "Adobe Network Block",
|
||||||
"Description": "Reduces user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs",
|
"Description": "Reduces user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Brave Debloat"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1126}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1139}
|
||||||
"WPFTweaksBraveDebloat": {
|
"WPFTweaksBraveDebloat": {
|
||||||
"Content": "Brave Debloat",
|
"Content": "Brave Debloat",
|
||||||
"Description": "Disables various annoyances like Brave Rewards, Leo AI, Crypto Wallet and VPN.",
|
"Description": "Disables various annoyances like Brave Rewards, Leo AI, Crypto Wallet and VPN.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove ALL MS Store Apps - NOT RECOMMENDED"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1647}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1669}
|
||||||
"WPFTweaksDeBloat": {
|
"WPFTweaksDeBloat": {
|
||||||
"Content": "Remove ALL MS Store Apps - NOT RECOMMENDED",
|
"Content": "Remove ALL MS Store Apps - NOT RECOMMENDED",
|
||||||
"Description": "USE WITH CAUTION!!! This will remove ALL Microsoft Store apps.",
|
"Description": "USE WITH CAUTION!!! This will remove ALL Microsoft Store apps.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Background Apps"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2111}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2133}
|
||||||
"WPFTweaksDisableBGapps": {
|
"WPFTweaksDisableBGapps": {
|
||||||
"Content": "Disable Background Apps",
|
"Content": "Disable Background Apps",
|
||||||
"Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Windows 11.",
|
"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: "Disable Fullscreen Optimizations"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2127}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2149}
|
||||||
"WPFTweaksDisableFSO": {
|
"WPFTweaksDisableFSO": {
|
||||||
"Content": "Disable Fullscreen Optimizations",
|
"Content": "Disable Fullscreen Optimizations",
|
||||||
"Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen.",
|
"Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable IPv6"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2089}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2111}
|
||||||
"WPFTweaksDisableIPv6": {
|
"WPFTweaksDisableIPv6": {
|
||||||
"Content": "Disable IPv6",
|
"Content": "Disable IPv6",
|
||||||
"Description": "Disables IPv6.",
|
"Description": "Disables IPv6.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Notification Tray/Calendar"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1950}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1972}
|
||||||
"WPFTweaksDisableNotifications": {
|
"WPFTweaksDisableNotifications": {
|
||||||
"Content": "Disable Notification Tray/Calendar",
|
"Content": "Disable Notification Tray/Calendar",
|
||||||
"Description": "Disables all Notifications INCLUDING Calendar.",
|
"Description": "Disables all Notifications INCLUDING Calendar.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Set Display for Performance"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1534}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1547}
|
||||||
"WPFTweaksDisplay": {
|
"WPFTweaksDisplay": {
|
||||||
"Content": "Set Display for Performance",
|
"Content": "Set Display for Performance",
|
||||||
"Description": "Sets the system preferences to performance. You can do this manually with sysdm.cpl as well.",
|
"Description": "Sets the system preferences to performance. You can do this manually with sysdm.cpl as well.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Edge Debloat"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1170}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1183}
|
||||||
"WPFTweaksEdgeDebloat": {
|
"WPFTweaksEdgeDebloat": {
|
||||||
"Content": "Edge Debloat",
|
"Content": "Edge Debloat",
|
||||||
"Description": "Disables various telemetry options, popups, and other annoyances in Edge.",
|
"Description": "Disables various telemetry options, popups, and other annoyances in Edge.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Prefer IPv4 over IPv6"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2051}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2073}
|
||||||
"WPFTweaksIPv46": {
|
"WPFTweaksIPv46": {
|
||||||
"Content": "Prefer IPv4 over IPv6",
|
"Content": "Prefer IPv4 over IPv6",
|
||||||
"Description": "Setting the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
|
"Description": "Setting the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Block Razer Software Installs"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1908}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1930}
|
||||||
"WPFTweaksRazerBlock": {
|
"WPFTweaksRazerBlock": {
|
||||||
"Content": "Block Razer Software Installs",
|
"Content": "Block Razer Software Installs",
|
||||||
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
|
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Microsoft Copilot"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1808}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1830}
|
||||||
"WPFTweaksRemoveCopilot": {
|
"WPFTweaksRemoveCopilot": {
|
||||||
"Content": "Disable Microsoft Copilot",
|
"Content": "Disable Microsoft Copilot",
|
||||||
"Description": "Disables MS Copilot AI built into Windows since 23H2.",
|
"Description": "Disables MS Copilot AI built into Windows since 23H2.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove Microsoft Edge"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1429}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1442}
|
||||||
"WPFTweaksRemoveEdge": {
|
"WPFTweaksRemoveEdge": {
|
||||||
"Content": "Remove Microsoft Edge",
|
"Content": "Remove Microsoft Edge",
|
||||||
"Description": "Unblocks Microsoft Edge uninstaller restrictions then uses that uninstaller to remove Microsoft Edge.",
|
"Description": "Unblocks Microsoft Edge uninstaller restrictions then uses that uninstaller to remove Microsoft Edge.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove Gallery from explorer"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1517}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1530}
|
||||||
"WPFTweaksRemoveGallery": {
|
"WPFTweaksRemoveGallery": {
|
||||||
"Content": "Remove Gallery from explorer",
|
"Content": "Remove Gallery from explorer",
|
||||||
"Description": "Removes the Gallery from Explorer and sets This PC as default.",
|
"Description": "Removes the Gallery from Explorer and sets This PC as default.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove Home from Explorer"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1498}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1511}
|
||||||
"WPFTweaksRemoveHome": {
|
"WPFTweaksRemoveHome": {
|
||||||
"Content": "Remove Home from Explorer",
|
"Content": "Remove Home from Explorer",
|
||||||
"Description": "Removes the Home from Explorer and sets This PC as default.",
|
"Description": "Removes the Home from Explorer and sets This PC as default.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove OneDrive"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1461}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1474}
|
||||||
"WPFTweaksRemoveOneDrive": {
|
"WPFTweaksRemoveOneDrive": {
|
||||||
"Content": "Remove OneDrive",
|
"Content": "Remove OneDrive",
|
||||||
"Description": "Denies permission to remove OneDrive user files, then uses its own uninstaller to remove it and restores the original permission afterward.",
|
"Description": "Denies permission to remove OneDrive user files, then uses its own uninstaller to remove it and restores the original permission afterward.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Set Classic Right-Click Menu"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2003}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2025}
|
||||||
"WPFTweaksRightClickMenu": {
|
"WPFTweaksRightClickMenu": {
|
||||||
"Content": "Set Classic Right-Click Menu",
|
"Content": "Set Classic Right-Click Menu",
|
||||||
"Description": "Restores the classic context menu when right-clicking in File Explorer, replacing the simplified Windows 11 version.",
|
"Description": "Restores the classic context menu when right-clicking in File Explorer, replacing the simplified Windows 11 version.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Storage Sense"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1792}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1814}
|
||||||
"WPFTweaksStorage": {
|
"WPFTweaksStorage": {
|
||||||
"Content": "Disable Storage Sense",
|
"Content": "Disable Storage Sense",
|
||||||
"Description": "Storage Sense deletes temp files automatically.",
|
"Description": "Storage Sense deletes temp files automatically.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Teredo"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2067}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2089}
|
||||||
"WPFTweaksTeredo": {
|
"WPFTweaksTeredo": {
|
||||||
"Content": "Disable Teredo",
|
"Content": "Disable Teredo",
|
||||||
"Description": "Teredo network tunneling is a IPv6 feature that can cause additional latency, but may cause problems with some games.",
|
"Description": "Teredo network tunneling is a IPv6 feature that can cause additional latency, but may cause problems with some games.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Set Time to UTC (Dual Boot)"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1445}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1458}
|
||||||
"WPFTweaksUTC": {
|
"WPFTweaksUTC": {
|
||||||
"Content": "Set Time to UTC (Dual Boot)",
|
"Content": "Set Time to UTC (Dual Boot)",
|
||||||
"Description": "Essential for computers that are dual booting. Fixes the time sync with Linux Systems.",
|
"Description": "Essential for computers that are dual booting. Fixes the time sync with Linux Systems.",
|
||||||
|
|||||||
@@ -3,12 +3,21 @@ title: "Remove Xbox & Gaming Components"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1633}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1646}
|
||||||
"WPFTweaksXboxRemoval": {
|
"WPFTweaksXboxRemoval": {
|
||||||
"Content": "Remove Xbox & Gaming Components",
|
"Content": "Remove Xbox & Gaming Components",
|
||||||
"Description": "Removes Xbox services, the Xbox app, Game Bar, and related authentication components.",
|
"Description": "Removes Xbox services, the Xbox app, Game Bar, and related authentication components.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
|
"registry": [
|
||||||
|
{
|
||||||
|
"Path": "KCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\GameDVR",
|
||||||
|
"Name": "AppCaptureEnabled",
|
||||||
|
"Value": "0",
|
||||||
|
"Type": "DWord",
|
||||||
|
"OriginalValue": "1"
|
||||||
|
}
|
||||||
|
],
|
||||||
"appx": [
|
"appx": [
|
||||||
"Microsoft.XboxIdentityProvider",
|
"Microsoft.XboxIdentityProvider",
|
||||||
"Microsoft.XboxSpeechToTextOverlay",
|
"Microsoft.XboxSpeechToTextOverlay",
|
||||||
@@ -17,3 +26,9 @@ description: ""
|
|||||||
"Microsoft.XboxGamingOverlay"
|
"Microsoft.XboxGamingOverlay"
|
||||||
],
|
],
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Registry Changes
|
||||||
|
|
||||||
|
Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.
|
||||||
|
|
||||||
|
You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "DNS"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2610}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2632}
|
||||||
"WPFchangedns": {
|
"WPFchangedns": {
|
||||||
"Content": "DNS",
|
"Content": "DNS",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ toc: true
|
|||||||
|
|
||||||
## General Questions
|
## General Questions
|
||||||
|
|
||||||
|
### Is Windows 10 still supported?
|
||||||
|
No. Windows 10 is no longer supported by Winutil because it reached end of support on **October 14, 2025**.
|
||||||
|
Winutil is focused on Windows 11.
|
||||||
|
|
||||||
### How do I uninstall Winutil?
|
### How do I uninstall Winutil?
|
||||||
You do not have to uninstall Winutil. As it is a script you run from PowerShell, it only loads into your RAM. This means as soon as you close Winutil, it will be cleared from your system. Winutil doesn't install itself permanently on your computer.
|
You do not need to uninstall Winutil. Because it runs as a PowerShell script, it is loaded into memory only while it is open. Once you close it, it is removed from memory and does not remain installed on your system.
|
||||||
|
|
||||||
### Is Winutil safe to use?
|
### Is Winutil safe to use?
|
||||||
Yes, Winutil is open source and the code is publicly available on GitHub. Thousands of users run it daily. However, like any system modification tool, you should:
|
Yes, Winutil is open source and the code is publicly available on GitHub. Thousands of users run it daily. However, like any system modification tool, you should:
|
||||||
@@ -44,12 +48,15 @@ Try these solutions in order:
|
|||||||
irm https://github.com/ChrisTitusTech/Winutil/releases/latest/download/Winutil.ps1 | iex
|
irm https://github.com/ChrisTitusTech/Winutil/releases/latest/download/Winutil.ps1 | iex
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Force TLS 1.2** (for older Windows):
|
2. **Force TLS 1.2**:
|
||||||
```powershell
|
```powershell
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
irm "https://christitus.com/win" | iex
|
irm "https://christitus.com/win" | iex
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On Windows 11, you usually do not need the TLS 1.2 command. Use it only if you hit download or security protocol errors.
|
||||||
|
|
||||||
3. **Change DNS** to Cloudflare (1.1.1.1) or Google (8.8.8.8)
|
3. **Change DNS** to Cloudflare (1.1.1.1) or Google (8.8.8.8)
|
||||||
|
|
||||||
4. **Use a VPN** if GitHub is blocked in your region
|
4. **Use a VPN** if GitHub is blocked in your region
|
||||||
@@ -70,7 +77,7 @@ If you applied a tweak and it breaks something, you can revert it:
|
|||||||
1. Open Winutil again
|
1. Open Winutil again
|
||||||
2. Go to the **Tweaks** tab
|
2. Go to the **Tweaks** tab
|
||||||
3. Select the same tweak you applied
|
3. Select the same tweak you applied
|
||||||
4. Click **"Undo Selected Tweaks"**
|
4. Click **Undo Selected Tweaks**
|
||||||
5. The system will revert to the previous state
|
5. The system will revert to the previous state
|
||||||
|
|
||||||
Alternatively, use System Restore if you created a restore point.
|
Alternatively, use System Restore if you created a restore point.
|
||||||
@@ -93,7 +100,7 @@ Alternatively, use System Restore if you created a restore point.
|
|||||||
Start with Essential Tweaks. Only use Advanced Tweaks if you understand the implications.
|
Start with Essential Tweaks. Only use Advanced Tweaks if you understand the implications.
|
||||||
|
|
||||||
### Will tweaks survive Windows Updates?
|
### Will tweaks survive Windows Updates?
|
||||||
Most tweaks persist through updates, but some may be reset by major Windows updates (feature updates). You may need to reapply certain tweaks after major updates.
|
Most tweaks persist through updates, but some may be reset by major Windows feature updates. You may need to reapply certain tweaks afterward.
|
||||||
|
|
||||||
### Can I create my own tweak presets?
|
### Can I create my own tweak presets?
|
||||||
Currently, Winutil uses predefined presets (Desktop, Laptop, Minimal, Standard). Custom presets aren't directly supported in the GUI, but you can script your preferred configuration.
|
Currently, Winutil uses predefined presets (Desktop, Laptop, Minimal, Standard). Custom presets aren't directly supported in the GUI, but you can script your preferred configuration.
|
||||||
@@ -112,8 +119,8 @@ Yes! Check the boxes for all applications you want, then click "Install Selected
|
|||||||
|
|
||||||
### WinGet isn't working. How do I fix it?
|
### WinGet isn't working. How do I fix it?
|
||||||
1. Go to the **Config** tab
|
1. Go to the **Config** tab
|
||||||
2. Find **Fixes** section
|
2. Find the **Fixes** section
|
||||||
3. Click **"WinGet Reinstall"**
|
3. Click **WinGet Reinstall**
|
||||||
4. Wait for completion
|
4. Wait for completion
|
||||||
5. Try installing applications again
|
5. Try installing applications again
|
||||||
|
|
||||||
@@ -138,8 +145,8 @@ Generally, **no**. Security updates are important. However, you might:
|
|||||||
|
|
||||||
### How do I re-enable updates after disabling them?
|
### How do I re-enable updates after disabling them?
|
||||||
1. Open Winutil
|
1. Open Winutil
|
||||||
2. Go to **Updates** tab
|
2. Go to the **Updates** tab
|
||||||
3. Click **"Enable Updates"**
|
3. Click **Enable Updates**
|
||||||
4. Updates will resume normally
|
4. Updates will resume normally
|
||||||
|
|
||||||
### What's the difference between "Security Updates Only" and "Disable Updates"?
|
### What's the difference between "Security Updates Only" and "Disable Updates"?
|
||||||
@@ -169,7 +176,7 @@ Troubleshooting steps:
|
|||||||
### Network tweaks broke my internet connection
|
### Network tweaks broke my internet connection
|
||||||
1. Open Winutil
|
1. Open Winutil
|
||||||
2. Go to **Config** > **Fixes**
|
2. Go to **Config** > **Fixes**
|
||||||
3. Click **"Reset Network"**
|
3. Click **Reset Network**
|
||||||
4. Restart your computer
|
4. Restart your computer
|
||||||
5. Connection should be restored
|
5. Connection should be restored
|
||||||
|
|
||||||
@@ -177,7 +184,7 @@ Troubleshooting steps:
|
|||||||
Undo the tweaks that might have affected those features:
|
Undo the tweaks that might have affected those features:
|
||||||
1. Reopen Winutil
|
1. Reopen Winutil
|
||||||
2. Select the tweaks you applied
|
2. Select the tweaks you applied
|
||||||
3. Click "Undo Selected Tweaks"
|
3. Click **Undo Selected Tweaks**
|
||||||
|
|
||||||
If that doesn't work, use System Restore to revert to a previous state.
|
If that doesn't work, use System Restore to revert to a previous state.
|
||||||
|
|
||||||
@@ -190,10 +197,10 @@ Yes, Winutil works on Windows Server editions, though some features may not be a
|
|||||||
Yes, Winutil works with Windows 10/11 LTSC editions. Some applications may not be available depending on your configuration.
|
Yes, Winutil works with Windows 10/11 LTSC editions. Some applications may not be available depending on your configuration.
|
||||||
|
|
||||||
### Can I use Winutil in a corporate/enterprise environment?
|
### Can I use Winutil in a corporate/enterprise environment?
|
||||||
Yes, but check your organization's policies first. Some tweaks may conflict with group policies or corporate requirements.
|
Yes, but check your organization's policies first. Some tweaks may conflict with Group Policy or other corporate requirements.
|
||||||
|
|
||||||
### How do I automate Winutil for multiple PCs?
|
### How do I automate Winutil for multiple PCs?
|
||||||
See the [Automation Guide](userguide/automation/) for details on:
|
See the [Automation Guide](/userguide/automation/) for details on:
|
||||||
- Configuration files
|
- Configuration files
|
||||||
- PowerShell parameters
|
- PowerShell parameters
|
||||||
- Batch deployment
|
- Batch deployment
|
||||||
@@ -206,7 +213,7 @@ Yes! Contributions are welcome:
|
|||||||
- Improve documentation
|
- Improve documentation
|
||||||
- Help others in Discord
|
- Help others in Discord
|
||||||
|
|
||||||
See the [Contributing Guide](contributing/) for details.
|
See the [Contributing Guide](/contributing/) for details.
|
||||||
|
|
||||||
## Privacy & Security
|
## Privacy & Security
|
||||||
|
|
||||||
@@ -239,7 +246,7 @@ Tweaks can improve performance by:
|
|||||||
- Cleaning temporary files
|
- Cleaning temporary files
|
||||||
- Optimizing startup programs
|
- Optimizing startup programs
|
||||||
|
|
||||||
Results vary based on your system and which tweaks you apply.
|
Results vary depending on your system and which tweaks you apply.
|
||||||
|
|
||||||
### What's the best preset for gaming?
|
### What's the best preset for gaming?
|
||||||
Use the **Desktop** preset, then additionally apply:
|
Use the **Desktop** preset, then additionally apply:
|
||||||
@@ -249,7 +256,7 @@ Use the **Desktop** preset, then additionally apply:
|
|||||||
- Set display for performance (Advanced)
|
- Set display for performance (Advanced)
|
||||||
|
|
||||||
### How much RAM does Winutil use?
|
### How much RAM does Winutil use?
|
||||||
Winutil itself uses ~50-100MB while running. Once closed, it's removed from memory.
|
Winutil itself uses about 50-100 MB while running. Once closed, it is removed from memory.
|
||||||
|
|
||||||
## Error Messages
|
## Error Messages
|
||||||
|
|
||||||
@@ -265,8 +272,8 @@ Type `Y` and press Enter in the PowerShell window. This only happens on first us
|
|||||||
|
|
||||||
Can't find your answer? Try these resources:
|
Can't find your answer? Try these resources:
|
||||||
|
|
||||||
- **[Known Issues](knownissues/)** - Check if it's a known problem
|
- **[Known Issues](/knownissues/)** - Check if it's a known problem
|
||||||
- **[User Guide](userguide/)** - Comprehensive documentation
|
- **[User Guide](/userguide/)** - Comprehensive documentation
|
||||||
- **[Discord Community](https://discord.gg/RUbZUZyByQ)** - Get help from other users
|
- **[Discord Community](https://discord.gg/RUbZUZyByQ)** - Get help from other users
|
||||||
- **[GitHub Issues](https://github.com/ChrisTitusTech/winutil/issues)** - Report bugs
|
- **[GitHub Issues](https://github.com/ChrisTitusTech/winutil/issues)** - Report bugs
|
||||||
- **[YouTube Tutorial](https://www.youtube.com/watch?v=6UQZ5oQg8XA)** - Video walkthrough
|
- **[YouTube Tutorial](https://www.youtube.com/watch?v=6UQZ5oQg8XA)** - Video walkthrough
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ title: User Guide
|
|||||||
weight: 2
|
weight: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
Welcome to the official User Guide for **Winutil**, your all-in-one Windows toolkit!
|
Welcome to the official User Guide for **Winutil**, your all-in-one Windows toolkit.
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> Windows 10 is not supported by Winutil. Windows 10 reached end of support on **October 14, 2025**.
|
||||||
|
|
||||||
## What is Winutil?
|
## What is Winutil?
|
||||||
|
|
||||||
@@ -19,19 +22,19 @@ Winutil (Chris Titus Tech's Windows Utility) is a comprehensive PowerShell-based
|
|||||||
|
|
||||||
Winutil is designed for:
|
Winutil is designed for:
|
||||||
|
|
||||||
- **Home Users**: Wanting to optimize their personal PCs
|
- **Home Users**: People who want to optimize their personal PCs
|
||||||
- **Power Users**: Needing fine-grained control over Windows
|
- **Power Users**: Users who want fine-grained control over Windows
|
||||||
- **IT Professionals**: Managing multiple systems efficiently
|
- **IT Professionals**: Teams managing multiple systems efficiently
|
||||||
- **Gamers**: Optimizing systems for gaming performance
|
- **Gamers**: Users optimizing systems for gaming performance
|
||||||
- **Privacy-Conscious Users**: Reducing telemetry and data collection
|
- **Privacy-Conscious Users**: People reducing telemetry and data collection
|
||||||
- **Developers**: Setting up clean development environments
|
- **Developers**: Users setting up clean development environments
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
New to Winutil? Start here:
|
New to Winutil? Start here:
|
||||||
|
|
||||||
1. **[Getting Started Guide](getting-started/)** - Installation and first steps
|
1. **[Getting Started Guide](getting-started/)** - Installation and first steps
|
||||||
2. **[Application Store](application/)** - Learn to install software easily
|
2. **[Applications Guide](application/)** - Learn to install, upgrade, and uninstall software
|
||||||
3. **[Tweaks Guide](tweaks/)** - Optimize your system
|
3. **[Tweaks Guide](tweaks/)** - Optimize your system
|
||||||
4. **[Features & Fixes](features/)** - Troubleshoot common issues
|
4. **[Features & Fixes](features/)** - Troubleshoot common issues
|
||||||
5. **[Win11 Creator](win11Creator/)** - Build a custom debloated Windows 11 ISO
|
5. **[Win11 Creator](win11Creator/)** - Build a custom debloated Windows 11 ISO
|
||||||
@@ -42,7 +45,7 @@ New to Winutil? Start here:
|
|||||||
|
|
||||||
Browse and install hundreds of popular applications with a single click. No more hunting for download links or dealing with installer bloat.
|
Browse and install hundreds of popular applications with a single click. No more hunting for download links or dealing with installer bloat.
|
||||||
|
|
||||||
**[Read the Store Guide →](application/)**
|
**[Read the Applications Guide →](application/)**
|
||||||
|
|
||||||
### ⚙️ System Tweaks
|
### ⚙️ System Tweaks
|
||||||
|
|
||||||
@@ -82,7 +85,7 @@ Automate Winutil configurations for:
|
|||||||
|
|
||||||
### 💿 Windows 11 Creator
|
### 💿 Windows 11 Creator
|
||||||
|
|
||||||
Build a custom Windows 11 ISO with bloatware removed, telemetry disabled, and hardware requirement checks bypassed — then export it as an ISO file or write it directly to a USB drive.
|
Build a custom Windows 11 ISO with bloatware removed, telemetry disabled, and hardware requirement checks bypassed. You can then export it as an ISO file or write it directly to a USB drive.
|
||||||
|
|
||||||
**[Read the Win11 Creator Guide →](win11Creator/)**
|
**[Read the Win11 Creator Guide →](win11Creator/)**
|
||||||
|
|
||||||
@@ -91,7 +94,7 @@ Build a custom Windows 11 ISO with bloatware removed, telemetry disabled, and ha
|
|||||||
| I want to... | Go to... |
|
| I want to... | Go to... |
|
||||||
|--------------|----------|
|
|--------------|----------|
|
||||||
| Install Winutil for the first time | [Getting Started](getting-started/) |
|
| Install Winutil for the first time | [Getting Started](getting-started/) |
|
||||||
| Install applications quickly | [Application Store](application/) |
|
| Install, upgrade, or uninstall apps | [Applications Guide](application/) |
|
||||||
| Speed up my computer | [Tweaks Guide](tweaks/) |
|
| Speed up my computer | [Tweaks Guide](tweaks/) |
|
||||||
| Fix Windows Update problems | [Features - Fixes](features/) |
|
| Fix Windows Update problems | [Features - Fixes](features/) |
|
||||||
| Automate setup for multiple PCs | [Automation](automation/) |
|
| Automate setup for multiple PCs | [Automation](automation/) |
|
||||||
@@ -117,15 +120,15 @@ Before using Winutil:
|
|||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
|
|
||||||
- **Operating System**: Windows 10 (1809+) or Windows 11
|
- **Operating System**: Windows 11
|
||||||
- **PowerShell**: Version 5.1 or later (included in Windows)
|
- **PowerShell**: Version 5.1 or later (included in Windows 11)
|
||||||
- **Permissions**: Administrator access required
|
- **Permissions**: Administrator access required
|
||||||
- **Internet**: Required for downloading apps and updates
|
- **Internet**: Required for downloading apps and updates
|
||||||
- **.NET Framework**: 4.5+ (usually pre-installed)
|
- **.NET Framework**: 4.5+ (usually pre-installed)
|
||||||
|
|
||||||
## Getting Help
|
## Getting Help
|
||||||
|
|
||||||
Need assistance?
|
Need help?
|
||||||
|
|
||||||
- **📖 Documentation**: You're reading it! Use the navigation menu
|
- **📖 Documentation**: You're reading it! Use the navigation menu
|
||||||
- **❓ FAQ**: Check [Frequently Asked Questions](../faq/)
|
- **❓ FAQ**: Check [Frequently Asked Questions](../faq/)
|
||||||
@@ -151,7 +154,7 @@ Want to help improve Winutil?
|
|||||||
This User Guide covers everything you need to know:
|
This User Guide covers everything you need to know:
|
||||||
|
|
||||||
1. **[Getting Started](getting-started/)** - Installation, first run, basic usage
|
1. **[Getting Started](getting-started/)** - Installation, first run, basic usage
|
||||||
2. **[Application Store](application/)** - Installing software, using presets
|
2. **[Applications](application/)** - Installing, upgrading, and uninstalling software
|
||||||
3. **[Tweaks](tweaks/)** - System optimizations and customizations
|
3. **[Tweaks](tweaks/)** - System optimizations and customizations
|
||||||
4. **[Features & Fixes](features/)** - Troubleshooting tools and utilities
|
4. **[Features & Fixes](features/)** - Troubleshooting tools and utilities
|
||||||
5. **[Win11 Creator](win11Creator/)** - Build a custom debloated Windows 11 ISO
|
5. **[Win11 Creator](win11Creator/)** - Build a custom debloated Windows 11 ISO
|
||||||
@@ -164,4 +167,4 @@ Watch the complete Winutil overview:
|
|||||||
|
|
||||||
{{< youtube id=6UQZ5oQg8XA loading=lazy >}}
|
{{< youtube id=6UQZ5oQg8XA loading=lazy >}}
|
||||||
|
|
||||||
Ready to get started? Head to the **[Getting Started Guide](getting-started/)** now!
|
Ready to get started? Head to the **[Getting Started Guide](getting-started/)**.
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
---
|
---
|
||||||
title: Applications
|
title: Applications
|
||||||
weight: 2
|
weight: 3
|
||||||
---
|
---
|
||||||
|
|
||||||
{{< tabs items="Installation & Updates,Upgrade All,Uninstall,Get Installed,Clear Selection" defaultIndex="0" >}}
|
{{< tabs >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Installation & Updates" selected=true >}}
|
||||||
* Choose the programs you want to install or upgrade.
|
* Choose the applications you want to install or upgrade.
|
||||||
* For programs not currently installed, this action will install them.
|
* For programs not currently installed, this action will install them.
|
||||||
* For programs already installed, this action will update them to the latest version.
|
* For programs already installed, this action will update them to the latest version.
|
||||||
* Click the `Install/Upgrade Selected` button to start the installation or upgrade process.
|
* Click the `Install/Upgrade Selected` button to start the installation or upgrade process.
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Upgrade All" >}}
|
||||||
* Simply press the `Upgrade All` button.
|
* Simply press the `Upgrade All` button.
|
||||||
* This will upgrade all applicable programs that are installed without the need for individual selection.
|
* This will upgrade all applicable programs that are installed without the need for individual selection.
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Uninstall" >}}
|
||||||
* Select the programs you wish to uninstall.
|
* Select the programs you wish to uninstall.
|
||||||
* Click the `Uninstall Selected` button to remove the selected programs.
|
* Click the `Uninstall Selected` button to remove the selected programs.
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Get Installed" >}}
|
||||||
* Click the `Show Installed Apps` button.
|
* Click the `Show Installed Apps` button.
|
||||||
* This will scan for and select all installed programs in Winutil that WinGet supports.
|
* This scans for and selects installed applications supported by WinGet.
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Clear Selection" >}}
|
||||||
* Click the `Clear Selection` button.
|
* Click the `Clear Selection` button.
|
||||||
* This will unselect all checked programs.
|
* This will unselect all checked programs.
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
@@ -36,4 +36,4 @@ weight: 2
|
|||||||
{{< image src="images/Install-Tab" alt="Install Image" >}}
|
{{< image src="images/Install-Tab" alt="Install Image" >}}
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> If you have trouble finding an application, press `ctrl + f` and search the name of it. Applications will filter depending on your input.
|
> If you have trouble finding an application, press `Ctrl + F` and search for its name. The list filters as you type.
|
||||||
|
|||||||
@@ -1,7 +1,27 @@
|
|||||||
Automation option in winutil allows you to run winutil from a config file,
|
---
|
||||||
you can get your own config file inside winutil by clicking the gear icon on the top right and clicking export and saving it as a file
|
title: Automation
|
||||||
|
weight: 7
|
||||||
|
---
|
||||||
|
|
||||||
you can automate winutil launch with this command
|
Use Automation to run Winutil from an exported configuration file.
|
||||||
|
|
||||||
|
To create a config file:
|
||||||
|
|
||||||
|
1. Open Winutil.
|
||||||
|
2. Click the gear icon in the top-right corner.
|
||||||
|
3. Choose **Export**.
|
||||||
|
4. Save the exported JSON file.
|
||||||
|
|
||||||
|
Once you have exported a config, launch Winutil with it using this command:
|
||||||
```powershell
|
```powershell
|
||||||
& ([ScriptBlock]::Create((irm "https://christitus.com/win"))) -Config C:\Path\To\Config -Run
|
& ([ScriptBlock]::Create((irm "https://christitus.com/win"))) -Config "C:\Path\To\Config.json" -Run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This is useful for:
|
||||||
|
|
||||||
|
- Applying the same Winutil configuration across multiple Windows 11 PCs
|
||||||
|
- Reusing a known-good baseline after reinstalling Windows
|
||||||
|
- Standardizing deployments for labs, workstations, or personal setups
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Run the command in an elevated PowerShell session so Winutil can apply system-level changes.
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
---
|
---
|
||||||
title: Features
|
title: Features
|
||||||
weight: 4
|
weight: 5
|
||||||
---
|
---
|
||||||
|
|
||||||
* Install the most used **Windows Features** by checking the checkbox and clicking "Install Features" to install them.
|
Use the **Features** and **Fixes** sections to install optional Windows components and run common repair tasks.
|
||||||
|
|
||||||
* All .Net Frameworks (2, 3, 4)
|
## Windows Features
|
||||||
* HyperV Virtualization
|
|
||||||
|
Install common **Windows features** by selecting the feature checkboxes and clicking **Install Features**.
|
||||||
|
|
||||||
|
* All .NET Frameworks (2, 3, 4)
|
||||||
|
* Hyper-V Virtualization
|
||||||
* Legacy Media (WMP, DirectPlay)
|
* Legacy Media (WMP, DirectPlay)
|
||||||
* NFS - Network File System
|
* NFS - Network File System
|
||||||
* Enable Daily Registry Backup Task 12:30am
|
* Enable Daily Registry Backup Task 12:30am
|
||||||
@@ -15,8 +19,9 @@ weight: 4
|
|||||||
* Windows Subsystem for Linux
|
* Windows Subsystem for Linux
|
||||||
* Windows Sandbox
|
* Windows Sandbox
|
||||||
|
|
||||||
### Fixes
|
## Fixes
|
||||||
* Quick fixes for your system if you are having issues.
|
|
||||||
|
Use these one-click fixes for common system problems.
|
||||||
|
|
||||||
* Set Up Autologin
|
* Set Up Autologin
|
||||||
* Reset Windows Update
|
* Reset Windows Update
|
||||||
@@ -25,9 +30,9 @@ weight: 4
|
|||||||
* WinGet Reinstall
|
* WinGet Reinstall
|
||||||
* Remove Adobe Creative Cloud
|
* Remove Adobe Creative Cloud
|
||||||
|
|
||||||
### Legacy Windows Panels
|
## Legacy Windows Panels
|
||||||
|
|
||||||
Open old-school Windows panels directly from Winutil. Following Panels are available:
|
Open old-school Windows panels directly from Winutil. Available panels include:
|
||||||
|
|
||||||
* Control Panel
|
* Control Panel
|
||||||
* Network Connections
|
* Network Connections
|
||||||
@@ -37,6 +42,6 @@ Open old-school Windows panels directly from Winutil. Following Panels are avail
|
|||||||
* System Properties
|
* System Properties
|
||||||
* User Accounts
|
* User Accounts
|
||||||
|
|
||||||
### Remote Access
|
## Remote Access
|
||||||
|
|
||||||
Enables OpenSSH server on your windows machine.
|
Enable an OpenSSH server on your Windows machine for remote access.
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
---
|
---
|
||||||
title: Getting Started
|
title: Getting Started
|
||||||
weight: 1
|
weight: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
## Welcome to Winutil!
|
## Welcome to Winutil!
|
||||||
|
|
||||||
Winutil is a powerful Windows utility that helps you optimize, customize, and maintain your Windows system. This guide will walk you through everything you need to get started.
|
Winutil is a powerful Windows utility that helps you optimize, customize, and maintain your system. This guide walks you through everything you need to get started.
|
||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
|
|
||||||
Before running Winutil, ensure your system meets these requirements:
|
Before running Winutil, ensure your system meets these requirements:
|
||||||
|
|
||||||
- **Operating System**: Windows 10 (Latest Version) or Windows 11
|
> [!IMPORTANT]
|
||||||
- **PowerShell**: Version 5.1 or later (included by default in Windows 10/11)
|
> Windows 10 is not supported by Winutil. Windows 10 reached end of support on **October 14, 2025**.
|
||||||
|
|
||||||
|
- **Operating System**: Windows 11
|
||||||
|
- **PowerShell**: Version 5.1 or later (included by default in Windows 11)
|
||||||
- **Administrator Access**: Required for system-level changes
|
- **Administrator Access**: Required for system-level changes
|
||||||
- **Internet Connection**: Required for downloading applications and updates
|
- **Internet Connection**: Required for downloading applications and updates
|
||||||
- **.NET Framework**: Version 4.5 or later (usually pre-installed)
|
- **.NET Framework**: Version 4.5 or later (usually pre-installed)
|
||||||
@@ -27,9 +30,8 @@ There are several ways to open PowerShell with admin rights:
|
|||||||
|
|
||||||
**Method 1: Start Menu (Recommended)**
|
**Method 1: Start Menu (Recommended)**
|
||||||
|
|
||||||
1. Right-click on the Windows Start button
|
1. Right-click the Windows Start button
|
||||||
2. Select "Windows PowerShell (Admin)" on Windows 10
|
2. Select "Terminal (Admin)"
|
||||||
3. Or select "Terminal (Admin)" on Windows 11
|
|
||||||
|
|
||||||
**Method 2: Search Method**
|
**Method 2: Search Method**
|
||||||
|
|
||||||
@@ -102,25 +104,25 @@ Before making any changes, create a system restore point:
|
|||||||
|
|
||||||
1. Go to the **Tweaks** tab
|
1. Go to the **Tweaks** tab
|
||||||
2. Find "Create Restore Point" under Essential Tweaks
|
2. Find "Create Restore Point" under Essential Tweaks
|
||||||
3. Check the box and click "Run Tweaks"
|
3. Check the box and click **Run Tweaks**
|
||||||
|
|
||||||
This allows you to undo changes if needed.
|
This gives you a rollback point if needed.
|
||||||
|
|
||||||
### 2. Install Essential Applications
|
### 2. Install Essential Applications
|
||||||
|
|
||||||
1. Navigate to the **Install** tab
|
1. Navigate to the **Install** tab
|
||||||
2. Browse categories or use the search bar
|
2. Browse categories or use the search bar
|
||||||
3. Check applications you want to install
|
3. Check applications you want to install
|
||||||
4. Click "Install Selected" at the bottom
|
4. Click "Install/Upgrade Selected" at the bottom
|
||||||
|
|
||||||
### 3. Apply Basic Tweaks
|
### 3. Apply Basic Tweaks
|
||||||
|
|
||||||
For a better Windows experience without risks:
|
For a better Windows experience with minimal risk:
|
||||||
|
|
||||||
1. Go to the **Tweaks** tab
|
1. Go to the **Tweaks** tab
|
||||||
2. Select the **"Desktop" preset** for a balanced configuration
|
2. Select the **"Desktop" preset** for a balanced configuration
|
||||||
3. Review the selected tweaks
|
3. Review the selected tweaks
|
||||||
4. Click "Run Tweaks"
|
4. Click **Run Tweaks**
|
||||||
|
|
||||||
## Common Tasks
|
## Common Tasks
|
||||||
|
|
||||||
@@ -128,10 +130,10 @@ For a better Windows experience without risks:
|
|||||||
|
|
||||||
**Single Application**:
|
**Single Application**:
|
||||||
|
|
||||||
1. Open **Install** tab
|
1. Open the **Install** tab
|
||||||
2. Search for the application name
|
2. Search for the application name
|
||||||
3. Check the box next to it
|
3. Check the box next to it
|
||||||
4. Click "Install Selected"
|
4. Click "Install/Upgrade Selected"
|
||||||
|
|
||||||
**Multiple Applications**:
|
**Multiple Applications**:
|
||||||
|
|
||||||
@@ -143,9 +145,9 @@ For a better Windows experience without risks:
|
|||||||
|
|
||||||
**Essential Tweaks** (Safe for all users):
|
**Essential Tweaks** (Safe for all users):
|
||||||
|
|
||||||
1. Go to **Tweaks** tab
|
1. Go to the **Tweaks** tab
|
||||||
2. Select from Essential Tweaks section
|
2. Select from the Essential Tweaks section
|
||||||
3. Click "Run Tweaks"
|
3. Click **Run Tweaks**
|
||||||
|
|
||||||
**Advanced Tweaks** (Use with caution):
|
**Advanced Tweaks** (Use with caution):
|
||||||
|
|
||||||
@@ -156,15 +158,15 @@ For a better Windows experience without risks:
|
|||||||
**Undoing Tweaks**:
|
**Undoing Tweaks**:
|
||||||
|
|
||||||
1. Select the same tweaks you applied
|
1. Select the same tweaks you applied
|
||||||
2. Click "Undo Selected Tweaks"
|
2. Click **Undo Selected Tweaks**
|
||||||
3. System will revert to previous state
|
3. The system reverts to the previous state
|
||||||
|
|
||||||
### Using Quick Fixes
|
### Using Quick Fixes
|
||||||
|
|
||||||
For common Windows issues:
|
For common Windows issues:
|
||||||
|
|
||||||
1. Go to **Config** tab
|
1. Go to the **Config** tab
|
||||||
2. Navigate to **Fixes** section
|
2. Navigate to the **Fixes** section
|
||||||
3. Select the appropriate fix:
|
3. Select the appropriate fix:
|
||||||
- **Reset Network**: Fixes network connectivity issues
|
- **Reset Network**: Fixes network connectivity issues
|
||||||
- **Reset Windows Update**: Resolves update problems
|
- **Reset Windows Update**: Resolves update problems
|
||||||
@@ -175,21 +177,21 @@ For common Windows issues:
|
|||||||
|
|
||||||
For improved privacy and speed:
|
For improved privacy and speed:
|
||||||
|
|
||||||
1. Go to **Config** or **Tweaks** tab
|
1. Go to the **Config** tab or the **Tweaks** tab
|
||||||
2. Find the DNS section
|
2. Find the DNS section
|
||||||
3. Select a provider:
|
3. Select a provider:
|
||||||
- **Cloudflare**: Fast and privacy-focused
|
- **Cloudflare**: Fast and privacy-focused
|
||||||
- **Google**: Reliable and widely used
|
- **Google**: Reliable and widely used
|
||||||
- **Quad9**: Security-focused with malware blocking
|
- **Quad9**: Security-focused with malware blocking
|
||||||
- **AdGuard**: Blocks ads and trackers
|
- **AdGuard**: Blocks ads and trackers
|
||||||
4. Click Apply
|
4. Click **Apply**
|
||||||
|
|
||||||
## Understanding Presets
|
## Understanding Presets
|
||||||
|
|
||||||
Winutil offers several preset configurations:
|
Winutil offers several preset configurations:
|
||||||
|
|
||||||
- **Minimal**: Minimal changes, keeps most Windows features
|
- **Minimal**: Minimal changes that keep most Windows features
|
||||||
- **Standard**: Good middle-ground for most users
|
- **Standard**: A good middle ground for most users
|
||||||
|
|
||||||
## Safety Tips
|
## Safety Tips
|
||||||
|
|
||||||
@@ -221,13 +223,16 @@ Winutil offers several preset configurations:
|
|||||||
irm https://github.com/ChrisTitusTech/Winutil/releases/latest/download/Winutil.ps1 | iex
|
irm https://github.com/ChrisTitusTech/Winutil/releases/latest/download/Winutil.ps1 | iex
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Force TLS 1.2 (for older Windows versions):
|
2. Force TLS 1.2:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
irm "https://christitus.com/win" | iex
|
irm "https://christitus.com/win" | iex
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> On Windows 11, you usually do not need the TLS 1.2 command. Use it only if you hit download or security protocol errors.
|
||||||
|
|
||||||
### Execution Policy Error
|
### Execution Policy Error
|
||||||
|
|
||||||
If you get an execution policy error:
|
If you get an execution policy error:
|
||||||
@@ -239,7 +244,7 @@ irm "https://christitus.com/win" | iex
|
|||||||
|
|
||||||
### Download Blocked (India/Certain Regions)
|
### Download Blocked (India/Certain Regions)
|
||||||
|
|
||||||
If GitHub is blocked in your region:
|
If downloads are blocked in your region:
|
||||||
|
|
||||||
1. Use a VPN service
|
1. Use a VPN service
|
||||||
2. Change DNS to Cloudflare (1.1.1.1) or Google (8.8.8.8)
|
2. Change DNS to Cloudflare (1.1.1.1) or Google (8.8.8.8)
|
||||||
@@ -258,16 +263,16 @@ If Winutil downloads but doesn't open:
|
|||||||
|
|
||||||
Now that you're set up, explore these guides:
|
Now that you're set up, explore these guides:
|
||||||
|
|
||||||
- [Application Installation Guide](../application/) - Learn about installing software
|
- [Applications Guide](../application/) - Learn about installing, upgrading, and uninstalling software
|
||||||
- [Tweaks Guide](../tweaks/) - Understand system optimizations
|
- [Tweaks Guide](../tweaks/) - Understand system optimizations
|
||||||
- [FAQ](../../faq/) - Common questions and answers
|
- [FAQ](/faq/) - Common questions and answers
|
||||||
|
|
||||||
## Getting Help
|
## Getting Help
|
||||||
|
|
||||||
If you need assistance:
|
If you need assistance:
|
||||||
|
|
||||||
- **Documentation**: Browse this documentation site
|
- **Documentation**: Browse this documentation site
|
||||||
- **Known Issues**: Check the [Known Issues](../../knownissues/) page
|
- **Known Issues**: Check the [Known Issues](/knownissues/) page
|
||||||
- **Discord**: Join the [community Discord server](https://discord.gg/RUbZUZyByQ)
|
- **Discord**: Join the [community Discord server](https://discord.gg/RUbZUZyByQ)
|
||||||
- **GitHub Issues**: Report bugs on [GitHub](https://github.com/ChrisTitusTech/winutil/issues)
|
- **GitHub Issues**: Report bugs on [GitHub](https://github.com/ChrisTitusTech/winutil/issues)
|
||||||
- **YouTube**: Watch [video tutorials](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
|
- **YouTube**: Watch [video tutorials](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
|
||||||
@@ -275,13 +280,14 @@ If you need assistance:
|
|||||||
## Quick Reference Card
|
## Quick Reference Card
|
||||||
|
|
||||||
| Task | Location | Action |
|
| Task | Location | Action |
|
||||||
| -------------------- | ----------- | ------------------------------------ |
|
| ---- | -------- | ------ |
|
||||||
| Install Apps | Install Tab | Check boxes → Install Selected |
|
| Install or upgrade apps | Install tab | Check boxes -> Install/Upgrade Selected |
|
||||||
| Apply Tweaks | Tweaks Tab | Select tweaks → Run Tweaks |
|
| Uninstall apps | Install tab | Check boxes -> Uninstall Selected |
|
||||||
| Undo Tweaks | Tweaks Tab | Select tweaks → Undo Selected Tweaks |
|
| Apply tweaks | Tweaks tab | Select tweaks -> Run Tweaks |
|
||||||
| Create Restore Point | Tweaks Tab | Essential Tweaks section |
|
| Undo tweaks | Tweaks tab | Select tweaks -> Undo Selected Tweaks |
|
||||||
| Fix Network | Config Tab | Fixes → Reset Network |
|
| Create restore point | Tweaks tab | Essential Tweaks section |
|
||||||
| Change DNS | Tweaks Tab | DNS section |
|
| Fix network | Config tab | Fixes -> Reset Network |
|
||||||
| Open Control Panel | Config Tab | Legacy Windows Panels |
|
| Change DNS | Tweaks tab | DNS section |
|
||||||
|
| Open Control Panel | Config tab | Legacy Windows Panels |
|
||||||
|
|
||||||
Happy optimizing! 🚀
|
Happy optimizing!
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
---
|
---
|
||||||
title: Tweaks
|
title: Tweaks
|
||||||
weight: 3
|
weight: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
{{< image src="images/Tweaks-Tab" alt="Image of Tweaks Tab" >}}
|
{{< image src="images/Tweaks-Tab" alt="Image of Tweaks Tab" >}}
|
||||||
|
|
||||||
### Run Tweaks
|
### Run Tweaks
|
||||||
* **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application.
|
* **Open the Tweaks tab**: Navigate to the **Tweaks** tab in the application.
|
||||||
* **Select Tweaks**: Choose the tweaks you want to apply. You can use the presets available at the top for convenience.
|
* **Select Tweaks**: Choose the tweaks you want to apply. You can use the presets available at the top for convenience.
|
||||||
* **Run Tweaks**: After selecting the desired tweaks, click the 'Run Tweaks' button at the bottom of the screen.
|
* **Run Tweaks**: After selecting the desired tweaks, click **Run Tweaks** at the bottom of the screen.
|
||||||
|
|
||||||
### Undo Tweaks
|
### Undo Tweaks
|
||||||
* **Open Tweaks Tab**: Go to the 'Tweaks' tab located next to 'Install'.
|
* **Open the Tweaks tab**: Go to the **Tweaks** tab located next to **Install**.
|
||||||
* **Select Tweaks to Remove**: Choose the tweaks you want to disable or remove.
|
* **Select Tweaks to Remove**: Choose the tweaks you want to disable or remove.
|
||||||
* **Undo Tweaks**: Click the 'Undo Selected Tweaks' button at the bottom of the screen to apply the changes.
|
* **Undo Tweaks**: Click **Undo Selected Tweaks** at the bottom of the screen to apply the changes.
|
||||||
|
|
||||||
### Essential Tweaks
|
### Essential Tweaks
|
||||||
Essential Tweaks are modifications and optimizations that are generally safe for most users to implement. These tweaks are designed to enhance system performance, improve privacy, and reduce unnecessary system activities. They are considered low-risk and are recommended for users who want to ensure their system runs smoothly and efficiently without delving too deeply into complex configurations. The goal of Essential Tweaks is to provide noticeable improvements with minimal risk, making them suitable for a wide range of users, including those who may not have advanced technical knowledge.
|
Essential Tweaks are modifications and optimizations that are generally safe for most users to implement. These tweaks are designed to enhance system performance, improve privacy, and reduce unnecessary system activities. They are considered low-risk and are recommended for users who want to ensure their system runs smoothly and efficiently without delving too deeply into complex configurations. The goal of Essential Tweaks is to provide noticeable improvements with minimal risk, making them suitable for a wide range of users, including those who may not have advanced technical knowledge.
|
||||||
@@ -21,10 +21,8 @@ Essential Tweaks are modifications and optimizations that are generally safe for
|
|||||||
### Advanced Tweaks (CAUTION)
|
### Advanced Tweaks (CAUTION)
|
||||||
Advanced Tweaks are intended for experienced users who have a solid understanding of their system and the potential implications of making deep-level changes. These tweaks involve more significant alterations to the operating system and can provide substantial customization. However, they also carry a higher risk of causing system instability or unintended side effects if not implemented correctly. Users who choose to apply Advanced Tweaks should proceed with caution, ensuring they have adequate knowledge and backups in place to recover if something goes wrong. These tweaks are not recommended for novice users or those unfamiliar with the inner workings of their operating system.
|
Advanced Tweaks are intended for experienced users who have a solid understanding of their system and the potential implications of making deep-level changes. These tweaks involve more significant alterations to the operating system and can provide substantial customization. However, they also carry a higher risk of causing system instability or unintended side effects if not implemented correctly. Users who choose to apply Advanced Tweaks should proceed with caution, ensuring they have adequate knowledge and backups in place to recover if something goes wrong. These tweaks are not recommended for novice users or those unfamiliar with the inner workings of their operating system.
|
||||||
|
|
||||||
### O&O Shutup
|
### O&O ShutUp10++
|
||||||
|
[O&O ShutUp10++](https://www.oo-software.com/en/shutup10) can be launched from Winutil with one click. It is a free privacy tool for Windows that helps users manage telemetry, update behavior, and app permission settings.
|
||||||
|
|
||||||
[O&O ShutUp10++](https://www.oo-software.com/en/shutup10) can be launched from Winutil with only one button click. It is a free privacy tool for Windows that lets users easily manage their privacy settings. It disables telemetry, controls updates, and manages app permissions to enhance security and privacy. The tool offers recommended settings for optimal privacy with just a few clicks.
|
|
||||||
|
|
||||||
{{< youtube id=3HvNr8eMcv0 loading=lazy >}}
|
{{< youtube id=3HvNr8eMcv0 loading=lazy >}}
|
||||||
|
|
||||||
@@ -41,16 +39,16 @@ The utility provides a convenient DNS selection feature, allowing users to choos
|
|||||||
* [**Cloudflare_Malware_Adult**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malware%20and%20adult%20content%3A): Blocks both malware and adult content, offering more comprehensive filtering.
|
* [**Cloudflare_Malware_Adult**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malware%20and%20adult%20content%3A): Blocks both malware and adult content, offering more comprehensive filtering.
|
||||||
* [**Open_DNS**](https://www.opendns.com/setupguide/#familyshield): Offers customizable filtering and enhanced security features.
|
* [**Open_DNS**](https://www.opendns.com/setupguide/#familyshield): Offers customizable filtering and enhanced security features.
|
||||||
* [**Quad9**](https://quad9.net/): Focuses on security by blocking known malicious domains.
|
* [**Quad9**](https://quad9.net/): Focuses on security by blocking known malicious domains.
|
||||||
* [**AdGuard_Ads_Trackers**](https://adguard-dns.io/en/welcome.html) AdGuard DNS will block ads, trackers, or any other DNS requests. Visit website and login for a dashboard, statistics and customize your experience in the server settings.
|
* [**AdGuard_Ads_Trackers**](https://adguard-dns.io/en/welcome.html): AdGuard DNS blocks ads, trackers, and other unwanted DNS requests. Visit the website and sign in for a dashboard, statistics, and additional server-side customization.
|
||||||
* [**AdGuard_Ads_Trackers_Malware_Adult**](https://adguard-dns.io/en/welcome.html) AdGuard DNS will block ads, trackers, adult content, and enable Safe Search and Safe Mode, where possible.
|
* [**AdGuard_Ads_Trackers_Malware_Adult**](https://adguard-dns.io/en/welcome.html): AdGuard DNS blocks ads, trackers, malware, and adult content, and enables Safe Search and Safe Mode where possible.
|
||||||
|
|
||||||
### Customize Preferences
|
### Customize Preferences
|
||||||
|
|
||||||
The Customize Preferences section allows users to personalize their Windows experience by toggling various visual and functional features. These preferences are designed to enhance usability and tailor the system to the user’s specific needs and preferences.
|
The Customize Preferences section allows users to personalize their Windows experience by toggling visual and functional settings.
|
||||||
|
|
||||||
### Performance Plans
|
### Performance Plans
|
||||||
|
|
||||||
The Performance Plans section allows users to manage the Ultimate Performance Profile on their system. This feature is designed to optimize the system for maximum performance.
|
The Performance Plans section allows users to manage the Ultimate Performance Profile for maximum performance.
|
||||||
|
|
||||||
#### Add and activate the Ultimate Performance Profile:
|
#### Add and activate the Ultimate Performance Profile:
|
||||||
* Enables and activates the Ultimate Performance Profile to enhance system performance by minimizing latency and increasing efficiency.
|
* Enables and activates the Ultimate Performance Profile to enhance system performance by minimizing latency and increasing efficiency.
|
||||||
|
|||||||
@@ -1,21 +1,30 @@
|
|||||||
The utility provides three distinct settings for managing Windows updates: Default (Out of Box) Settings, Security (Recommended) Settings, and Disable ALL Updates (NOT RECOMMENDED!). Each setting offers a different approach to handling updates, catering to various user needs and preferences.
|
---
|
||||||
|
title: Updates
|
||||||
|
weight: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
Winutil provides three update modes so you can choose how aggressively Windows Update is managed on your system:
|
||||||
|
|
||||||
|
- **Default (Out of Box) Settings**: Restores standard Windows Update behavior
|
||||||
|
- **Security (Recommended) Settings**: Prioritizes stability while still receiving security updates
|
||||||
|
- **Disable ALL Updates**: Turns off Windows Update entirely and should only be used with extreme caution
|
||||||
|
|
||||||
### Default (Out of Box) Settings
|
### Default (Out of Box) Settings
|
||||||
- **Description**: This setting retains the default configurations that come with Windows, ensuring no modifications are made.
|
|
||||||
- **Functionality**: It will remove any custom Windows update settings previously applied.
|
- **What it does**: Restores the default Windows Update configuration.
|
||||||
- **Note**: If update errors persist, reset all updates in the configuration tab to restore all Microsoft Update Services to their default settings, reinstalling them from their servers.
|
- **Best for**: Systems where you want Windows to manage updates normally.
|
||||||
|
- **Notes**: This removes custom update settings previously applied by Winutil. If update errors continue, use the reset option in the **Config** tab to restore Microsoft Update services to their default state.
|
||||||
|
|
||||||
### Security (Recommended) Settings
|
### Security (Recommended) Settings
|
||||||
- **Description**: This is the recommended setting for all computers.
|
|
||||||
- **Update Schedule**:
|
- **What it does**: Applies a more conservative update strategy designed for most users.
|
||||||
- **Feature Updates**: Delays feature updates by 365 days to avoid potential bugs and instability.
|
- **Feature updates**: Delayed by **365 days** to reduce the chance of disruption from major Windows changes.
|
||||||
- **Security Updates**: Installs security updates 4 days after their release to ensure system protection against pressing security flaws.
|
- **Security updates**: Delayed by **4 days** to allow time for early issues to surface while still keeping the system protected.
|
||||||
- **Rationale**:
|
- **Why use it**: This mode offers the best balance between security and stability, which is why it is the recommended option for most PCs.
|
||||||
- **Feature Updates**: Often introduce new features and bugs; delaying these updates minimizes the risk of system disruptions.
|
|
||||||
- **Security Updates**: Essential for patching critical security vulnerabilities. Delaying them by a few days allows for verification of stability and compatibility without leaving the system exposed for extended periods.
|
|
||||||
|
|
||||||
### Disable ALL Updates (NOT RECOMMENDED!)
|
### Disable ALL Updates (NOT RECOMMENDED!)
|
||||||
- **Description**: This setting completely disables all Windows updates.
|
|
||||||
- **Suitability**: May be appropriate for systems used for specific purposes that do not require active internet browsing.
|
- **What it does**: Disables all Windows updates.
|
||||||
- **Warning**: Disabling updates significantly increases the risk of the system being hacked or infected due to the lack of security patches.
|
- **Best for**: Highly controlled or special-purpose systems where updates must remain off temporarily.
|
||||||
- **Note**: It is strongly advised against using this setting due to the heightened security risks.
|
- **Warning**: This leaves the system without security patches and significantly increases security risk.
|
||||||
|
- **Recommendation**: Avoid this mode unless you fully understand the tradeoffs and have a specific reason to use it.
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
---
|
---
|
||||||
title: Win 11 Creator
|
title: Win11 Creator
|
||||||
weight: 5
|
weight: 8
|
||||||
---
|
---
|
||||||
|
|
||||||
## Using Winutil's Win11 Creator
|
## Using Winutil's Win11 Creator
|
||||||
|
|
||||||
Winutil includes a built-in **Win11 Creator** tool that lets you take any official Windows 11 ISO and produce a customized, debloated version — with telemetry removed, hardware requirement checks bypassed, and local account setup enabled out of the box. You can export the result as a new ISO file or write it directly to a USB drive.
|
Winutil includes a built-in **Win11 Creator** tool that lets you take an official Windows 11 ISO and produce a customized, debloated version. The resulting image can remove telemetry, bypass hardware requirement checks, and enable local account setup out of the box. You can export the result as a new ISO file or write it directly to a USB drive.
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> You need a valid Windows 11 ISO before starting. Download one from [Microsoft's official site](https://www.microsoft.com/en-us/software-download/windows11) or use [UUP Dump](https://uupdump.net/). The process uses ~10–15 GB of temporary disk space, so make sure you have room.
|
> You need an **official Windows 11 ISO** from [Microsoft's website](https://www.microsoft.com/en-us/software-download/windows11) before starting. Custom, modified, or non-official ISOs are not supported. The process uses ~10–15 GB of temporary disk space, so make sure you have room.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Step 1 — Select Your ISO
|
### Step 1 — Select Your Official Windows 11 ISO
|
||||||
|
|
||||||
1. Open Winutil and go to the **Win11 Creator** tab.
|
1. Open Winutil and go to the **Win11 Creator** tab.
|
||||||
2. Click **Browse** and select your Windows 11 ISO file (must be 4 GB or larger).
|
2. Click **Browse** and select your **official Windows 11 ISO file** from Microsoft (must be 4 GB or larger). Custom or modified ISOs are not supported.
|
||||||
3. The file path and size will appear on screen once selected.
|
3. The file path and size will appear on screen once selected.
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -35,16 +35,33 @@ Winutil includes a built-in **Win11 Creator** tool that lets you take any offici
|
|||||||
|
|
||||||
Click **Run Windows ISO Modification and Creator** to start the customization process. Winutil will:
|
Click **Run Windows ISO Modification and Creator** to start the customization process. Winutil will:
|
||||||
|
|
||||||
|
**App & Component Removal:**
|
||||||
- **Remove 40+ bloat apps** — Clipchamp, Teams, Copilot, Dev Home, new Outlook, Bing apps, Solitaire, and more
|
- **Remove 40+ bloat apps** — Clipchamp, Teams, Copilot, Dev Home, new Outlook, Bing apps, Solitaire, and more
|
||||||
- **Delete OneDrive setup** from the image
|
- **Delete OneDrive setup** from the image
|
||||||
- **Apply registry tweaks** — disables telemetry, advertising ID, tailored experiences, and cloud content features
|
|
||||||
- **Bypass hardware checks** — removes TPM, Secure Boot, CPU, and RAM requirement enforcement so the ISO installs on unsupported hardware
|
**System Customization:**
|
||||||
|
- **Bypass hardware checks** — removes TPM, Secure Boot, CPU, RAM, and storage requirement enforcement so the ISO installs on unsupported hardware
|
||||||
- **Enable local account setup** — injects an `autounattend.xml` that skips the Microsoft account screen during OOBE
|
- **Enable local account setup** — injects an `autounattend.xml` that skips the Microsoft account screen during OOBE
|
||||||
|
- **Disable BitLocker and device encryption** — removes startup overhead
|
||||||
|
- **Disable Chat icon** — removes chat taskbar button
|
||||||
- **Strip unused editions** — keeps only your selected edition, saving 1–2 GB per removed edition
|
- **Strip unused editions** — keeps only your selected edition, saving 1–2 GB per removed edition
|
||||||
- **Clean the component store** — runs DISM cleanup to reclaim another 300–800 MB
|
- **Clean the component store** — runs DISM cleanup to reclaim another 300–800 MB
|
||||||
- **Remove telemetry scheduled tasks** — CEIP, Appraiser, WaaSMedic, and others
|
|
||||||
|
|
||||||
A live log shows progress as each step completes. This stage takes **10–30 minutes** depending on your disk speed — the WIM dismount near the end is the slowest part, so don't close Winutil while it's running.
|
**Privacy & Telemetry Tweaks:**
|
||||||
|
- **Disable telemetry** — advertising ID, tailored experiences, input personalization, speech online privacy
|
||||||
|
- **Disable cloud content features** — app suggestions, Microsoft Store recommendations
|
||||||
|
- **Remove telemetry scheduled tasks** — CEIP, Appraiser, WaaSMedic, and others
|
||||||
|
- **Disable OneDrive folder backup** — prevents automatic backups to cloud
|
||||||
|
- **Prevent DevHome and Outlook post-setup installation**
|
||||||
|
- **Prevent Teams installation** — blocks auto-install after OOBE
|
||||||
|
- **Prevent new Outlook Mail app installation**
|
||||||
|
- **Disable Windows Update during OOBE** — re-enabled automatically on first login
|
||||||
|
- **Disable Copilot and search box suggestions**
|
||||||
|
|
||||||
|
**Optional: Driver Injection**
|
||||||
|
- If enabled, injects all drivers from your current system into the install.wim and boot.wim — useful for offline installations on machines with missing drivers. This is an optional checkbox in Step 3.
|
||||||
|
|
||||||
|
A live log shows progress as each step completes. This stage usually takes **10–30 minutes** depending on disk speed. The WIM dismount near the end is the slowest part, so do not close Winutil while it is running.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -52,9 +69,9 @@ A live log shows progress as each step completes. This stage takes **10–30 min
|
|||||||
|
|
||||||
Once modification is complete, choose how to save your image:
|
Once modification is complete, choose how to save your image:
|
||||||
|
|
||||||
{{< tabs items="Save as ISO,Write to USB" defaultIndex="0" >}}
|
{{< tabs >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Save as ISO" selected=true >}}
|
||||||
1. Click **Save as an ISO File**.
|
1. Click **Save as an ISO File**.
|
||||||
2. Choose a save location (defaults to your Desktop as `Win11_Modified_yyyyMMdd.iso`).
|
2. Choose a save location (defaults to your Desktop as `Win11_Modified_yyyyMMdd.iso`).
|
||||||
3. Winutil builds a dual BIOS/UEFI bootable ISO using `oscdimg.exe`.
|
3. Winutil builds a dual BIOS/UEFI bootable ISO using `oscdimg.exe`.
|
||||||
@@ -65,7 +82,7 @@ Once modification is complete, choose how to save your image:
|
|||||||
**Typical output size:** 2.5–3.5 GB (down from 5–6 GB original)
|
**Typical output size:** 2.5–3.5 GB (down from 5–6 GB original)
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
|
|
||||||
{{< tab >}}
|
{{< tab name="Write to USB" >}}
|
||||||
1. Click **Write Directly to a USB Drive**.
|
1. Click **Write Directly to a USB Drive**.
|
||||||
2. Select your USB drive from the dropdown (click **Refresh** if it doesn't appear).
|
2. Select your USB drive from the dropdown (click **Refresh** if it doesn't appear).
|
||||||
3. Click **Erase & Write to USB** and confirm the warning — **all data on the drive will be permanently erased**.
|
3. Click **Erase & Write to USB** and confirm the warning — **all data on the drive will be permanently erased**.
|
||||||
@@ -83,7 +100,7 @@ Once modification is complete, choose how to save your image:
|
|||||||
|
|
||||||
### Step 5 — Clean Up (Optional)
|
### Step 5 — Clean Up (Optional)
|
||||||
|
|
||||||
Click **Clean & Reset** to delete the temporary working directory (~10–15 GB) and reset the tool back to its initial state, ready for a new ISO. You'll be asked to confirm before anything is deleted.
|
Click **Clean & Reset** to delete the temporary working directory (~10–15 GB) and return the tool to its initial state, ready for a new ISO. You will be asked to confirm before anything is deleted.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -94,9 +111,9 @@ When you install Windows 11 from your modified ISO:
|
|||||||
- **No Microsoft account required** — create a local account directly during setup
|
- **No Microsoft account required** — create a local account directly during setup
|
||||||
- **No hardware checks** — installs on machines without TPM 2.0, Secure Boot, or supported CPUs
|
- **No hardware checks** — installs on machines without TPM 2.0, Secure Boot, or supported CPUs
|
||||||
- **Dark mode enabled by default**
|
- **Dark mode enabled by default**
|
||||||
- **Empty taskbar and Start Menu** — no pinned apps
|
- **Empty taskbar and Start Menu** — no pinned apps, Chat icon removed
|
||||||
- **Windows Update re-enabled automatically** after first login (it's paused during OOBE to prevent interruption)
|
- **Windows Update disabled during OOBE** — automatically re-enabled on first login to prevent setup interruptions
|
||||||
- **BitLocker disabled**, Recall disabled, desktop shortcuts removed
|
- **BitLocker disabled** — removes startup overhead on first boot
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -112,14 +129,14 @@ When you install Windows 11 from your modified ISO:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
A list of the best free and open source tools for downloading, creating and flashing Windows ISOs.
|
Below is a list of free and open-source tools for downloading, creating, and flashing Windows ISOs.
|
||||||
|
|
||||||
## Download Windows ISOs
|
## Download Windows ISOs
|
||||||
|
|
||||||
| Tool | Description | Website |
|
| Tool | Description | Website |
|
||||||
|------|-------------|---------|
|
|------|-------------|---------|
|
||||||
| **[UUP Dump](https://uupdump.net/)** | Download Windows UUP files directly from Microsoft's servers and convert them into a clean ISO — great for getting the latest builds | [uupdump.net](https://uupdump.net/) |
|
| **[UUP Dump](https://uupdump.net/)** | Download Windows UUP files directly from Microsoft's servers and convert them into a clean ISO — great for getting the latest builds | [uupdump.net](https://uupdump.net/) |
|
||||||
| **[Microsoft Media Creation Tool](https://www.microsoft.com/en-us/software-download/windows11)** | Microsoft's official tool for downloading and creating Windows 10/11 installation media | [microsoft.com](https://www.microsoft.com/en-us/software-download/windows11) |
|
| **[Microsoft Media Creation Tool](https://www.microsoft.com/en-us/software-download/windows11)** | Microsoft's official tool for downloading and creating Windows 11 installation media | [microsoft.com](https://www.microsoft.com/en-us/software-download/windows11) |
|
||||||
|
|
||||||
|
|
||||||
## Customize Windows ISOs
|
## Customize Windows ISOs
|
||||||
@@ -144,7 +161,7 @@ A list of the best free and open source tools for downloading, creating and flas
|
|||||||
---
|
---
|
||||||
|
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Already have a Windows 11 ISO? Skip the third-party tools and use Winutil's built-in **[Win11 Creator](#using-winutilss-win11-creator)** at the top of this page.
|
> Already have a Windows 11 ISO? Skip the third-party tools and use Winutil's built-in **[Win11 Creator](#using-winutils-win11-creator)** at the top of this page.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Always download Windows ISOs from official Microsoft sources or trusted tools like Rufus/UUP Dump to avoid tampered images.
|
> Always download Windows ISOs from official Microsoft sources or trusted tools like Rufus/UUP Dump to avoid tampered images.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
module github.com/ChrisTitusTech/WinUtil
|
module github.com/ChrisTitusTech/WinUtil
|
||||||
|
|
||||||
go 1.23.3
|
go 1.26
|
||||||
|
|
||||||
require github.com/imfing/hextra v0.11.1 // indirect
|
require github.com/imfing/hextra v0.12.0 // indirect
|
||||||
|
|||||||
@@ -2,3 +2,5 @@ github.com/imfing/hextra v0.9.7 h1:Zg5n24us36Bn/S/5mEUPkRW6uwE6vHHEqWSgN0bPXaM=
|
|||||||
github.com/imfing/hextra v0.9.7/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
|
github.com/imfing/hextra v0.9.7/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
|
||||||
github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI=
|
github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI=
|
||||||
github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
|
github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
|
||||||
|
github.com/imfing/hextra v0.12.0 h1:f6y35hW/WDJEcx9S0dOmbICOBxYE0PmP6IJFsTUgVyY=
|
||||||
|
github.com/imfing/hextra v0.12.0/go.mod h1:YAv8XRNSmcqjieFwI7fVQK1AoY2Do+45DO9HGqxSGu4=
|
||||||
|
|||||||
@@ -12,29 +12,48 @@ canonifyURLs = true
|
|||||||
path = "github.com/imfing/hextra"
|
path = "github.com/imfing/hextra"
|
||||||
|
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
name = "Developer Documentation"
|
identifier = "userguide"
|
||||||
pageRef = "/dev"
|
name = "User Guides"
|
||||||
|
pageRef = "/userguide"
|
||||||
weight = 1
|
weight = 1
|
||||||
|
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
name = "User Guides"
|
identifier = "documentation"
|
||||||
pageRef = "/userguide"
|
name = "Developer Documentation"
|
||||||
weight = 2
|
weight = 2
|
||||||
|
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
|
identifier = "contribution-guides"
|
||||||
name = "Contribution Guides"
|
name = "Contribution Guides"
|
||||||
pageRef = "CONTRIBUTING.md"
|
pageRef = "CONTRIBUTING.md"
|
||||||
|
weight = 1
|
||||||
|
parent = "documentation"
|
||||||
|
|
||||||
|
[[menu.main]]
|
||||||
|
identifier = "developer-documentation"
|
||||||
|
name = "Developer Docs"
|
||||||
|
pageRef = "/dev"
|
||||||
|
weight = 2
|
||||||
|
parent = "documentation"
|
||||||
|
|
||||||
|
[[menu.main]]
|
||||||
|
identifier = "help"
|
||||||
|
name = "Help"
|
||||||
weight = 3
|
weight = 3
|
||||||
|
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
|
identifier = "faq"
|
||||||
name = "FAQ"
|
name = "FAQ"
|
||||||
pageRef = "faq.md"
|
pageRef = "faq.md"
|
||||||
weight = 4
|
weight = 1
|
||||||
|
parent = "help"
|
||||||
|
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
|
identifier = "known-issues"
|
||||||
name = "Known Issues"
|
name = "Known Issues"
|
||||||
pageRef = "KnownIssues.md"
|
pageRef = "KnownIssues.md"
|
||||||
weight = 4
|
weight = 2
|
||||||
|
parent = "help"
|
||||||
|
|
||||||
[[menu.main]]
|
[[menu.main]]
|
||||||
name = "Store"
|
name = "Store"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
copyright: "© <script>document.write(new Date().getFullYear())</script> <a href='https://christitus.com'>Chris Titus Tech</a>. All rights reserved."
|
copyright: "© <script>document.write(new Date().getFullYear())</script> <a href='https://christitus.com'>Chris Titus Tech</a>. All rights reserved."
|
||||||
|
|
||||||
backToTop: "Scroll to top"
|
backToTop: "Scroll to top"
|
||||||
changeLanguage: "Change language"
|
changeLanguage: "Change language"
|
||||||
changeTheme: "Change theme"
|
changeTheme: "Change theme"
|
||||||
|
|||||||
@@ -1,18 +1,12 @@
|
|||||||
function Write-Win11ISOLog {
|
function Write-Win11ISOLog {
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Appends a timestamped message to the Win11ISO status log TextBox.
|
|
||||||
.PARAMETER Message
|
|
||||||
The message to append.
|
|
||||||
#>
|
|
||||||
param([string]$Message)
|
param([string]$Message)
|
||||||
$timestamp = (Get-Date).ToString("HH:mm:ss")
|
$ts = (Get-Date).ToString("HH:mm:ss")
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
$current = $sync["WPFWin11ISOStatusLog"].Text
|
$current = $sync["WPFWin11ISOStatusLog"].Text
|
||||||
if ($current -eq "Ready. Please select a Windows 11 ISO to begin.") {
|
if ($current -eq "Ready. Please select a Windows 11 ISO to begin.") {
|
||||||
$sync["WPFWin11ISOStatusLog"].Text = "[$timestamp] $Message"
|
$sync["WPFWin11ISOStatusLog"].Text = "[$ts] $Message"
|
||||||
} else {
|
} else {
|
||||||
$sync["WPFWin11ISOStatusLog"].Text += "`n[$timestamp] $Message"
|
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $Message"
|
||||||
}
|
}
|
||||||
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
||||||
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
||||||
@@ -20,11 +14,6 @@ function Write-Win11ISOLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-WinUtilISOBrowse {
|
function Invoke-WinUtilISOBrowse {
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Opens an OpenFileDialog so the user can choose a Windows 11 ISO file.
|
|
||||||
Populates WPFWin11ISOPath and reveals the Mount & Verify section (Step 2).
|
|
||||||
#>
|
|
||||||
Add-Type -AssemblyName System.Windows.Forms
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
|
||||||
$dlg = [System.Windows.Forms.OpenFileDialog]::new()
|
$dlg = [System.Windows.Forms.OpenFileDialog]::new()
|
||||||
@@ -35,18 +24,12 @@ function Invoke-WinUtilISOBrowse {
|
|||||||
if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return }
|
if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return }
|
||||||
|
|
||||||
$isoPath = $dlg.FileName
|
$isoPath = $dlg.FileName
|
||||||
|
|
||||||
# ── Basic size sanity-check (a Win11 ISO is typically > 4 GB) ──
|
|
||||||
$fileSizeGB = [math]::Round((Get-Item $isoPath).Length / 1GB, 2)
|
$fileSizeGB = [math]::Round((Get-Item $isoPath).Length / 1GB, 2)
|
||||||
|
|
||||||
$sync["WPFWin11ISOPath"].Text = $isoPath
|
$sync["WPFWin11ISOPath"].Text = $isoPath
|
||||||
$sync["WPFWin11ISOFileInfo"].Text = "File size: $fileSizeGB GB"
|
$sync["WPFWin11ISOFileInfo"].Text = "File size: $fileSizeGB GB"
|
||||||
$sync["WPFWin11ISOFileInfo"].Visibility = "Visible"
|
$sync["WPFWin11ISOFileInfo"].Visibility = "Visible"
|
||||||
|
|
||||||
# Reveal Step 2
|
|
||||||
$sync["WPFWin11ISOMountSection"].Visibility = "Visible"
|
$sync["WPFWin11ISOMountSection"].Visibility = "Visible"
|
||||||
|
|
||||||
# Collapse all later steps whenever a new ISO is chosen
|
|
||||||
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed"
|
||||||
@@ -55,17 +38,10 @@ function Invoke-WinUtilISOBrowse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-WinUtilISOMountAndVerify {
|
function Invoke-WinUtilISOMountAndVerify {
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Mounts the selected ISO, verifies it is a valid Windows 11 image,
|
|
||||||
and populates the edition list. Reveals Step 3 on success.
|
|
||||||
#>
|
|
||||||
$isoPath = $sync["WPFWin11ISOPath"].Text
|
$isoPath = $sync["WPFWin11ISOPath"].Text
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($isoPath) -or $isoPath -eq "No ISO selected...") {
|
if ([string]::IsNullOrWhiteSpace($isoPath) -or $isoPath -eq "No ISO selected...") {
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show("Please select an ISO file first.", "No ISO Selected", "OK", "Warning")
|
||||||
"Please select an ISO file first.",
|
|
||||||
"No ISO Selected", "OK", "Warning")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,14 +49,17 @@ function Invoke-WinUtilISOMountAndVerify {
|
|||||||
Set-WinUtilProgressBar -Label "Mounting ISO..." -Percent 10
|
Set-WinUtilProgressBar -Label "Mounting ISO..." -Percent 10
|
||||||
|
|
||||||
try {
|
try {
|
||||||
# Mount the ISO
|
Mount-DiskImage -ImagePath $isoPath -ErrorAction Stop | Out-Null
|
||||||
$diskImage = Mount-DiskImage -ImagePath $isoPath -PassThru -ErrorAction Stop
|
|
||||||
$driveLetter = ($diskImage | Get-Volume).DriveLetter + ":"
|
do {
|
||||||
|
Start-Sleep -Milliseconds 500
|
||||||
|
} until ((Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter)
|
||||||
|
|
||||||
|
$driveLetter = (Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter + ":"
|
||||||
Write-Win11ISOLog "Mounted at drive $driveLetter"
|
Write-Win11ISOLog "Mounted at drive $driveLetter"
|
||||||
|
|
||||||
Set-WinUtilProgressBar -Label "Verifying ISO contents..." -Percent 30
|
Set-WinUtilProgressBar -Label "Verifying ISO contents..." -Percent 30
|
||||||
|
|
||||||
# ── Verify install.wim / install.esd presence ──
|
|
||||||
$wimPath = Join-Path $driveLetter "sources\install.wim"
|
$wimPath = Join-Path $driveLetter "sources\install.wim"
|
||||||
$esdPath = Join-Path $driveLetter "sources\install.esd"
|
$esdPath = Join-Path $driveLetter "sources\install.esd"
|
||||||
|
|
||||||
@@ -96,14 +75,10 @@ function Invoke-WinUtilISOMountAndVerify {
|
|||||||
|
|
||||||
$activeWim = if (Test-Path $wimPath) { $wimPath } else { $esdPath }
|
$activeWim = if (Test-Path $wimPath) { $wimPath } else { $esdPath }
|
||||||
|
|
||||||
# ── Read edition / architecture info ──
|
|
||||||
Set-WinUtilProgressBar -Label "Reading image metadata..." -Percent 55
|
Set-WinUtilProgressBar -Label "Reading image metadata..." -Percent 55
|
||||||
|
|
||||||
$imageInfo = Get-WindowsImage -ImagePath $activeWim | Select-Object ImageIndex, ImageName
|
$imageInfo = Get-WindowsImage -ImagePath $activeWim | Select-Object ImageIndex, ImageName
|
||||||
|
|
||||||
# ── Verify at least one Win11 edition is present ──
|
if (-not ($imageInfo | Where-Object { $_.ImageName -match "Windows 11" })) {
|
||||||
$isWin11 = $imageInfo | Where-Object { $_.ImageName -match "Windows 11" }
|
|
||||||
if (-not $isWin11) {
|
|
||||||
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
||||||
Write-Win11ISOLog "ERROR: No 'Windows 11' edition found in the image."
|
Write-Win11ISOLog "ERROR: No 'Windows 11' edition found in the image."
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show(
|
||||||
@@ -113,10 +88,8 @@ function Invoke-WinUtilISOMountAndVerify {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# Store edition info for later index lookup
|
|
||||||
$sync["Win11ISOImageInfo"] = $imageInfo
|
$sync["Win11ISOImageInfo"] = $imageInfo
|
||||||
|
|
||||||
# ── Populate UI ──
|
|
||||||
$sync["WPFWin11ISOMountDriveLetter"].Text = "Mounted at: $driveLetter | Image file: $(Split-Path $activeWim -Leaf)"
|
$sync["WPFWin11ISOMountDriveLetter"].Text = "Mounted at: $driveLetter | Image file: $(Split-Path $activeWim -Leaf)"
|
||||||
$sync["WPFWin11ISOEditionComboBox"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOEditionComboBox"].Dispatcher.Invoke([action]{
|
||||||
$sync["WPFWin11ISOEditionComboBox"].Items.Clear()
|
$sync["WPFWin11ISOEditionComboBox"].Items.Clear()
|
||||||
@@ -124,12 +97,10 @@ function Invoke-WinUtilISOMountAndVerify {
|
|||||||
[void]$sync["WPFWin11ISOEditionComboBox"].Items.Add("$($img.ImageIndex): $($img.ImageName)")
|
[void]$sync["WPFWin11ISOEditionComboBox"].Items.Add("$($img.ImageIndex): $($img.ImageName)")
|
||||||
}
|
}
|
||||||
if ($sync["WPFWin11ISOEditionComboBox"].Items.Count -gt 0) {
|
if ($sync["WPFWin11ISOEditionComboBox"].Items.Count -gt 0) {
|
||||||
# Default to Windows 11 Pro; fall back to first item if not found
|
|
||||||
$proIndex = -1
|
$proIndex = -1
|
||||||
for ($i = 0; $i -lt $sync["WPFWin11ISOEditionComboBox"].Items.Count; $i++) {
|
for ($i = 0; $i -lt $sync["WPFWin11ISOEditionComboBox"].Items.Count; $i++) {
|
||||||
if ($sync["WPFWin11ISOEditionComboBox"].Items[$i] -match "Windows 11 Pro(?![\w ])") {
|
if ($sync["WPFWin11ISOEditionComboBox"].Items[$i] -match "Windows 11 Pro(?![\w ])") {
|
||||||
$proIndex = $i
|
$proIndex = $i; break
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sync["WPFWin11ISOEditionComboBox"].SelectedIndex = if ($proIndex -ge 0) { $proIndex } else { 0 }
|
$sync["WPFWin11ISOEditionComboBox"].SelectedIndex = if ($proIndex -ge 0) { $proIndex } else { 0 }
|
||||||
@@ -137,42 +108,27 @@ function Invoke-WinUtilISOMountAndVerify {
|
|||||||
})
|
})
|
||||||
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Visible"
|
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Visible"
|
||||||
|
|
||||||
# Store for later steps
|
|
||||||
$sync["Win11ISODriveLetter"] = $driveLetter
|
$sync["Win11ISODriveLetter"] = $driveLetter
|
||||||
$sync["Win11ISOWimPath"] = $activeWim
|
$sync["Win11ISOWimPath"] = $activeWim
|
||||||
$sync["Win11ISOImagePath"] = $isoPath
|
$sync["Win11ISOImagePath"] = $isoPath
|
||||||
|
|
||||||
# Reveal Step 3
|
|
||||||
$sync["WPFWin11ISOModifySection"].Visibility = "Visible"
|
$sync["WPFWin11ISOModifySection"].Visibility = "Visible"
|
||||||
|
|
||||||
Set-WinUtilProgressBar -Label "ISO verified ✔" -Percent 100
|
Set-WinUtilProgressBar -Label "ISO verified" -Percent 100
|
||||||
Write-Win11ISOLog "ISO verified OK. Editions found: $($imageInfo.Count)"
|
Write-Win11ISOLog "ISO verified OK. Editions found: $($imageInfo.Count)"
|
||||||
}
|
} catch {
|
||||||
catch {
|
|
||||||
Write-Win11ISOLog "ERROR during mount/verify: $_"
|
Write-Win11ISOLog "ERROR during mount/verify: $_"
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show(
|
||||||
"An error occurred while mounting or verifying the ISO:`n`n$_",
|
"An error occurred while mounting or verifying the ISO:`n`n$_",
|
||||||
"Error", "OK", "Error")
|
"Error", "OK", "Error")
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
Start-Sleep -Milliseconds 800
|
Start-Sleep -Milliseconds 800
|
||||||
Set-WinUtilProgressBar -Label "" -Percent 0
|
Set-WinUtilProgressBar -Label "" -Percent 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-WinUtilISOModify {
|
function Invoke-WinUtilISOModify {
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Extracts ISO contents to a temp working directory, modifies install.wim,
|
|
||||||
then repackages the image. Reveals Step 4 (output options) on success.
|
|
||||||
|
|
||||||
.NOTES
|
|
||||||
This function runs inside a PowerShell runspace so the UI stays responsive.
|
|
||||||
Placeholder modification logic is provided; extend as needed.
|
|
||||||
#>
|
|
||||||
|
|
||||||
$isoPath = $sync["Win11ISOImagePath"]
|
$isoPath = $sync["Win11ISOImagePath"]
|
||||||
$driveLetter= $sync["Win11ISODriveLetter"]
|
$driveLetter = $sync["Win11ISODriveLetter"]
|
||||||
$wimPath = $sync["Win11ISOWimPath"]
|
$wimPath = $sync["Win11ISOWimPath"]
|
||||||
|
|
||||||
if (-not $isoPath) {
|
if (-not $isoPath) {
|
||||||
@@ -182,9 +138,8 @@ function Invoke-WinUtilISOModify {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Resolve selected edition index from the ComboBox ──
|
|
||||||
$selectedItem = $sync["WPFWin11ISOEditionComboBox"].SelectedItem
|
$selectedItem = $sync["WPFWin11ISOEditionComboBox"].SelectedItem
|
||||||
$selectedWimIndex = 1 # default fallback
|
$selectedWimIndex = 1
|
||||||
if ($selectedItem -and $selectedItem -match '^(\d+):') {
|
if ($selectedItem -and $selectedItem -match '^(\d+):') {
|
||||||
$selectedWimIndex = [int]$Matches[1]
|
$selectedWimIndex = [int]$Matches[1]
|
||||||
} elseif ($sync["Win11ISOImageInfo"]) {
|
} elseif ($sync["Win11ISOImageInfo"]) {
|
||||||
@@ -193,13 +148,11 @@ function Invoke-WinUtilISOModify {
|
|||||||
$selectedEditionName = if ($selectedItem) { ($selectedItem -replace '^\d+:\s*', '') } else { "Unknown" }
|
$selectedEditionName = if ($selectedItem) { ($selectedItem -replace '^\d+:\s*', '') } else { "Unknown" }
|
||||||
Write-Win11ISOLog "Selected edition: $selectedEditionName (Index $selectedWimIndex)"
|
Write-Win11ISOLog "Selected edition: $selectedEditionName (Index $selectedWimIndex)"
|
||||||
|
|
||||||
# Disable the modify button to prevent double-click
|
|
||||||
$sync["WPFWin11ISOModifyButton"].IsEnabled = $false
|
$sync["WPFWin11ISOModifyButton"].IsEnabled = $false
|
||||||
|
$sync["Win11ISOModifying"] = $true
|
||||||
|
|
||||||
$existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") -ErrorAction SilentlyContinue |
|
$existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") -ErrorAction SilentlyContinue |
|
||||||
Where-Object { $_.PSIsContainer } |
|
Where-Object { $_.PSIsContainer } | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||||
Sort-Object LastWriteTime -Descending |
|
|
||||||
Select-Object -First 1
|
|
||||||
|
|
||||||
$workDir = if ($existingWorkDir) {
|
$workDir = if ($existingWorkDir) {
|
||||||
Write-Win11ISOLog "Reusing existing temp directory: $($existingWorkDir.FullName)"
|
Write-Win11ISOLog "Reusing existing temp directory: $($existingWorkDir.FullName)"
|
||||||
@@ -208,9 +161,6 @@ function Invoke-WinUtilISOModify {
|
|||||||
Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Resolve autounattend.xml content ──────────────────────────────────────
|
|
||||||
# Compiled winutil.ps1 sets $WinUtilAutounattendXml before main.ps1 runs.
|
|
||||||
# In dev/source mode fall back to reading tools\autounattend.xml directly.
|
|
||||||
$autounattendContent = if ($WinUtilAutounattendXml) {
|
$autounattendContent = if ($WinUtilAutounattendXml) {
|
||||||
$WinUtilAutounattendXml
|
$WinUtilAutounattendXml
|
||||||
} else {
|
} else {
|
||||||
@@ -218,11 +168,12 @@ function Invoke-WinUtilISOModify {
|
|||||||
if (Test-Path $toolsXml) { Get-Content $toolsXml -Raw } else { "" }
|
if (Test-Path $toolsXml) { Get-Content $toolsXml -Raw } else { "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Run modification in a background runspace ──
|
|
||||||
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
||||||
$runspace.ApartmentState = "STA"
|
$runspace.ApartmentState = "STA"
|
||||||
$runspace.ThreadOptions = "ReuseThread"
|
$runspace.ThreadOptions = "ReuseThread"
|
||||||
$runspace.Open()
|
$runspace.Open()
|
||||||
|
$injectDrivers = $sync["WPFWin11ISOInjectDrivers"].IsChecked -eq $true
|
||||||
|
|
||||||
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
||||||
$runspace.SessionStateProxy.SetVariable("isoPath", $isoPath)
|
$runspace.SessionStateProxy.SetVariable("isoPath", $isoPath)
|
||||||
$runspace.SessionStateProxy.SetVariable("driveLetter", $driveLetter)
|
$runspace.SessionStateProxy.SetVariable("driveLetter", $driveLetter)
|
||||||
@@ -231,28 +182,18 @@ function Invoke-WinUtilISOModify {
|
|||||||
$runspace.SessionStateProxy.SetVariable("selectedWimIndex", $selectedWimIndex)
|
$runspace.SessionStateProxy.SetVariable("selectedWimIndex", $selectedWimIndex)
|
||||||
$runspace.SessionStateProxy.SetVariable("selectedEditionName", $selectedEditionName)
|
$runspace.SessionStateProxy.SetVariable("selectedEditionName", $selectedEditionName)
|
||||||
$runspace.SessionStateProxy.SetVariable("autounattendContent", $autounattendContent)
|
$runspace.SessionStateProxy.SetVariable("autounattendContent", $autounattendContent)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("injectDrivers", $injectDrivers)
|
||||||
|
|
||||||
# Serialize functions so they are available inside the runspace
|
$isoScriptFuncDef = "function Invoke-WinUtilISOScript {`n" + ${function:Invoke-WinUtilISOScript}.ToString() + "`n}"
|
||||||
$isoScriptFuncDef = "function Invoke-WinUtilISOScript {`n" + `
|
$win11ISOLogFuncDef = "function Write-Win11ISOLog {`n" + ${function:Write-Win11ISOLog}.ToString() + "`n}"
|
||||||
${function:Invoke-WinUtilISOScript}.ToString() + "`n}"
|
|
||||||
$runspace.SessionStateProxy.SetVariable("isoScriptFuncDef", $isoScriptFuncDef)
|
$runspace.SessionStateProxy.SetVariable("isoScriptFuncDef", $isoScriptFuncDef)
|
||||||
|
|
||||||
$win11ISOLogFuncDef = "function Write-Win11ISOLog {`n" + `
|
|
||||||
${function:Write-Win11ISOLog}.ToString() + "`n}"
|
|
||||||
$runspace.SessionStateProxy.SetVariable("win11ISOLogFuncDef", $win11ISOLogFuncDef)
|
$runspace.SessionStateProxy.SetVariable("win11ISOLogFuncDef", $win11ISOLogFuncDef)
|
||||||
|
|
||||||
$refreshUSBFuncDef = "function Invoke-WinUtilISORefreshUSBDrives {`n" + `
|
|
||||||
${function:Invoke-WinUtilISORefreshUSBDrives}.ToString() + "`n}"
|
|
||||||
$runspace.SessionStateProxy.SetVariable("refreshUSBFuncDef", $refreshUSBFuncDef)
|
|
||||||
|
|
||||||
$script = [Management.Automation.PowerShell]::Create()
|
$script = [Management.Automation.PowerShell]::Create()
|
||||||
$script.Runspace = $runspace
|
$script.Runspace = $runspace
|
||||||
$script.AddScript({
|
$script.AddScript({
|
||||||
|
|
||||||
# Import helper functions into this runspace
|
|
||||||
. ([scriptblock]::Create($isoScriptFuncDef))
|
. ([scriptblock]::Create($isoScriptFuncDef))
|
||||||
. ([scriptblock]::Create($win11ISOLogFuncDef))
|
. ([scriptblock]::Create($win11ISOLogFuncDef))
|
||||||
. ([scriptblock]::Create($refreshUSBFuncDef))
|
|
||||||
|
|
||||||
function Log($msg) {
|
function Log($msg) {
|
||||||
$ts = (Get-Date).ToString("HH:mm:ss")
|
$ts = (Get-Date).ToString("HH:mm:ss")
|
||||||
@@ -261,6 +202,7 @@ function Invoke-WinUtilISOModify {
|
|||||||
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
||||||
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
||||||
})
|
})
|
||||||
|
Add-Content -Path (Join-Path $workDir "WinUtil_Win11ISO.log") -Value "[$ts] $msg" -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetProgress($label, $pct) {
|
function SetProgress($label, $pct) {
|
||||||
@@ -272,173 +214,112 @@ function Invoke-WinUtilISOModify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
# ── Hide Steps 1-3 while modification is running; expand log to fill screen ──
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
$sync["WPFWin11ISOSelectSection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
||||||
$expandedHeight = [Math]::Max(400, $sync["Form"].ActualHeight - 100)
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Height = $expandedHeight
|
|
||||||
$sync["Win11ISOLogExpanded"] = $true
|
|
||||||
# Register the resize handler once so the log tracks window resizes
|
|
||||||
if (-not $sync["Win11ISOResizeHandlerAdded"]) {
|
|
||||||
$sync["Form"].add_SizeChanged({
|
|
||||||
if ($sync["Win11ISOLogExpanded"]) {
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Height = [Math]::Max(400, $sync["Form"].ActualHeight - 100)
|
|
||||||
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
|
||||||
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
$sync["Win11ISOResizeHandlerAdded"] = $true
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
# ── 1. Create working directory structure ──
|
|
||||||
Log "Creating working directory: $workDir"
|
Log "Creating working directory: $workDir"
|
||||||
$isoContents = Join-Path $workDir "iso_contents"
|
$isoContents = Join-Path $workDir "iso_contents"
|
||||||
$mountDir = Join-Path $workDir "wim_mount"
|
$mountDir = Join-Path $workDir "wim_mount"
|
||||||
New-Item -ItemType Directory -Path $isoContents, $mountDir -Force | Out-Null
|
New-Item -ItemType Directory -Path $isoContents, $mountDir -Force | Out-Null
|
||||||
SetProgress "Copying ISO contents..." 10
|
SetProgress "Copying ISO contents..." 10
|
||||||
|
|
||||||
# ── 2. Copy all ISO contents to the working directory ──
|
|
||||||
Log "Copying ISO contents from $driveLetter to $isoContents..."
|
Log "Copying ISO contents from $driveLetter to $isoContents..."
|
||||||
$robocopyArgs = @($driveLetter, $isoContents, "/E", "/NFL", "/NDL", "/NJH", "/NJS")
|
& robocopy $driveLetter $isoContents /E /NFL /NDL /NJH /NJS | Out-Null
|
||||||
& robocopy @robocopyArgs | Out-Null
|
|
||||||
Log "ISO contents copied."
|
Log "ISO contents copied."
|
||||||
SetProgress "Mounting install.wim..." 25
|
SetProgress "Mounting install.wim..." 25
|
||||||
|
|
||||||
# ── 3. Copy install.wim to working dir (it may be read-only on the DVD) ──
|
|
||||||
$localWim = Join-Path $isoContents "sources\install.wim"
|
$localWim = Join-Path $isoContents "sources\install.wim"
|
||||||
if (-not (Test-Path $localWim)) {
|
if (-not (Test-Path $localWim)) { $localWim = Join-Path $isoContents "sources\install.esd" }
|
||||||
# ESD path
|
|
||||||
$localWim = Join-Path $isoContents "sources\install.esd"
|
|
||||||
}
|
|
||||||
# Ensure the file is writable
|
|
||||||
Set-ItemProperty -Path $localWim -Name IsReadOnly -Value $false
|
Set-ItemProperty -Path $localWim -Name IsReadOnly -Value $false
|
||||||
|
|
||||||
# ── 4. Mount the selected edition of install.wim ──
|
|
||||||
Log "Mounting install.wim (Index ${selectedWimIndex}: $selectedEditionName) at $mountDir..."
|
Log "Mounting install.wim (Index ${selectedWimIndex}: $selectedEditionName) at $mountDir..."
|
||||||
Mount-WindowsImage -ImagePath $localWim -Index $selectedWimIndex -Path $mountDir -ErrorAction Stop | Out-Null
|
Mount-WindowsImage -ImagePath $localWim -Index $selectedWimIndex -Path $mountDir -ErrorAction Stop | Out-Null
|
||||||
SetProgress "Modifying install.wim..." 45
|
SetProgress "Modifying install.wim..." 45
|
||||||
|
|
||||||
# ── Apply all WinUtil modifications via Invoke-WinUtilISOScript ──
|
|
||||||
Log "Applying WinUtil modifications to install.wim..."
|
Log "Applying WinUtil modifications to install.wim..."
|
||||||
Invoke-WinUtilISOScript -ScratchDir $mountDir -ISOContentsDir $isoContents -AutoUnattendXml $autounattendContent -Log { param($m) Log $m }
|
Invoke-WinUtilISOScript -ScratchDir $mountDir -ISOContentsDir $isoContents -AutoUnattendXml $autounattendContent -InjectCurrentSystemDrivers $injectDrivers -Log { param($m) Log $m }
|
||||||
|
|
||||||
# ── 4b. DISM component store cleanup ──
|
|
||||||
# /ResetBase removes all superseded component versions from WinSxS,
|
|
||||||
# which is the single largest space saving possible (typically 300–800 MB).
|
|
||||||
# This must be done while the image is still mounted.
|
|
||||||
SetProgress "Cleaning up component store (WinSxS)..." 56
|
SetProgress "Cleaning up component store (WinSxS)..." 56
|
||||||
Log "Running DISM component store cleanup (/ResetBase)..."
|
Log "Running DISM component store cleanup (/ResetBase)..."
|
||||||
& dism /English "/image:$mountDir" /Cleanup-Image /StartComponentCleanup /ResetBase | ForEach-Object { Log $_ }
|
& dism /English "/image:$mountDir" /Cleanup-Image /StartComponentCleanup /ResetBase | ForEach-Object { Log $_ }
|
||||||
Log "Component store cleanup complete."
|
Log "Component store cleanup complete."
|
||||||
|
|
||||||
# ── 5. Save and dismount the WIM ──
|
|
||||||
SetProgress "Saving modified install.wim..." 65
|
SetProgress "Saving modified install.wim..." 65
|
||||||
Log "Dismounting and saving install.wim. This will take several minutes..."
|
Log "Dismounting and saving install.wim. This will take several minutes..."
|
||||||
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
||||||
Log "install.wim saved."
|
Log "install.wim saved."
|
||||||
|
|
||||||
# ── 5b. Strip unused editions — export only the selected index ──
|
|
||||||
# A standard multi-edition install.wim can be 4–5 GB; exporting a
|
|
||||||
# single index typically drops it to ~3 GB, saving 1–2 GB in the ISO.
|
|
||||||
SetProgress "Removing unused editions from install.wim..." 70
|
SetProgress "Removing unused editions from install.wim..." 70
|
||||||
Log "Exporting edition '$selectedEditionName' (Index $selectedWimIndex) to a single-edition install.wim..."
|
Log "Exporting edition '$selectedEditionName' (Index $selectedWimIndex) to a single-edition install.wim..."
|
||||||
$exportWim = Join-Path $isoContents "sources\install_export.wim"
|
$exportWim = Join-Path $isoContents "sources\install_export.wim"
|
||||||
Export-WindowsImage `
|
Export-WindowsImage -SourceImagePath $localWim -SourceIndex $selectedWimIndex -DestinationImagePath $exportWim -ErrorAction Stop | Out-Null
|
||||||
-SourceImagePath $localWim `
|
|
||||||
-SourceIndex $selectedWimIndex `
|
|
||||||
-DestinationImagePath $exportWim `
|
|
||||||
-ErrorAction Stop | Out-Null
|
|
||||||
Remove-Item -Path $localWim -Force
|
Remove-Item -Path $localWim -Force
|
||||||
Rename-Item -Path $exportWim -NewName "install.wim" -Force
|
Rename-Item -Path $exportWim -NewName "install.wim" -Force
|
||||||
# Update local path so later steps (e.g. ISO build) reference the new file
|
|
||||||
$localWim = Join-Path $isoContents "sources\install.wim"
|
$localWim = Join-Path $isoContents "sources\install.wim"
|
||||||
Log "Unused editions removed. install.wim now contains only '$selectedEditionName'."
|
Log "Unused editions removed. install.wim now contains only '$selectedEditionName'."
|
||||||
|
|
||||||
SetProgress "Dismounting source ISO..." 80
|
SetProgress "Dismounting source ISO..." 80
|
||||||
|
|
||||||
# ── 6. Dismount the original ISO ──
|
|
||||||
Log "Dismounting original ISO..."
|
Log "Dismounting original ISO..."
|
||||||
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
||||||
|
|
||||||
# Store work directory for output steps
|
|
||||||
$sync["Win11ISOWorkDir"] = $workDir
|
$sync["Win11ISOWorkDir"] = $workDir
|
||||||
$sync["Win11ISOContentsDir"] = $isoContents
|
$sync["Win11ISOContentsDir"] = $isoContents
|
||||||
|
|
||||||
SetProgress "Modification complete ✔" 100
|
SetProgress "Modification complete" 100
|
||||||
Log "install.wim modification complete. Choose an output option in Step 4."
|
Log "install.wim modification complete. Choose an output option in Step 4."
|
||||||
|
|
||||||
# ── Reveal Step 4 on the UI thread ──
|
|
||||||
# Note: USB drive enumeration (Get-Disk) is intentionally deferred to
|
|
||||||
# when the user explicitly selects the USB option, to avoid blocking
|
|
||||||
# the UI thread here.
|
|
||||||
$sync["WPFWin11ISOOutputSection"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOOutputSection"].Dispatcher.Invoke([action]{
|
||||||
$sync["WPFWin11ISOOutputSection"].Visibility = "Visible"
|
$sync["WPFWin11ISOOutputSection"].Visibility = "Visible"
|
||||||
})
|
})
|
||||||
}
|
} catch {
|
||||||
catch {
|
|
||||||
Log "ERROR during modification: $_"
|
Log "ERROR during modification: $_"
|
||||||
|
|
||||||
# ── Cleanup: dismount WIM if still mounted ──
|
|
||||||
try {
|
try {
|
||||||
if (Test-Path $mountDir) {
|
if (Test-Path $mountDir) {
|
||||||
$mountedImages = Get-WindowsImage -Mounted -ErrorAction SilentlyContinue |
|
$mountedImages = Get-WindowsImage -Mounted -ErrorAction SilentlyContinue | Where-Object { $_.Path -eq $mountDir }
|
||||||
Where-Object { $_.Path -eq $mountDir }
|
|
||||||
if ($mountedImages) {
|
if ($mountedImages) {
|
||||||
Log "Cleaning up: dismounting install.wim (discarding changes)..."
|
Log "Cleaning up: dismounting install.wim (discarding changes)..."
|
||||||
Dismount-WindowsImage -Path $mountDir -Discard -ErrorAction SilentlyContinue | Out-Null
|
Dismount-WindowsImage -Path $mountDir -Discard -ErrorAction SilentlyContinue | Out-Null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch { Log "Warning: could not dismount install.wim during cleanup: $_" }
|
||||||
Log "Warning: could not dismount install.wim during cleanup: $_"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Cleanup: dismount the source ISO ──
|
|
||||||
try {
|
try {
|
||||||
$mountedISO = Get-DiskImage -ImagePath $isoPath -ErrorAction SilentlyContinue
|
$mountedISO = Get-DiskImage -ImagePath $isoPath -ErrorAction SilentlyContinue
|
||||||
if ($mountedISO -and $mountedISO.Attached) {
|
if ($mountedISO -and $mountedISO.Attached) {
|
||||||
Log "Cleaning up: dismounting source ISO..."
|
Log "Cleaning up: dismounting source ISO..."
|
||||||
Dismount-DiskImage -ImagePath $isoPath -ErrorAction SilentlyContinue | Out-Null
|
Dismount-DiskImage -ImagePath $isoPath -ErrorAction SilentlyContinue | Out-Null
|
||||||
}
|
}
|
||||||
} catch {
|
} catch { Log "Warning: could not dismount ISO during cleanup: $_" }
|
||||||
Log "Warning: could not dismount ISO during cleanup: $_"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Cleanup: remove temp working directory ──
|
|
||||||
try {
|
try {
|
||||||
if (Test-Path $workDir) {
|
if (Test-Path $workDir) {
|
||||||
Log "Cleaning up: removing temp directory $workDir..."
|
Log "Cleaning up: removing temp directory $workDir..."
|
||||||
Remove-Item -Path $workDir -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path $workDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
} catch {
|
} catch { Log "Warning: could not remove temp directory during cleanup: $_" }
|
||||||
Log "Warning: could not remove temp directory during cleanup: $_"
|
|
||||||
}
|
|
||||||
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show(
|
||||||
"An error occurred during install.wim modification:`n`n$_",
|
"An error occurred during install.wim modification:`n`n$_",
|
||||||
"Modification Error", "OK", "Error")
|
"Modification Error", "OK", "Error")
|
||||||
})
|
})
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
Start-Sleep -Milliseconds 800
|
Start-Sleep -Milliseconds 800
|
||||||
|
$sync["Win11ISOModifying"] = $false
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
$sync.progressBarTextBlock.Text = ""
|
$sync.progressBarTextBlock.Text = ""
|
||||||
$sync.progressBarTextBlock.ToolTip = ""
|
$sync.progressBarTextBlock.ToolTip = ""
|
||||||
$sync.ProgressBar.Value = 0
|
$sync.ProgressBar.Value = 0
|
||||||
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true
|
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true
|
||||||
# ── Only restore steps 1-3 if Step 4 was NOT successfully shown ──
|
|
||||||
# When modification succeeds, Step 4 is visible and steps 1-3 stay
|
|
||||||
# hidden until the user clicks Clean & Reset.
|
|
||||||
if ($sync["WPFWin11ISOOutputSection"].Visibility -ne "Visible") {
|
if ($sync["WPFWin11ISOOutputSection"].Visibility -ne "Visible") {
|
||||||
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
|
||||||
$sync["WPFWin11ISOMountSection"].Visibility = "Visible"
|
$sync["WPFWin11ISOMountSection"].Visibility = "Visible"
|
||||||
$sync["WPFWin11ISOModifySection"].Visibility = "Visible"
|
$sync["WPFWin11ISOModifySection"].Visibility = "Visible"
|
||||||
}
|
}
|
||||||
$sync["Win11ISOLogExpanded"] = $false
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Height = 140
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}) | Out-Null
|
}) | Out-Null
|
||||||
@@ -446,13 +327,41 @@ function Invoke-WinUtilISOModify {
|
|||||||
$script.BeginInvoke() | Out-Null
|
$script.BeginInvoke() | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-WinUtilISOCleanAndReset {
|
function Invoke-WinUtilISOCheckExistingWork {
|
||||||
<#
|
if ($sync["Win11ISOContentsDir"] -and (Test-Path $sync["Win11ISOContentsDir"])) { return }
|
||||||
.SYNOPSIS
|
|
||||||
Deletes the temporary working directory created during ISO modification
|
|
||||||
and resets the entire ISO UI back to its initial state (Step 1 only).
|
|
||||||
#>
|
|
||||||
|
|
||||||
|
# Check if ISO modification is currently in progress
|
||||||
|
if ($sync["Win11ISOModifying"]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.PSIsContainer } | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||||
|
|
||||||
|
if (-not $existingWorkDir) { return }
|
||||||
|
|
||||||
|
$isoContents = Join-Path $existingWorkDir.FullName "iso_contents"
|
||||||
|
if (-not (Test-Path $isoContents)) { return }
|
||||||
|
|
||||||
|
$sync["Win11ISOWorkDir"] = $existingWorkDir.FullName
|
||||||
|
$sync["Win11ISOContentsDir"] = $isoContents
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOOutputSection"].Visibility = "Visible"
|
||||||
|
|
||||||
|
$modified = $existingWorkDir.LastWriteTime.ToString("yyyy-MM-dd HH:mm")
|
||||||
|
Write-Win11ISOLog "Existing working directory found: $($existingWorkDir.FullName)"
|
||||||
|
Write-Win11ISOLog "Last modified: $modified - Skipping Steps 1-3 and resuming at Step 4."
|
||||||
|
Write-Win11ISOLog "Click 'Clean & Reset' if you want to start over with a new ISO."
|
||||||
|
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"A previous WinUtil ISO working directory was found:`n`n$($existingWorkDir.FullName)`n`n(Last modified: $modified)`n`nStep 4 (output options) has been restored so you can save the already-modified image.`n`nClick 'Clean & Reset' in Step 4 if you want to start over.",
|
||||||
|
"Existing Work Found", "OK", "Info")
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-WinUtilISOCleanAndReset {
|
||||||
$workDir = $sync["Win11ISOWorkDir"]
|
$workDir = $sync["Win11ISOWorkDir"]
|
||||||
|
|
||||||
if ($workDir -and (Test-Path $workDir)) {
|
if ($workDir -and (Test-Path $workDir)) {
|
||||||
@@ -460,17 +369,104 @@ function Invoke-WinUtilISOCleanAndReset {
|
|||||||
"This will delete the temporary working directory:`n`n$workDir`n`nAnd reset the interface back to the start.`n`nContinue?",
|
"This will delete the temporary working directory:`n`n$workDir`n`nAnd reset the interface back to the start.`n`nContinue?",
|
||||||
"Clean & Reset", "YesNo", "Warning")
|
"Clean & Reset", "YesNo", "Warning")
|
||||||
if ($confirm -ne "Yes") { return }
|
if ($confirm -ne "Yes") { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $false
|
||||||
|
|
||||||
|
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
||||||
|
$runspace.ApartmentState = "STA"
|
||||||
|
$runspace.ThreadOptions = "ReuseThread"
|
||||||
|
$runspace.Open()
|
||||||
|
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("workDir", $workDir)
|
||||||
|
|
||||||
|
$script = [Management.Automation.PowerShell]::Create()
|
||||||
|
$script.Runspace = $runspace
|
||||||
|
$script.AddScript({
|
||||||
|
|
||||||
|
function Log($msg) {
|
||||||
|
$ts = (Get-Date).ToString("HH:mm:ss")
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg"
|
||||||
|
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
||||||
|
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
||||||
|
})
|
||||||
|
Add-Content -Path (Join-Path $workDir "WinUtil_Win11ISO.log") -Value "[$ts] $msg" -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetProgress($label, $pct) {
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync.progressBarTextBlock.Text = $label
|
||||||
|
$sync.progressBarTextBlock.ToolTip = $label
|
||||||
|
$sync.ProgressBar.Value = [Math]::Max($pct, 5)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Write-Win11ISOLog "Deleting temp directory: $workDir"
|
if ($workDir) {
|
||||||
Remove-Item -Path $workDir -Recurse -Force -ErrorAction Stop
|
$mountDir = Join-Path $workDir "wim_mount"
|
||||||
Write-Win11ISOLog "Temp directory deleted."
|
try {
|
||||||
|
$mountedImages = Get-WindowsImage -Mounted -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.Path -like "$workDir*" }
|
||||||
|
if ($mountedImages) {
|
||||||
|
foreach ($img in $mountedImages) {
|
||||||
|
Log "Dismounting WIM at: $($img.Path) (discarding changes)..."
|
||||||
|
SetProgress "Dismounting WIM image..." 3
|
||||||
|
Dismount-WindowsImage -Path $img.Path -Discard -ErrorAction Stop | Out-Null
|
||||||
|
Log "WIM dismounted successfully."
|
||||||
|
}
|
||||||
|
} elseif (Test-Path $mountDir) {
|
||||||
|
Log "No mounted WIM reported by Get-WindowsImage, running DISM /Cleanup-Wim as a precaution..."
|
||||||
|
SetProgress "Running DISM cleanup..." 3
|
||||||
|
& dism /English /Cleanup-Wim 2>&1 | ForEach-Object { Log $_ }
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
Write-Win11ISOLog "WARNING: could not fully delete temp directory: $_"
|
Log "Warning: could not dismount WIM cleanly, attempting DISM /Cleanup-Wim fallback: $_"
|
||||||
|
try { & dism /English /Cleanup-Wim 2>&1 | ForEach-Object { Log $_ } }
|
||||||
|
catch { Log "Warning: DISM /Cleanup-Wim also failed: $_" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Clear all stored ISO state
|
if ($workDir -and (Test-Path $workDir)) {
|
||||||
|
Log "Scanning files to delete in: $workDir"
|
||||||
|
SetProgress "Scanning files..." 5
|
||||||
|
|
||||||
|
$allFiles = @(Get-ChildItem -Path $workDir -File -Recurse -Force -ErrorAction SilentlyContinue)
|
||||||
|
$allDirs = @(Get-ChildItem -Path $workDir -Directory -Recurse -Force -ErrorAction SilentlyContinue |
|
||||||
|
Sort-Object { $_.FullName.Length } -Descending)
|
||||||
|
$total = $allFiles.Count
|
||||||
|
$deleted = 0
|
||||||
|
|
||||||
|
Log "Found $total files to delete."
|
||||||
|
|
||||||
|
foreach ($f in $allFiles) {
|
||||||
|
try { Remove-Item -Path $f.FullName -Force -ErrorAction Stop } catch { Log "WARNING: could not delete $($f.FullName): $_" }
|
||||||
|
$deleted++
|
||||||
|
if ($deleted % 100 -eq 0 -or $deleted -eq $total) {
|
||||||
|
$pct = [math]::Round(($deleted / [Math]::Max($total, 1)) * 85) + 5
|
||||||
|
SetProgress "Deleting files in $($f.Directory.Name)... ($deleted / $total)" $pct
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($d in $allDirs) {
|
||||||
|
try { Remove-Item -Path $d.FullName -Force -ErrorAction SilentlyContinue } catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
try { Remove-Item -Path $workDir -Recurse -Force -ErrorAction Stop } catch {}
|
||||||
|
|
||||||
|
if (Test-Path $workDir) {
|
||||||
|
Log "WARNING: some items could not be deleted in $workDir"
|
||||||
|
} else {
|
||||||
|
Log "Temp directory deleted successfully."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log "No temp directory found — resetting UI."
|
||||||
|
}
|
||||||
|
|
||||||
|
SetProgress "Resetting UI..." 95
|
||||||
|
Log "Resetting interface..."
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
$sync["Win11ISOWorkDir"] = $null
|
$sync["Win11ISOWorkDir"] = $null
|
||||||
$sync["Win11ISOContentsDir"] = $null
|
$sync["Win11ISOContentsDir"] = $null
|
||||||
$sync["Win11ISOImagePath"] = $null
|
$sync["Win11ISOImagePath"] = $null
|
||||||
@@ -479,7 +475,6 @@ function Invoke-WinUtilISOCleanAndReset {
|
|||||||
$sync["Win11ISOImageInfo"] = $null
|
$sync["Win11ISOImageInfo"] = $null
|
||||||
$sync["Win11ISOUSBDisks"] = $null
|
$sync["Win11ISOUSBDisks"] = $null
|
||||||
|
|
||||||
# Reset the UI to the initial state
|
|
||||||
$sync["WPFWin11ISOPath"].Text = "No ISO selected..."
|
$sync["WPFWin11ISOPath"].Text = "No ISO selected..."
|
||||||
$sync["WPFWin11ISOFileInfo"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOFileInfo"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
|
||||||
@@ -488,23 +483,35 @@ function Invoke-WinUtilISOCleanAndReset {
|
|||||||
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
|
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
|
||||||
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
|
||||||
$sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin."
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Height = 140
|
|
||||||
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true
|
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true
|
||||||
|
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true
|
||||||
|
|
||||||
|
$sync.progressBarTextBlock.Text = ""
|
||||||
|
$sync.progressBarTextBlock.ToolTip = ""
|
||||||
|
$sync.ProgressBar.Value = 0
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin."
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
Log "ERROR during Clean & Reset: $_"
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync.progressBarTextBlock.Text = ""
|
||||||
|
$sync.progressBarTextBlock.ToolTip = ""
|
||||||
|
$sync.ProgressBar.Value = 0
|
||||||
|
$sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}) | Out-Null
|
||||||
|
|
||||||
|
$script.BeginInvoke() | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-WinUtilISOExport {
|
function Invoke-WinUtilISOExport {
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Saves the modified ISO contents as a new bootable ISO file.
|
|
||||||
Uses oscdimg.exe (part of the Windows ADK) if present; falls back
|
|
||||||
to a reminder message if not installed.
|
|
||||||
#>
|
|
||||||
$contentsDir = $sync["Win11ISOContentsDir"]
|
$contentsDir = $sync["Win11ISOContentsDir"]
|
||||||
|
|
||||||
if (-not $contentsDir -or -not (Test-Path $contentsDir)) {
|
if (-not $contentsDir -or -not (Test-Path $contentsDir)) {
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show(
|
||||||
"No modified ISO content found. Please complete Steps 1–3 first.",
|
"No modified ISO content found. Please complete Steps 1-3 first.",
|
||||||
"Not Ready", "OK", "Warning")
|
"Not Ready", "OK", "Warning")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -520,9 +527,6 @@ function Invoke-WinUtilISOExport {
|
|||||||
if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return }
|
if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return }
|
||||||
|
|
||||||
$outputISO = $dlg.FileName
|
$outputISO = $dlg.FileName
|
||||||
Write-Win11ISOLog "Exporting to ISO: $outputISO"
|
|
||||||
|
|
||||||
Set-WinUtilProgressBar -Label "Building ISO..." -Percent 10
|
|
||||||
|
|
||||||
# Locate oscdimg.exe (Windows ADK or winget per-user install)
|
# Locate oscdimg.exe (Windows ADK or winget per-user install)
|
||||||
$oscdimg = Get-ChildItem "C:\Program Files (x86)\Windows Kits" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
$oscdimg = Get-ChildItem "C:\Program Files (x86)\Windows Kits" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
||||||
@@ -535,12 +539,10 @@ function Invoke-WinUtilISOExport {
|
|||||||
|
|
||||||
if (-not $oscdimg) {
|
if (-not $oscdimg) {
|
||||||
Write-Win11ISOLog "oscdimg.exe not found. Attempting to install via winget..."
|
Write-Win11ISOLog "oscdimg.exe not found. Attempting to install via winget..."
|
||||||
Set-WinUtilProgressBar -Label "Installing oscdimg..." -Percent 5
|
|
||||||
try {
|
try {
|
||||||
$winget = Get-Command winget -ErrorAction Stop
|
$winget = Get-Command winget -ErrorAction Stop
|
||||||
$result = & $winget install -e --id Microsoft.OSCDIMG --accept-package-agreements --accept-source-agreements 2>&1
|
$result = & $winget install -e --id Microsoft.OSCDIMG --accept-package-agreements --accept-source-agreements 2>&1
|
||||||
Write-Win11ISOLog "winget output: $result"
|
Write-Win11ISOLog "winget output: $result"
|
||||||
# Re-scan after install
|
|
||||||
$oscdimg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
$oscdimg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
||||||
Where-Object { $_.FullName -match 'Microsoft\.OSCDIMG' } |
|
Where-Object { $_.FullName -match 'Microsoft\.OSCDIMG' } |
|
||||||
Select-Object -First 1 -ExpandProperty FullName
|
Select-Object -First 1 -ExpandProperty FullName
|
||||||
@@ -549,7 +551,6 @@ function Invoke-WinUtilISOExport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (-not $oscdimg) {
|
if (-not $oscdimg) {
|
||||||
Set-WinUtilProgressBar -Label "" -Percent 0
|
|
||||||
Write-Win11ISOLog "oscdimg.exe still not found after install attempt."
|
Write-Win11ISOLog "oscdimg.exe still not found after install attempt."
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show(
|
||||||
"oscdimg.exe could not be found or installed automatically.`n`nPlease install it manually:`n winget install -e --id Microsoft.OSCDIMG`n`nOr install the Windows ADK from:`nhttps://learn.microsoft.com/windows-hardware/get-started/adk-install",
|
"oscdimg.exe could not be found or installed automatically.`n`nPlease install it manually:`n winget install -e --id Microsoft.OSCDIMG`n`nOr install the Windows ADK from:`nhttps://learn.microsoft.com/windows-hardware/get-started/adk-install",
|
||||||
@@ -559,21 +560,42 @@ function Invoke-WinUtilISOExport {
|
|||||||
Write-Win11ISOLog "oscdimg.exe installed successfully."
|
Write-Win11ISOLog "oscdimg.exe installed successfully."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build boot parameters (BIOS + UEFI dual-boot)
|
$sync["WPFWin11ISOChooseISOButton"].IsEnabled = $false
|
||||||
$bootData = "2#p0,e,b`"$contentsDir\boot\etfsboot.com`"#pEF,e,b`"$contentsDir\efi\microsoft\boot\efisys.bin`""
|
|
||||||
$oscdimgArgs = @(
|
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
||||||
"-m", # ignore source path max size
|
$runspace.ApartmentState = "STA"
|
||||||
"-o", # optimise storage
|
$runspace.ThreadOptions = "ReuseThread"
|
||||||
"-u2", # UDF 2.01
|
$runspace.Open()
|
||||||
"-udfver102",
|
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
||||||
"-bootdata:$bootData",
|
$runspace.SessionStateProxy.SetVariable("contentsDir", $contentsDir)
|
||||||
"-l`"CTOS_MODIFIED`"",
|
$runspace.SessionStateProxy.SetVariable("outputISO", $outputISO)
|
||||||
"`"$contentsDir`"",
|
$runspace.SessionStateProxy.SetVariable("oscdimg", $oscdimg)
|
||||||
"`"$outputISO`""
|
|
||||||
)
|
$win11ISOLogFuncDef = "function Write-Win11ISOLog {`n" + ${function:Write-Win11ISOLog}.ToString() + "`n}"
|
||||||
|
$runspace.SessionStateProxy.SetVariable("win11ISOLogFuncDef", $win11ISOLogFuncDef)
|
||||||
|
|
||||||
|
$script = [Management.Automation.PowerShell]::Create()
|
||||||
|
$script.Runspace = $runspace
|
||||||
|
$script.AddScript({
|
||||||
|
. ([scriptblock]::Create($win11ISOLogFuncDef))
|
||||||
|
|
||||||
|
function SetProgress($label, $pct) {
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync.progressBarTextBlock.Text = $label
|
||||||
|
$sync.progressBarTextBlock.ToolTip = $label
|
||||||
|
$sync.ProgressBar.Value = [Math]::Max($pct, 5)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Write-Win11ISOLog "Exporting to ISO: $outputISO"
|
||||||
|
SetProgress "Building ISO..." 10
|
||||||
|
|
||||||
|
$bootData = "2#p0,e,b`"$contentsDir\boot\etfsboot.com`"#pEF,e,b`"$contentsDir\efi\microsoft\boot\efisys.bin`""
|
||||||
|
$oscdimgArgs = @("-m", "-o", "-u2", "-udfver102", "-bootdata:$bootData", "-l`"CTOS_MODIFIED`"", "`"$contentsDir`"", "`"$outputISO`"")
|
||||||
|
|
||||||
Write-Win11ISOLog "Running oscdimg..."
|
Write-Win11ISOLog "Running oscdimg..."
|
||||||
|
|
||||||
$psi = [System.Diagnostics.ProcessStartInfo]::new()
|
$psi = [System.Diagnostics.ProcessStartInfo]::new()
|
||||||
$psi.FileName = $oscdimg
|
$psi.FileName = $oscdimg
|
||||||
$psi.Arguments = $oscdimgArgs -join " "
|
$psi.Arguments = $oscdimgArgs -join " "
|
||||||
@@ -586,230 +608,46 @@ function Invoke-WinUtilISOExport {
|
|||||||
$proc.StartInfo = $psi
|
$proc.StartInfo = $psi
|
||||||
$proc.Start() | Out-Null
|
$proc.Start() | Out-Null
|
||||||
|
|
||||||
# Stream stdout and stderr line-by-line to the status log
|
# Stream stdout line-by-line as oscdimg runs
|
||||||
$stdoutTask = $proc.StandardOutput.ReadToEndAsync()
|
while (-not $proc.StandardOutput.EndOfStream) {
|
||||||
$stderrTask = $proc.StandardError.ReadToEndAsync()
|
$line = $proc.StandardOutput.ReadLine()
|
||||||
$proc.WaitForExit()
|
|
||||||
[System.Threading.Tasks.Task]::WaitAll($stdoutTask, $stderrTask)
|
|
||||||
|
|
||||||
foreach ($line in ($stdoutTask.Result -split "`r?`n")) {
|
|
||||||
if ($line.Trim()) { Write-Win11ISOLog $line }
|
if ($line.Trim()) { Write-Win11ISOLog $line }
|
||||||
}
|
}
|
||||||
foreach ($line in ($stderrTask.Result -split "`r?`n")) {
|
|
||||||
|
$proc.WaitForExit()
|
||||||
|
|
||||||
|
# Flush any stderr after process exits
|
||||||
|
$stderr = $proc.StandardError.ReadToEnd()
|
||||||
|
foreach ($line in ($stderr -split "`r?`n")) {
|
||||||
if ($line.Trim()) { Write-Win11ISOLog "[stderr]$line" }
|
if ($line.Trim()) { Write-Win11ISOLog "[stderr]$line" }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($proc.ExitCode -eq 0) {
|
if ($proc.ExitCode -eq 0) {
|
||||||
Set-WinUtilProgressBar -Label "ISO exported ✔" -Percent 100
|
SetProgress "ISO exported" 100
|
||||||
Write-Win11ISOLog "ISO exported successfully: $outputISO"
|
Write-Win11ISOLog "ISO exported successfully: $outputISO"
|
||||||
[System.Windows.MessageBox]::Show(
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
"ISO exported successfully!`n`n$outputISO",
|
[System.Windows.MessageBox]::Show("ISO exported successfully!`n`n$outputISO", "Export Complete", "OK", "Info")
|
||||||
"Export Complete", "OK", "Info")
|
})
|
||||||
} else {
|
} else {
|
||||||
Write-Win11ISOLog "oscdimg exited with code $($proc.ExitCode)."
|
Write-Win11ISOLog "oscdimg exited with code $($proc.ExitCode)."
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
[System.Windows.MessageBox]::Show(
|
[System.Windows.MessageBox]::Show(
|
||||||
"oscdimg exited with code $($proc.ExitCode).`nCheck the status log for details.",
|
"oscdimg exited with code $($proc.ExitCode).`nCheck the status log for details.",
|
||||||
"Export Error", "OK", "Error")
|
"Export Error", "OK", "Error")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
} catch {
|
||||||
catch {
|
|
||||||
Write-Win11ISOLog "ERROR during ISO export: $_"
|
Write-Win11ISOLog "ERROR during ISO export: $_"
|
||||||
[System.Windows.MessageBox]::Show("ISO export failed:`n`n$_","Error","OK","Error")
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
Start-Sleep -Milliseconds 800
|
|
||||||
Set-WinUtilProgressBar -Label "" -Percent 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Invoke-WinUtilISORefreshUSBDrives {
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Populates the USB drive ComboBox with all currently attached removable drives.
|
|
||||||
#>
|
|
||||||
$combo = $sync["WPFWin11ISOUSBDriveComboBox"]
|
|
||||||
$combo.Items.Clear()
|
|
||||||
|
|
||||||
$removable = Get-Disk | Where-Object { $_.BusType -eq "USB" } | Sort-Object Number
|
|
||||||
|
|
||||||
if ($removable.Count -eq 0) {
|
|
||||||
$combo.Items.Add("No USB drives detected")
|
|
||||||
$combo.SelectedIndex = 0
|
|
||||||
Write-Win11ISOLog "No USB drives detected."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($disk in $removable) {
|
|
||||||
$sizeGB = [math]::Round($disk.Size / 1GB, 1)
|
|
||||||
$label = "Disk $($disk.Number): $($disk.FriendlyName) [$sizeGB GB] — $($disk.PartitionStyle)"
|
|
||||||
$combo.Items.Add($label)
|
|
||||||
}
|
|
||||||
$combo.SelectedIndex = 0
|
|
||||||
Write-Win11ISOLog "Found $($removable.Count) USB drive(s)."
|
|
||||||
|
|
||||||
# Store disk objects for later use
|
|
||||||
$sync["Win11ISOUSBDisks"] = $removable
|
|
||||||
}
|
|
||||||
|
|
||||||
function Invoke-WinUtilISOWriteUSB {
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Erases the selected USB drive and writes the modified Windows 11 ISO
|
|
||||||
content as a bootable installation drive (using DISM / robocopy approach).
|
|
||||||
#>
|
|
||||||
$contentsDir = $sync["Win11ISOContentsDir"]
|
|
||||||
$usbDisks = $sync["Win11ISOUSBDisks"]
|
|
||||||
|
|
||||||
if (-not $contentsDir -or -not (Test-Path $contentsDir)) {
|
|
||||||
[System.Windows.MessageBox]::Show(
|
|
||||||
"No modified ISO content found. Please complete Steps 1–3 first.",
|
|
||||||
"Not Ready", "OK", "Warning")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$selectedIndex = $sync["WPFWin11ISOUSBDriveComboBox"].SelectedIndex
|
|
||||||
if ($selectedIndex -lt 0 -or -not $usbDisks -or $selectedIndex -ge $usbDisks.Count) {
|
|
||||||
[System.Windows.MessageBox]::Show(
|
|
||||||
"Please select a USB drive from the dropdown.",
|
|
||||||
"No Drive Selected", "OK", "Warning")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$targetDisk = $usbDisks[$selectedIndex]
|
|
||||||
$diskNum = $targetDisk.Number
|
|
||||||
$sizeGB = [math]::Round($targetDisk.Size / 1GB, 1)
|
|
||||||
|
|
||||||
$confirm = [System.Windows.MessageBox]::Show(
|
|
||||||
"ALL data on Disk $diskNum ($($targetDisk.FriendlyName), $sizeGB GB) will be PERMANENTLY ERASED.`n`nAre you sure you want to continue?",
|
|
||||||
"Confirm USB Erase", "YesNo", "Warning")
|
|
||||||
|
|
||||||
if ($confirm -ne "Yes") {
|
|
||||||
Write-Win11ISOLog "USB write cancelled by user."
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $false
|
|
||||||
Write-Win11ISOLog "Starting USB write to Disk $diskNum..."
|
|
||||||
|
|
||||||
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
|
||||||
$runspace.ApartmentState = "STA"
|
|
||||||
$runspace.ThreadOptions = "ReuseThread"
|
|
||||||
$runspace.Open()
|
|
||||||
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
|
||||||
$runspace.SessionStateProxy.SetVariable("diskNum", $diskNum)
|
|
||||||
$runspace.SessionStateProxy.SetVariable("contentsDir", $contentsDir)
|
|
||||||
|
|
||||||
$script = [Management.Automation.PowerShell]::Create()
|
|
||||||
$script.Runspace = $runspace
|
|
||||||
$script.AddScript({
|
|
||||||
|
|
||||||
function Log($msg) {
|
|
||||||
$ts = (Get-Date).ToString("HH:mm:ss")
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg"
|
[System.Windows.MessageBox]::Show("ISO export failed:`n`n$_", "Error", "OK", "Error")
|
||||||
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
|
||||||
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
|
||||||
})
|
})
|
||||||
}
|
} finally {
|
||||||
function SetProgress($label, $pct) {
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
|
||||||
$sync.progressBarTextBlock.Text = $label
|
|
||||||
$sync.progressBarTextBlock.ToolTip = $label
|
|
||||||
$sync.ProgressBar.Value = [Math]::Max($pct, 5)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
SetProgress "Formatting USB drive..." 10
|
|
||||||
|
|
||||||
# ── Diskpart script: clean, GPT, create ESP + data partitions ──
|
|
||||||
$dpScript = @"
|
|
||||||
select disk $diskNum
|
|
||||||
clean
|
|
||||||
convert gpt
|
|
||||||
create partition efi size=512
|
|
||||||
format quick fs=fat32 label="SYSTEM"
|
|
||||||
assign
|
|
||||||
create partition primary
|
|
||||||
format quick fs=fat32 label="WINPE"
|
|
||||||
assign
|
|
||||||
exit
|
|
||||||
"@
|
|
||||||
$dpFile = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt"
|
|
||||||
$dpScript | Set-Content -Path $dpFile -Encoding ASCII
|
|
||||||
Log "Running diskpart on Disk $diskNum..."
|
|
||||||
diskpart /s $dpFile | Out-Null
|
|
||||||
Remove-Item $dpFile -Force
|
|
||||||
|
|
||||||
SetProgress "Identifying USB partitions..." 30
|
|
||||||
Start-Sleep -Seconds 3 # let Windows assign drive letters
|
|
||||||
|
|
||||||
# Find newly assigned drive letter for the data partition
|
|
||||||
$usbVol = Get-Partition -DiskNumber $diskNum |
|
|
||||||
Where-Object { $_.Type -eq "Basic" } |
|
|
||||||
Get-Volume |
|
|
||||||
Where-Object { $_.FileSystemLabel -eq "WINPE" } |
|
|
||||||
Select-Object -First 1
|
|
||||||
|
|
||||||
if (-not $usbVol) {
|
|
||||||
throw "Could not locate the formatted USB data partition. Drive letter may not have been assigned automatically."
|
|
||||||
}
|
|
||||||
|
|
||||||
$usbDrive = "$($usbVol.DriveLetter):"
|
|
||||||
Log "USB data partition: $usbDrive"
|
|
||||||
SetProgress "Copying Windows 11 files to USB..." 45
|
|
||||||
|
|
||||||
# ── Copy files (split large install.wim if > 4 GB for FAT32) ──
|
|
||||||
$installWim = Join-Path $contentsDir "sources\install.wim"
|
|
||||||
if (Test-Path $installWim) {
|
|
||||||
$wimSizeMB = [math]::Round((Get-Item $installWim).Length / 1MB)
|
|
||||||
if ($wimSizeMB -gt 3800) {
|
|
||||||
# FAT32 limit – split with DISM
|
|
||||||
Log "install.wim is $wimSizeMB MB – splitting for FAT32 compatibility..."
|
|
||||||
$splitDest = Join-Path $usbDrive "sources\install.swm"
|
|
||||||
New-Item -ItemType Directory -Path (Split-Path $splitDest) -Force | Out-Null
|
|
||||||
Split-WindowsImage -ImagePath $installWim `
|
|
||||||
-SplitImagePath $splitDest `
|
|
||||||
-FileSize 3800 -CheckIntegrity | Out-Null
|
|
||||||
Log "install.wim split complete."
|
|
||||||
|
|
||||||
# Copy everything else (exclude install.wim)
|
|
||||||
$robocopyArgs = @($contentsDir, $usbDrive, "/E", "/XF", "install.wim", "/NFL", "/NDL", "/NJH", "/NJS")
|
|
||||||
& robocopy @robocopyArgs | Out-Null
|
|
||||||
} else {
|
|
||||||
& robocopy $contentsDir $usbDrive /E /NFL /NDL /NJH /NJS | Out-Null
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
& robocopy $contentsDir $usbDrive /E /NFL /NDL /NJH /NJS | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
SetProgress "Finalising USB drive..." 90
|
|
||||||
Log "Files copied to USB."
|
|
||||||
|
|
||||||
SetProgress "USB write complete ✔" 100
|
|
||||||
Log "USB drive is ready for use."
|
|
||||||
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
|
||||||
[System.Windows.MessageBox]::Show(
|
|
||||||
"USB drive created successfully!`n`nYou can now boot from this drive to install Windows 11.",
|
|
||||||
"USB Ready", "OK", "Info")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Log "ERROR during USB write: $_"
|
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
|
||||||
[System.Windows.MessageBox]::Show(
|
|
||||||
"USB write failed:`n`n$_",
|
|
||||||
"USB Write Error", "OK", "Error")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
Start-Sleep -Milliseconds 800
|
Start-Sleep -Milliseconds 800
|
||||||
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
$sync.progressBarTextBlock.Text = ""
|
$sync.progressBarTextBlock.Text = ""
|
||||||
$sync.progressBarTextBlock.ToolTip = ""
|
$sync.progressBarTextBlock.ToolTip = ""
|
||||||
$sync.ProgressBar.Value = 0
|
$sync.ProgressBar.Value = 0
|
||||||
$sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $true
|
$sync["WPFWin11ISOChooseISOButton"].IsEnabled = $true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}) | Out-Null
|
}) | Out-Null
|
||||||
|
|||||||
@@ -4,50 +4,38 @@ function Invoke-WinUtilISOScript {
|
|||||||
Applies WinUtil modifications to a mounted Windows 11 install.wim image.
|
Applies WinUtil modifications to a mounted Windows 11 install.wim image.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Performs the following operations against an already-mounted WIM image:
|
Removes AppX bloatware and OneDrive, optionally injects all drivers exported from
|
||||||
|
the running system into install.wim and boot.wim (controlled by the
|
||||||
|
-InjectCurrentSystemDrivers switch), applies offline registry tweaks (hardware
|
||||||
|
bypass, privacy, OOBE, telemetry, update suppression), deletes CEIP/WU
|
||||||
|
scheduled-task definition files, and optionally writes autounattend.xml to the ISO
|
||||||
|
root and removes the support\ folder from the ISO contents directory.
|
||||||
|
|
||||||
1. Removes provisioned AppX bloatware packages via DISM.
|
All setup scripts embedded in the autounattend.xml <Extensions><File> nodes are
|
||||||
2. Removes OneDriveSetup.exe from the system image.
|
written directly into the WIM at their target paths under C:\Windows\Setup\Scripts\
|
||||||
3. Loads offline registry hives (COMPONENTS, DEFAULT, NTUSER, SOFTWARE, SYSTEM)
|
to ensure they survive Windows Setup stripping unrecognised-namespace XML elements
|
||||||
and applies the following tweaks:
|
from the Panther copy of the answer file.
|
||||||
- Bypasses hardware requirement checks (CPU, RAM, SecureBoot, Storage, TPM).
|
|
||||||
- Disables sponsored-app delivery and ContentDeliveryManager features.
|
|
||||||
- Enables local-account OOBE path (BypassNRO).
|
|
||||||
- Writes autounattend.xml to the Sysprep directory inside the WIM and,
|
|
||||||
optionally, to the ISO/USB root so Windows Setup picks it up at boot.
|
|
||||||
- Disables reserved storage.
|
|
||||||
- Disables BitLocker device encryption.
|
|
||||||
- Hides the Chat (Teams) taskbar icon.
|
|
||||||
- Disables OneDrive folder backup (KFM).
|
|
||||||
- Disables telemetry, advertising ID, and input personalization.
|
|
||||||
- Blocks post-install delivery of DevHome, Outlook, and Teams.
|
|
||||||
- Disables Windows Copilot.
|
|
||||||
- Disables Windows Update during OOBE.
|
|
||||||
4. Deletes unwanted scheduled-task XML definition files (CEIP, Appraiser, etc.).
|
|
||||||
5. Removes the support\ folder from the ISO contents directory (if supplied).
|
|
||||||
|
|
||||||
Mounting and dismounting the WIM is the responsibility of the caller
|
Mounting/dismounting the WIM is the caller's responsibility (e.g. Invoke-WinUtilISO).
|
||||||
(e.g. Invoke-WinUtilISO).
|
|
||||||
|
|
||||||
.PARAMETER ScratchDir
|
.PARAMETER ScratchDir
|
||||||
Mandatory. Full path to the directory where the Windows image is currently mounted.
|
Mandatory. Full path to the directory where the Windows image is currently mounted.
|
||||||
Example: C:\Users\USERNAME\AppData\Local\Temp\WinUtil_Win11ISO_20260222\wim_mount
|
|
||||||
|
|
||||||
.PARAMETER ISOContentsDir
|
.PARAMETER ISOContentsDir
|
||||||
Optional. Root directory of the extracted ISO contents.
|
Optional. Root directory of the extracted ISO contents. When supplied,
|
||||||
When supplied, autounattend.xml is also written here so Windows Setup picks it
|
autounattend.xml is written here and the support\ folder is removed.
|
||||||
up automatically at boot, and the support\ folder is deleted from that location.
|
|
||||||
|
|
||||||
.PARAMETER AutoUnattendXml
|
.PARAMETER AutoUnattendXml
|
||||||
Optional. Full XML content for autounattend.xml.
|
Optional. Full XML content for autounattend.xml. If empty, the OOBE bypass
|
||||||
In compiled winutil.ps1 this is the embedded $WinUtilAutounattendXml here-string;
|
file is skipped and a warning is logged.
|
||||||
in dev mode it is read from tools\autounattend.xml.
|
|
||||||
If empty, the OOBE bypass file is skipped and a warning is logged.
|
.PARAMETER InjectCurrentSystemDrivers
|
||||||
|
Optional. When $true, exports all drivers from the running system and injects
|
||||||
|
them into install.wim and boot.wim index 2 (Windows Setup PE).
|
||||||
|
Defaults to $false.
|
||||||
|
|
||||||
.PARAMETER Log
|
.PARAMETER Log
|
||||||
Optional ScriptBlock used for progress/status logging.
|
Optional ScriptBlock for progress/status logging. Receives a single [string] argument.
|
||||||
Receives a single [string] message argument.
|
|
||||||
Defaults to { param($m) Write-Output $m } when not supplied.
|
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Invoke-WinUtilISOScript -ScratchDir "C:\Temp\wim_mount"
|
Invoke-WinUtilISOScript -ScratchDir "C:\Temp\wim_mount"
|
||||||
@@ -62,24 +50,19 @@ function Invoke-WinUtilISOScript {
|
|||||||
.NOTES
|
.NOTES
|
||||||
Author : Chris Titus @christitustech
|
Author : Chris Titus @christitustech
|
||||||
GitHub : https://github.com/ChrisTitusTech
|
GitHub : https://github.com/ChrisTitusTech
|
||||||
Version : 26.02.22
|
Version : 26.03.02
|
||||||
#>
|
#>
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory)][string]$ScratchDir,
|
[Parameter(Mandatory)][string]$ScratchDir,
|
||||||
# Root directory of the extracted ISO contents. When supplied, autounattend.xml
|
|
||||||
# is written here so Windows Setup picks it up automatically at boot.
|
|
||||||
[string]$ISOContentsDir = "",
|
[string]$ISOContentsDir = "",
|
||||||
# Autounattend XML content. In compiled winutil.ps1 this comes from the embedded
|
|
||||||
# $WinUtilAutounattendXml here-string; in dev mode it is read from tools\autounattend.xml.
|
|
||||||
[string]$AutoUnattendXml = "",
|
[string]$AutoUnattendXml = "",
|
||||||
|
[bool]$InjectCurrentSystemDrivers = $false,
|
||||||
[scriptblock]$Log = { param($m) Write-Output $m }
|
[scriptblock]$Log = { param($m) Write-Output $m }
|
||||||
)
|
)
|
||||||
|
|
||||||
# ── Resolve admin group name (for takeown / icacls) ──────────────────────
|
|
||||||
$adminSID = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544')
|
$adminSID = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544')
|
||||||
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
|
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
|
||||||
|
|
||||||
# ── Local helpers ─────────────────────────────────────────────────────────
|
|
||||||
function Set-ISOScriptReg {
|
function Set-ISOScriptReg {
|
||||||
param ([string]$path, [string]$name, [string]$type, [string]$value)
|
param ([string]$path, [string]$name, [string]$type, [string]$value)
|
||||||
try {
|
try {
|
||||||
@@ -100,15 +83,37 @@ function Invoke-WinUtilISOScript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
function Add-DriversToImage {
|
||||||
# 1. Remove provisioned AppX packages
|
param ([string]$MountPath, [string]$DriverDir, [string]$Label = "image", [scriptblock]$Logger)
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
& dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse 2>&1 |
|
||||||
|
ForEach-Object { & $Logger " dism[$Label]: $_" }
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-BootWimInject {
|
||||||
|
param ([string]$BootWimPath, [string]$DriverDir, [scriptblock]$Logger)
|
||||||
|
Set-ItemProperty -Path $BootWimPath -Name IsReadOnly -Value $false -ErrorAction SilentlyContinue
|
||||||
|
$mountDir = Join-Path $env:TEMP "WinUtil_BootMount_$(Get-Random)"
|
||||||
|
New-Item -Path $mountDir -ItemType Directory -Force | Out-Null
|
||||||
|
try {
|
||||||
|
& $Logger "Mounting boot.wim (index 2) for driver injection..."
|
||||||
|
Mount-WindowsImage -ImagePath $BootWimPath -Index 2 -Path $mountDir -ErrorAction Stop | Out-Null
|
||||||
|
Add-DriversToImage -MountPath $mountDir -DriverDir $DriverDir -Label "boot" -Logger $Logger
|
||||||
|
& $Logger "Saving boot.wim..."
|
||||||
|
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
||||||
|
& $Logger "boot.wim driver injection complete."
|
||||||
|
} catch {
|
||||||
|
& $Logger "Warning: boot.wim driver injection failed: $_"
|
||||||
|
try { Dismount-WindowsImage -Path $mountDir -Discard -ErrorAction SilentlyContinue | Out-Null } catch {}
|
||||||
|
} finally {
|
||||||
|
Remove-Item -Path $mountDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 1. Remove provisioned AppX packages ──────────────────────────────────
|
||||||
& $Log "Removing provisioned AppX packages..."
|
& $Log "Removing provisioned AppX packages..."
|
||||||
|
|
||||||
$packages = & dism /English "/image:$ScratchDir" /Get-ProvisionedAppxPackages |
|
$packages = & dism /English "/image:$ScratchDir" /Get-ProvisionedAppxPackages |
|
||||||
ForEach-Object {
|
ForEach-Object { if ($_ -match 'PackageName : (.*)') { $matches[1] } }
|
||||||
if ($_ -match 'PackageName : (.*)') { $matches[1] }
|
|
||||||
}
|
|
||||||
|
|
||||||
$packagePrefixes = @(
|
$packagePrefixes = @(
|
||||||
'AppUp.IntelManagementandSecurityStatus',
|
'AppUp.IntelManagementandSecurityStatus',
|
||||||
@@ -155,25 +160,46 @@ function Invoke-WinUtilISOScript {
|
|||||||
'MicrosoftTeams'
|
'MicrosoftTeams'
|
||||||
)
|
)
|
||||||
|
|
||||||
$packagesToRemove = $packages | Where-Object {
|
$packages | Where-Object { $pkg = $_; $packagePrefixes | Where-Object { $pkg -like "*$_*" } } |
|
||||||
$pkg = $_
|
ForEach-Object { & dism /English "/image:$ScratchDir" /Remove-ProvisionedAppxPackage "/PackageName:$_" }
|
||||||
$packagePrefixes | Where-Object { $pkg -like "*$_*" }
|
|
||||||
|
# ── 2. Inject current system drivers (optional) ───────────────────────────
|
||||||
|
if ($InjectCurrentSystemDrivers) {
|
||||||
|
& $Log "Exporting all drivers from running system..."
|
||||||
|
$driverExportRoot = Join-Path $env:TEMP "WinUtil_DriverExport_$(Get-Random)"
|
||||||
|
New-Item -Path $driverExportRoot -ItemType Directory -Force | Out-Null
|
||||||
|
try {
|
||||||
|
Export-WindowsDriver -Online -Destination $driverExportRoot | Out-Null
|
||||||
|
|
||||||
|
& $Log "Injecting current system drivers into install.wim..."
|
||||||
|
Add-DriversToImage -MountPath $ScratchDir -DriverDir $driverExportRoot -Label "install" -Logger $Log
|
||||||
|
& $Log "install.wim driver injection complete."
|
||||||
|
|
||||||
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
|
$bootWim = Join-Path $ISOContentsDir "sources\boot.wim"
|
||||||
|
if (Test-Path $bootWim) {
|
||||||
|
& $Log "Injecting current system drivers into boot.wim..."
|
||||||
|
Invoke-BootWimInject -BootWimPath $bootWim -DriverDir $driverExportRoot -Logger $Log
|
||||||
|
} else {
|
||||||
|
& $Log "Warning: boot.wim not found — skipping boot.wim driver injection."
|
||||||
}
|
}
|
||||||
foreach ($package in $packagesToRemove) {
|
}
|
||||||
& dism /English "/image:$ScratchDir" /Remove-ProvisionedAppxPackage "/PackageName:$package"
|
} catch {
|
||||||
|
& $Log "Error during driver export/injection: $_"
|
||||||
|
} finally {
|
||||||
|
Remove-Item -Path $driverExportRoot -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
& $Log "Driver injection skipped."
|
||||||
}
|
}
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ── 3. Remove OneDrive ────────────────────────────────────────────────────
|
||||||
# 2. Remove OneDrive
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
|
||||||
& $Log "Removing OneDrive..."
|
& $Log "Removing OneDrive..."
|
||||||
& takeown /f "$ScratchDir\Windows\System32\OneDriveSetup.exe" | Out-Null
|
& takeown /f "$ScratchDir\Windows\System32\OneDriveSetup.exe" | Out-Null
|
||||||
& icacls "$ScratchDir\Windows\System32\OneDriveSetup.exe" /grant "$($adminGroup.Value):(F)" /T /C | Out-Null
|
& icacls "$ScratchDir\Windows\System32\OneDriveSetup.exe" /grant "$($adminGroup.Value):(F)" /T /C | Out-Null
|
||||||
Remove-Item -Path "$ScratchDir\Windows\System32\OneDriveSetup.exe" -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path "$ScratchDir\Windows\System32\OneDriveSetup.exe" -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ── 4. Registry tweaks ────────────────────────────────────────────────────
|
||||||
# 3. Registry tweaks
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
|
||||||
& $Log "Loading offline registry hives..."
|
& $Log "Loading offline registry hives..."
|
||||||
reg load HKLM\zCOMPONENTS "$ScratchDir\Windows\System32\config\COMPONENTS"
|
reg load HKLM\zCOMPONENTS "$ScratchDir\Windows\System32\config\COMPONENTS"
|
||||||
reg load HKLM\zDEFAULT "$ScratchDir\Windows\System32\config\default"
|
reg load HKLM\zDEFAULT "$ScratchDir\Windows\System32\config\default"
|
||||||
@@ -222,14 +248,37 @@ function Invoke-WinUtilISOScript {
|
|||||||
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' 'BypassNRO' 'REG_DWORD' '1'
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' 'BypassNRO' 'REG_DWORD' '1'
|
||||||
|
|
||||||
if ($AutoUnattendXml) {
|
if ($AutoUnattendXml) {
|
||||||
# ── Place autounattend.xml inside the WIM (Sysprep) ──────────────────
|
try {
|
||||||
$sysprepDest = "$ScratchDir\Windows\System32\Sysprep\autounattend.xml"
|
$xmlDoc = [xml]::new()
|
||||||
Set-Content -Path $sysprepDest -Value $AutoUnattendXml -Encoding UTF8 -Force
|
$xmlDoc.LoadXml($AutoUnattendXml)
|
||||||
& $Log "Written autounattend.xml to Sysprep directory."
|
|
||||||
|
$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable)
|
||||||
|
$nsMgr.AddNamespace("sg", "https://schneegans.de/windows/unattend-generator/")
|
||||||
|
|
||||||
|
$fileNodes = $xmlDoc.SelectNodes("//sg:File", $nsMgr)
|
||||||
|
if ($fileNodes -and $fileNodes.Count -gt 0) {
|
||||||
|
foreach ($fileNode in $fileNodes) {
|
||||||
|
$absPath = $fileNode.GetAttribute("path")
|
||||||
|
$relPath = $absPath -replace '^[A-Za-z]:[/\\]', ''
|
||||||
|
$destPath = Join-Path $ScratchDir $relPath
|
||||||
|
New-Item -Path (Split-Path $destPath -Parent) -ItemType Directory -Force -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
|
||||||
|
$ext = [IO.Path]::GetExtension($destPath).ToLower()
|
||||||
|
$encoding = switch ($ext) {
|
||||||
|
{ $_ -in '.ps1', '.xml' } { [System.Text.Encoding]::UTF8 }
|
||||||
|
{ $_ -in '.reg', '.vbs', '.js' } { [System.Text.UnicodeEncoding]::new($false, $true) }
|
||||||
|
default { [System.Text.Encoding]::Default }
|
||||||
|
}
|
||||||
|
[System.IO.File]::WriteAllBytes($destPath, ($encoding.GetPreamble() + $encoding.GetBytes($fileNode.InnerText.Trim())))
|
||||||
|
& $Log "Pre-staged setup script: $relPath"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
& $Log "Warning: no <Extensions><File> nodes found in autounattend.xml — setup scripts not pre-staged."
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
& $Log "Warning: could not pre-stage setup scripts from autounattend.xml: $_"
|
||||||
|
}
|
||||||
|
|
||||||
# ── Place autounattend.xml at the ISO / USB root ──────────────────────
|
|
||||||
# Windows Setup reads this file first (before booting into the OS),
|
|
||||||
# which is what drives the local-account / OOBE bypass at install time.
|
|
||||||
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
$isoDest = Join-Path $ISOContentsDir "autounattend.xml"
|
$isoDest = Join-Path $ISOContentsDir "autounattend.xml"
|
||||||
Set-Content -Path $isoDest -Value $AutoUnattendXml -Encoding UTF8 -Force
|
Set-Content -Path $isoDest -Value $AutoUnattendXml -Encoding UTF8 -Force
|
||||||
@@ -304,12 +353,9 @@ function Invoke-WinUtilISOScript {
|
|||||||
reg unload HKLM\zSOFTWARE
|
reg unload HKLM\zSOFTWARE
|
||||||
reg unload HKLM\zSYSTEM
|
reg unload HKLM\zSYSTEM
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ── 5. Delete scheduled task definition files ─────────────────────────────
|
||||||
# 4. Delete scheduled task definition files
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
|
||||||
& $Log "Deleting scheduled task definition files..."
|
& $Log "Deleting scheduled task definition files..."
|
||||||
$tasksPath = "$ScratchDir\Windows\System32\Tasks"
|
$tasksPath = "$ScratchDir\Windows\System32\Tasks"
|
||||||
|
|
||||||
Remove-Item "$tasksPath\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" -Force -ErrorAction SilentlyContinue
|
Remove-Item "$tasksPath\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" -Force -ErrorAction SilentlyContinue
|
||||||
Remove-Item "$tasksPath\Microsoft\Windows\Customer Experience Improvement Program" -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item "$tasksPath\Microsoft\Windows\Customer Experience Improvement Program" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
Remove-Item "$tasksPath\Microsoft\Windows\Application Experience\ProgramDataUpdater" -Force -ErrorAction SilentlyContinue
|
Remove-Item "$tasksPath\Microsoft\Windows\Application Experience\ProgramDataUpdater" -Force -ErrorAction SilentlyContinue
|
||||||
@@ -321,12 +367,9 @@ function Invoke-WinUtilISOScript {
|
|||||||
Remove-Item "$tasksPath\Microsoft\Windows\WaaSMedic" -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item "$tasksPath\Microsoft\Windows\WaaSMedic" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
Remove-Item "$tasksPath\Microsoft\Windows\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item "$tasksPath\Microsoft\Windows\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
Remove-Item "$tasksPath\Microsoft\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item "$tasksPath\Microsoft\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
& $Log "Scheduled task files deleted."
|
& $Log "Scheduled task files deleted."
|
||||||
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
# ── 6. Remove ISO support folder ─────────────────────────────────────────
|
||||||
# 5. Remove ISO support folder (fresh-install only; not needed)
|
|
||||||
# ═════════════════════════════════════════════════════════════════════════
|
|
||||||
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
& $Log "Removing ISO support\ folder..."
|
& $Log "Removing ISO support\ folder..."
|
||||||
Remove-Item -Path (Join-Path $ISOContentsDir "support") -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path (Join-Path $ISOContentsDir "support") -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
|||||||
268
functions/private/Invoke-WinUtilISOUSB.ps1
Normal file
268
functions/private/Invoke-WinUtilISOUSB.ps1
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
function Invoke-WinUtilISORefreshUSBDrives {
|
||||||
|
$combo = $sync["WPFWin11ISOUSBDriveComboBox"]
|
||||||
|
$removable = @(Get-Disk | Where-Object { $_.BusType -eq "USB" } | Sort-Object Number)
|
||||||
|
|
||||||
|
$combo.Items.Clear()
|
||||||
|
|
||||||
|
if ($removable.Count -eq 0) {
|
||||||
|
$combo.Items.Add("No USB drives detected")
|
||||||
|
$combo.SelectedIndex = 0
|
||||||
|
$sync["Win11ISOUSBDisks"] = @()
|
||||||
|
Write-Win11ISOLog "No USB drives detected."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($disk in $removable) {
|
||||||
|
$sizeGB = [math]::Round($disk.Size / 1GB, 1)
|
||||||
|
$combo.Items.Add("Disk $($disk.Number): $($disk.FriendlyName) [$sizeGB GB] - $($disk.PartitionStyle)")
|
||||||
|
}
|
||||||
|
$combo.SelectedIndex = 0
|
||||||
|
Write-Win11ISOLog "Found $($removable.Count) USB drive(s)."
|
||||||
|
$sync["Win11ISOUSBDisks"] = $removable
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-WinUtilISOWriteUSB {
|
||||||
|
$contentsDir = $sync["Win11ISOContentsDir"]
|
||||||
|
$usbDisks = $sync["Win11ISOUSBDisks"]
|
||||||
|
|
||||||
|
if (-not $contentsDir -or -not (Test-Path $contentsDir)) {
|
||||||
|
[System.Windows.MessageBox]::Show("No modified ISO content found. Please complete Steps 1-3 first.", "Not Ready", "OK", "Warning")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$combo = $sync["WPFWin11ISOUSBDriveComboBox"]
|
||||||
|
$selectedIndex = $combo.SelectedIndex
|
||||||
|
$selectedItemText = [string]$combo.SelectedItem
|
||||||
|
$usbDisks = @($usbDisks)
|
||||||
|
|
||||||
|
$targetDisk = $null
|
||||||
|
if ($selectedIndex -ge 0 -and $selectedIndex -lt $usbDisks.Count) {
|
||||||
|
$targetDisk = $usbDisks[$selectedIndex]
|
||||||
|
} elseif ($selectedItemText -match 'Disk\s+(\d+):') {
|
||||||
|
$selectedDiskNum = [int]$matches[1]
|
||||||
|
$targetDisk = $usbDisks | Where-Object { $_.Number -eq $selectedDiskNum } | Select-Object -First 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $targetDisk) {
|
||||||
|
[System.Windows.MessageBox]::Show("Please select a USB drive from the dropdown.", "No Drive Selected", "OK", "Warning")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$diskNum = $targetDisk.Number
|
||||||
|
$sizeGB = [math]::Round($targetDisk.Size / 1GB, 1)
|
||||||
|
|
||||||
|
$confirm = [System.Windows.MessageBox]::Show(
|
||||||
|
"ALL data on Disk $diskNum ($($targetDisk.FriendlyName), $sizeGB GB) will be PERMANENTLY ERASED.`n`nAre you sure you want to continue?",
|
||||||
|
"Confirm USB Erase", "YesNo", "Warning")
|
||||||
|
|
||||||
|
if ($confirm -ne "Yes") {
|
||||||
|
Write-Win11ISOLog "USB write cancelled by user."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $false
|
||||||
|
Write-Win11ISOLog "Starting USB write to Disk $diskNum..."
|
||||||
|
|
||||||
|
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
||||||
|
$runspace.ApartmentState = "STA"
|
||||||
|
$runspace.ThreadOptions = "ReuseThread"
|
||||||
|
$runspace.Open()
|
||||||
|
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("diskNum", $diskNum)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("contentsDir", $contentsDir)
|
||||||
|
|
||||||
|
$script = [Management.Automation.PowerShell]::Create()
|
||||||
|
$script.Runspace = $runspace
|
||||||
|
$script.AddScript({
|
||||||
|
|
||||||
|
function Log($msg) {
|
||||||
|
$ts = (Get-Date).ToString("HH:mm:ss")
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg"
|
||||||
|
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
||||||
|
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetProgress($label, $pct) {
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync.progressBarTextBlock.Text = $label
|
||||||
|
$sync.progressBarTextBlock.ToolTip = $label
|
||||||
|
$sync.ProgressBar.Value = [Math]::Max($pct, 5)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-FreeDriveLetter {
|
||||||
|
$used = (Get-PSDrive -PSProvider FileSystem -ErrorAction SilentlyContinue).Name
|
||||||
|
foreach ($c in [char[]](68..90)) {
|
||||||
|
if ($used -notcontains [string]$c) { return $c }
|
||||||
|
}
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SetProgress "Formatting USB drive..." 10
|
||||||
|
|
||||||
|
# Phase 1: Clean disk via diskpart (retry once if the drive is not yet ready)
|
||||||
|
$dpFile1 = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt"
|
||||||
|
"select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1 -Encoding ASCII
|
||||||
|
Log "Running diskpart clean on Disk $diskNum..."
|
||||||
|
$dpCleanOut = diskpart /s $dpFile1 2>&1
|
||||||
|
$dpCleanOut | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" }
|
||||||
|
Remove-Item $dpFile1 -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
if (($dpCleanOut -join ' ') -match 'device is not ready') {
|
||||||
|
Log "Disk $diskNum was not ready; waiting 5 seconds and retrying clean..."
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
|
||||||
|
$dpFile1b = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt"
|
||||||
|
"select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1b -Encoding ASCII
|
||||||
|
diskpart /s $dpFile1b 2>&1 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" }
|
||||||
|
Remove-Item $dpFile1b -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
# Phase 2: Initialize as GPT
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
|
||||||
|
$diskObj = Get-Disk -Number $diskNum -ErrorAction Stop
|
||||||
|
if ($diskObj.PartitionStyle -eq 'RAW') {
|
||||||
|
Initialize-Disk -Number $diskNum -PartitionStyle GPT -ErrorAction Stop
|
||||||
|
Log "Disk $diskNum initialized as GPT."
|
||||||
|
} else {
|
||||||
|
Set-Disk -Number $diskNum -PartitionStyle GPT -ErrorAction Stop
|
||||||
|
Log "Disk $diskNum converted to GPT (was $($diskObj.PartitionStyle))."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Phase 3: Create FAT32 partition via diskpart, then format with Format-Volume
|
||||||
|
# (diskpart's 'format' command can fail with "no volume selected" on fresh/never-formatted drives)
|
||||||
|
$volLabel = "W11-" + (Get-Date).ToString('yyMMdd')
|
||||||
|
$dpFile2 = Join-Path $env:TEMP "winutil_diskpart2_$(Get-Random).txt"
|
||||||
|
$maxFat32PartitionMB = 32768
|
||||||
|
$diskSizeMB = [int][Math]::Floor((Get-Disk -Number $diskNum -ErrorAction Stop).Size / 1MB)
|
||||||
|
$createPartitionCommand = "create partition primary"
|
||||||
|
if ($diskSizeMB -gt $maxFat32PartitionMB) {
|
||||||
|
$createPartitionCommand = "create partition primary size=$maxFat32PartitionMB"
|
||||||
|
Log "Disk $diskNum is $diskSizeMB MB; creating FAT32 partition capped at $maxFat32PartitionMB MB (32 GB)."
|
||||||
|
}
|
||||||
|
|
||||||
|
@(
|
||||||
|
"select disk $diskNum"
|
||||||
|
$createPartitionCommand
|
||||||
|
"exit"
|
||||||
|
) | Set-Content -Path $dpFile2 -Encoding ASCII
|
||||||
|
Log "Creating partitions on Disk $diskNum..."
|
||||||
|
diskpart /s $dpFile2 2>&1 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" }
|
||||||
|
Remove-Item $dpFile2 -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
SetProgress "Formatting USB partition..." 25
|
||||||
|
Start-Sleep -Seconds 3
|
||||||
|
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
$partitions = Get-Partition -DiskNumber $diskNum -ErrorAction Stop
|
||||||
|
Log "Partitions on Disk $diskNum after creation: $($partitions.Count)"
|
||||||
|
foreach ($p in $partitions) {
|
||||||
|
Log " Partition $($p.PartitionNumber) Type=$($p.Type) Letter=$($p.DriveLetter) Size=$([math]::Round($p.Size/1MB))MB"
|
||||||
|
}
|
||||||
|
|
||||||
|
$winpePart = $partitions | Where-Object { $_.Type -eq "Basic" } | Select-Object -Last 1
|
||||||
|
if (-not $winpePart) {
|
||||||
|
throw "Could not find the Basic partition on Disk $diskNum after creation."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Format using Format-Volume (reliable on fresh drives; diskpart format fails
|
||||||
|
# with 'no volume selected' when the partition has never been formatted before)
|
||||||
|
Log "Formatting Partition $($winpePart.PartitionNumber) as FAT32 (label: $volLabel)..."
|
||||||
|
Get-Partition -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber |
|
||||||
|
Format-Volume -FileSystem FAT32 -NewFileSystemLabel $volLabel -Force -Confirm:$false | Out-Null
|
||||||
|
Log "Partition $($winpePart.PartitionNumber) formatted as FAT32."
|
||||||
|
|
||||||
|
SetProgress "Assigning drive letters..." 30
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" -ErrorAction SilentlyContinue } catch {}
|
||||||
|
$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
|
||||||
|
Log "Assigned drive letter $usbLetter to WINPE partition (Partition $($winpePart.PartitionNumber))."
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
|
||||||
|
$usbDrive = "${usbLetter}:"
|
||||||
|
$retries = 0
|
||||||
|
while (-not (Test-Path $usbDrive) -and $retries -lt 6) {
|
||||||
|
$retries++
|
||||||
|
Log "Waiting for $usbDrive to become accessible (attempt $retries/6)..."
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
}
|
||||||
|
if (-not (Test-Path $usbDrive)) { throw "Drive $usbDrive is not accessible after letter assignment." }
|
||||||
|
Log "USB data partition: $usbDrive"
|
||||||
|
|
||||||
|
$contentSizeBytes = (Get-ChildItem -LiteralPath $contentsDir -File -Recurse -Force -ErrorAction Stop | Measure-Object -Property Length -Sum).Sum
|
||||||
|
if (-not $contentSizeBytes) { $contentSizeBytes = 0 }
|
||||||
|
$usbVolume = Get-Volume -DriveLetter $usbLetter -ErrorAction Stop
|
||||||
|
$partitionCapacityBytes = [int64]$usbVolume.Size
|
||||||
|
$partitionFreeBytes = [int64]$usbVolume.SizeRemaining
|
||||||
|
|
||||||
|
$contentSizeGB = [math]::Round($contentSizeBytes / 1GB, 2)
|
||||||
|
$partitionCapacityGB = [math]::Round($partitionCapacityBytes / 1GB, 2)
|
||||||
|
$partitionFreeGB = [math]::Round($partitionFreeBytes / 1GB, 2)
|
||||||
|
|
||||||
|
Log "Source content size: $contentSizeGB GB. USB partition capacity: $partitionCapacityGB GB, free: $partitionFreeGB GB."
|
||||||
|
|
||||||
|
if ($contentSizeBytes -gt $partitionCapacityBytes) {
|
||||||
|
throw "ISO content ($contentSizeGB GB) is larger than the USB partition capacity ($partitionCapacityGB GB). Use a larger USB drive or reduce image size."
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($contentSizeBytes -gt $partitionFreeBytes) {
|
||||||
|
throw "Insufficient free space on USB partition. Required: $contentSizeGB GB, available: $partitionFreeGB GB."
|
||||||
|
}
|
||||||
|
|
||||||
|
SetProgress "Copying Windows 11 files to USB..." 45
|
||||||
|
|
||||||
|
# Copy files; split install.wim if > 4 GB (FAT32 limit)
|
||||||
|
$installWim = Join-Path $contentsDir "sources\install.wim"
|
||||||
|
if (Test-Path $installWim) {
|
||||||
|
$wimSizeMB = [math]::Round((Get-Item $installWim).Length / 1MB)
|
||||||
|
if ($wimSizeMB -gt 3800) {
|
||||||
|
Log "install.wim is $wimSizeMB MB - splitting for FAT32 compatibility... This will take several minutes."
|
||||||
|
$splitDest = Join-Path $usbDrive "sources\install.swm"
|
||||||
|
New-Item -ItemType Directory -Path (Split-Path $splitDest) -Force | Out-Null
|
||||||
|
Split-WindowsImage -ImagePath $installWim -SplitImagePath $splitDest -FileSize 3800 -CheckIntegrity
|
||||||
|
Log "install.wim split complete."
|
||||||
|
Log "Copying remaining files to USB..."
|
||||||
|
& robocopy $contentsDir $usbDrive /E /XF install.wim /NFL /NDL /NJH /NJS
|
||||||
|
} else {
|
||||||
|
& robocopy $contentsDir $usbDrive /E /NFL /NDL /NJH /NJS
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
& robocopy $contentsDir $usbDrive /E /NFL /NDL /NJH /NJS
|
||||||
|
}
|
||||||
|
|
||||||
|
SetProgress "Finalising USB drive..." 90
|
||||||
|
Log "Files copied to USB."
|
||||||
|
SetProgress "USB write complete" 100
|
||||||
|
Log "USB drive is ready for use."
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"USB drive created successfully!`n`nYou can now boot from this drive to install Windows 11.",
|
||||||
|
"USB Ready", "OK", "Info")
|
||||||
|
})
|
||||||
|
} catch {
|
||||||
|
Log "ERROR during USB write: $_"
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
[System.Windows.MessageBox]::Show("USB write failed:`n`n$_", "USB Write Error", "OK", "Error")
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
Start-Sleep -Milliseconds 800
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync.progressBarTextBlock.Text = ""
|
||||||
|
$sync.progressBarTextBlock.ToolTip = ""
|
||||||
|
$sync.ProgressBar.Value = 0
|
||||||
|
$sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}) | Out-Null
|
||||||
|
|
||||||
|
$script.BeginInvoke() | Out-Null
|
||||||
|
}
|
||||||
@@ -59,17 +59,19 @@ function Reset-WPFCheckBoxes {
|
|||||||
$sync.selectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
|
$sync.selectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
|
||||||
|
|
||||||
if($doToggles) {
|
if($doToggles) {
|
||||||
# Restore toggle switch states
|
# Restore toggle switch states from imported config.
|
||||||
|
# Only act on toggles that are explicitly listed in the import — toggles absent
|
||||||
|
# from the export file were not part of the saved config and should keep whatever
|
||||||
|
# state the live system already has (set during UI initialisation via Get-WinUtilToggleStatus).
|
||||||
$importedToggles = $sync.selectedToggles
|
$importedToggles = $sync.selectedToggles
|
||||||
$allToggles = $sync.GetEnumerator() | Where-Object { $_.Key -like "WPFToggle*" -and $_.Value -is [System.Windows.Controls.CheckBox] }
|
$allToggles = $sync.GetEnumerator() | Where-Object { $_.Key -like "WPFToggle*" -and $_.Value -is [System.Windows.Controls.CheckBox] }
|
||||||
foreach ($toggle in $allToggles) {
|
foreach ($toggle in $allToggles) {
|
||||||
if ($importedToggles -contains $toggle.Key) {
|
if ($importedToggles -contains $toggle.Key) {
|
||||||
$sync[$toggle.Key].IsChecked = $true
|
$sync[$toggle.Key].IsChecked = $true
|
||||||
Write-Debug "Restoring toggle: $($toggle.Key) = checked"
|
Write-Debug "Restoring toggle: $($toggle.Key) = checked"
|
||||||
} else {
|
|
||||||
$sync[$toggle.Key].IsChecked = $false
|
|
||||||
Write-Debug "Restoring toggle: $($toggle.Key) = unchecked"
|
|
||||||
}
|
}
|
||||||
|
# Toggles not present in the import are intentionally left untouched;
|
||||||
|
# their current UI state already reflects the real system state.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
function Test-WinUtilInternetConnection {
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Tests if the computer has internet connectivity
|
|
||||||
.OUTPUTS
|
|
||||||
Boolean - True if connected, False if offline
|
|
||||||
#>
|
|
||||||
try {
|
|
||||||
# Test multiple reliable endpoints
|
|
||||||
$testSites = @(
|
|
||||||
"8.8.8.8", # Google DNS
|
|
||||||
"1.1.1.1", # Cloudflare DNS
|
|
||||||
"208.67.222.222" # OpenDNS
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($site in $testSites) {
|
|
||||||
if (Test-Connection -ComputerName $site -Count 1 -Quiet -ErrorAction SilentlyContinue) {
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@ function Invoke-WPFFixesWinget {
|
|||||||
try {
|
try {
|
||||||
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||||
Write-Host "==> Starting Winget Repair"
|
Write-Host "==> Starting Winget Repair"
|
||||||
Install-WinUtilWinget -Force
|
Install-WinUtilWinget
|
||||||
} catch {
|
} catch {
|
||||||
Write-Error "Failed to install winget: $_"
|
Write-Error "Failed to install winget: $_"
|
||||||
Set-WinUtilTaskbaritem -state "Error" -overlay "warning"
|
Set-WinUtilTaskbaritem -state "Error" -overlay "warning"
|
||||||
|
|||||||
@@ -94,7 +94,14 @@ function Invoke-WPFImpex {
|
|||||||
Update-WinUtilSelections -flatJson $flattenedJson
|
Update-WinUtilSelections -flatJson $flattenedJson
|
||||||
|
|
||||||
if (!$PARAM_NOUI) {
|
if (!$PARAM_NOUI) {
|
||||||
|
# Set flag so toggle Checked/Unchecked events don't trigger registry writes
|
||||||
|
# while we're programmatically restoring UI state from the imported config
|
||||||
|
$sync.ImportInProgress = $true
|
||||||
|
try {
|
||||||
Reset-WPFCheckBoxes -doToggles $true
|
Reset-WPFCheckBoxes -doToggles $true
|
||||||
|
} finally {
|
||||||
|
$sync.ImportInProgress = $false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -193,13 +193,19 @@ function Invoke-WPFUIElements {
|
|||||||
$sync[$entryInfo.Name].Add_Checked({
|
$sync[$entryInfo.Name].Add_Checked({
|
||||||
[System.Object]$Sender = $args[0]
|
[System.Object]$Sender = $args[0]
|
||||||
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
|
Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name
|
||||||
|
# Skip applying tweaks while an import is restoring toggle states
|
||||||
|
if (-not $sync.ImportInProgress) {
|
||||||
Invoke-WinUtilTweaks $Sender.name
|
Invoke-WinUtilTweaks $Sender.name
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$sync[$entryInfo.Name].Add_Unchecked({
|
$sync[$entryInfo.Name].Add_Unchecked({
|
||||||
[System.Object]$Sender = $args[0]
|
[System.Object]$Sender = $args[0]
|
||||||
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name
|
Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name
|
||||||
|
# Skip undoing tweaks while an import is restoring toggle states
|
||||||
|
if (-not $sync.ImportInProgress) {
|
||||||
Invoke-WinUtiltweaks $Sender.name -undo $true
|
Invoke-WinUtiltweaks $Sender.name -undo $true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,14 @@ function Invoke-WPFtweaksbutton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$Tweaks = $sync.selectedTweaks
|
$Tweaks = $sync.selectedTweaks
|
||||||
|
$dnsProvider = $sync["WPFchangedns"].text
|
||||||
|
$restorePointTweak = "WPFTweaksRestorePoint"
|
||||||
|
$restorePointSelected = $Tweaks -contains $restorePointTweak
|
||||||
|
$tweaksToRun = @($Tweaks | Where-Object { $_ -ne $restorePointTweak })
|
||||||
|
$totalSteps = [Math]::Max($Tweaks.Count, 1)
|
||||||
|
$completedSteps = 0
|
||||||
|
|
||||||
Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text
|
if ($tweaks.count -eq 0 -and $dnsProvider -eq "Default") {
|
||||||
|
|
||||||
if ($tweaks.count -eq 0 -and $sync["WPFchangedns"].text -eq "Default") {
|
|
||||||
$msg = "Please check the tweaks you wish to perform."
|
$msg = "Please check the tweaks you wish to perform."
|
||||||
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
@@ -24,24 +28,53 @@ function Invoke-WPFtweaksbutton {
|
|||||||
|
|
||||||
Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
|
Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
|
||||||
|
|
||||||
|
if ($restorePointSelected) {
|
||||||
|
$sync.ProcessRunning = $true
|
||||||
|
|
||||||
|
if ($Tweaks.Count -eq 1) {
|
||||||
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
|
} else {
|
||||||
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-WinUtilProgressBar -Label "Creating restore point" -Percent 0
|
||||||
|
Invoke-WinUtilTweaks $restorePointTweak
|
||||||
|
$completedSteps = 1
|
||||||
|
|
||||||
|
if ($tweaksToRun.Count -eq 0 -and $dnsProvider -eq "Default") {
|
||||||
|
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
|
||||||
|
$sync.ProcessRunning = $false
|
||||||
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
|
Write-Host "================================="
|
||||||
|
Write-Host "-- Tweaks are Finished ---"
|
||||||
|
Write-Host "================================="
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# 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
|
# 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",$tweaks)) -ScriptBlock {
|
$handle = Invoke-WPFRunspace -ParameterList @(("tweaks", $tweaksToRun), ("dnsProvider", $dnsProvider), ("completedSteps", $completedSteps), ("totalSteps", $totalSteps)) -ScriptBlock {
|
||||||
param($tweaks)
|
param($tweaks, $dnsProvider, $completedSteps, $totalSteps)
|
||||||
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
|
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
|
||||||
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
|
|
||||||
|
if ($completedSteps -eq 0) {
|
||||||
if ($Tweaks.count -eq 1) {
|
if ($Tweaks.count -eq 1) {
|
||||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
Invoke-WPFUIThread -ScriptBlock{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
Invoke-WPFUIThread -ScriptBlock{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
# Execute other selected tweaks
|
}
|
||||||
|
|
||||||
for ($i = 0; $i -lt $Tweaks.Count; $i++) {
|
Set-WinUtilDNS -DNSProvider $dnsProvider
|
||||||
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100)
|
|
||||||
|
for ($i = 0; $i -lt $tweaks.Count; $i++) {
|
||||||
|
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($completedSteps / $totalSteps * 100)
|
||||||
Invoke-WinUtilTweaks $tweaks[$i]
|
Invoke-WinUtilTweaks $tweaks[$i]
|
||||||
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) }
|
$completedSteps++
|
||||||
|
$progress = $completedSteps / $totalSteps
|
||||||
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value $progress }
|
||||||
}
|
}
|
||||||
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
|
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
@@ -49,11 +82,5 @@ function Invoke-WPFtweaksbutton {
|
|||||||
Write-Host "================================="
|
Write-Host "================================="
|
||||||
Write-Host "-- Tweaks are Finished ---"
|
Write-Host "-- Tweaks are Finished ---"
|
||||||
Write-Host "================================="
|
Write-Host "================================="
|
||||||
|
|
||||||
# $ButtonType = [System.Windows.MessageBoxButton]::OK
|
|
||||||
# $MessageboxTitle = "Tweaks are Finished "
|
|
||||||
# $Messageboxbody = ("Done")
|
|
||||||
# $MessageIcon = [System.Windows.MessageBoxImage]::Information
|
|
||||||
# [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,14 @@ $maxthreads = [int]$env:NUMBER_OF_PROCESSORS
|
|||||||
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null
|
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null
|
||||||
$debugVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'DebugPreference',$DebugPreference,$Null
|
$debugVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'DebugPreference',$DebugPreference,$Null
|
||||||
$uiVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_NOUI',$PARAM_NOUI,$Null
|
$uiVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_NOUI',$PARAM_NOUI,$Null
|
||||||
|
$offlineVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_OFFLINE',$PARAM_OFFLINE,$Null
|
||||||
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
|
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
|
||||||
|
|
||||||
# Add the variable to the session state
|
# Add the variable to the session state
|
||||||
$InitialSessionState.Variables.Add($hashVars)
|
$InitialSessionState.Variables.Add($hashVars)
|
||||||
$InitialSessionState.Variables.Add($debugVar)
|
$InitialSessionState.Variables.Add($debugVar)
|
||||||
$InitialSessionState.Variables.Add($uiVar)
|
$InitialSessionState.Variables.Add($uiVar)
|
||||||
|
$InitialSessionState.Variables.Add($offlineVar)
|
||||||
|
|
||||||
# Get every private function and add them to the session state
|
# Get every private function and add them to the session state
|
||||||
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' }
|
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' }
|
||||||
@@ -350,11 +352,10 @@ $sync["Form"].Add_ContentRendered({
|
|||||||
Write-Debug "Unable to retrieve information about the primary monitor."
|
Write-Debug "Unable to retrieve information about the primary monitor."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check internet connectivity and disable install tab if offline
|
if ($PARAM_OFFLINE) {
|
||||||
#$isOnline = Test-WinUtilInternetConnection
|
# Show offline banner
|
||||||
$isOnline = $true # Temporarily force online mode until we can resolve false negatives
|
$sync.WPFOfflineBanner.Visibility = [System.Windows.Visibility]::Visible
|
||||||
|
|
||||||
if (-not $isOnline) {
|
|
||||||
# Disable the install tab
|
# Disable the install tab
|
||||||
$sync.WPFTab1BT.IsEnabled = $false
|
$sync.WPFTab1BT.IsEnabled = $false
|
||||||
$sync.WPFTab1BT.Opacity = 0.5
|
$sync.WPFTab1BT.Opacity = 0.5
|
||||||
@@ -486,7 +487,7 @@ $sync["AboutMenuItem"].Add_Click({
|
|||||||
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
|
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
|
||||||
|
|
||||||
$authorInfo = @"
|
$authorInfo = @"
|
||||||
Author : <a href="https://github.com/ChrisTitusTech">@christitustech</a>
|
Author : <a href="https://github.com/ChrisTitusTech">@ChrisTitusTech</a>
|
||||||
UI : <a href="https://github.com/MyDrift-user">@MyDrift-user</a>, <a href="https://github.com/Marterich">@Marterich</a>
|
UI : <a href="https://github.com/MyDrift-user">@MyDrift-user</a>, <a href="https://github.com/Marterich">@Marterich</a>
|
||||||
Runspace : <a href="https://github.com/DeveloperDurp">@DeveloperDurp</a>, <a href="https://github.com/Marterich">@Marterich</a>
|
Runspace : <a href="https://github.com/DeveloperDurp">@DeveloperDurp</a>, <a href="https://github.com/Marterich">@Marterich</a>
|
||||||
GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a>
|
GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a>
|
||||||
@@ -494,6 +495,11 @@ Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sy
|
|||||||
"@
|
"@
|
||||||
Show-CustomDialog -Title "About" -Message $authorInfo
|
Show-CustomDialog -Title "About" -Message $authorInfo
|
||||||
})
|
})
|
||||||
|
$sync["DocumentationMenuItem"].Add_Click({
|
||||||
|
Write-Debug "Documentation clicked"
|
||||||
|
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
|
||||||
|
Start-Process "https://winutil.christitus.com/"
|
||||||
|
})
|
||||||
$sync["SponsorMenuItem"].Add_Click({
|
$sync["SponsorMenuItem"].Add_Click({
|
||||||
Write-Debug "Sponsors clicked"
|
Write-Debug "Sponsors clicked"
|
||||||
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
|
Invoke-WPFPopup -Action "Hide" -Popups @("Settings")
|
||||||
@@ -540,6 +546,10 @@ $sync["FontScalingApplyButton"].Add_Click({
|
|||||||
|
|
||||||
# ── Win11ISO Tab button handlers ──────────────────────────────────────────────
|
# ── Win11ISO Tab button handlers ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
$sync["WPFTab5BT"].Add_Click({
|
||||||
|
$sync["Form"].Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null
|
||||||
|
})
|
||||||
|
|
||||||
$sync["WPFWin11ISOBrowseButton"].Add_Click({
|
$sync["WPFWin11ISOBrowseButton"].Add_Click({
|
||||||
Write-Debug "WPFWin11ISOBrowseButton clicked"
|
Write-Debug "WPFWin11ISOBrowseButton clicked"
|
||||||
Invoke-WinUtilISOBrowse
|
Invoke-WinUtilISOBrowse
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
param (
|
param (
|
||||||
[string]$Config,
|
[string]$Config,
|
||||||
[switch]$Run,
|
[switch]$Run,
|
||||||
[switch]$Noui
|
[switch]$Noui,
|
||||||
|
[switch]$Offline
|
||||||
)
|
)
|
||||||
|
|
||||||
if ($Config) {
|
if ($Config) {
|
||||||
@@ -27,25 +28,10 @@ if ($Noui) {
|
|||||||
$PARAM_NOUI = $true
|
$PARAM_NOUI = $true
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load DLLs
|
$PARAM_OFFLINE = $false
|
||||||
Add-Type -AssemblyName PresentationFramework
|
if ($Offline) {
|
||||||
Add-Type -AssemblyName System.Windows.Forms
|
$PARAM_OFFLINE = $true
|
||||||
|
}
|
||||||
# Variable to sync between runspaces
|
|
||||||
$sync = [Hashtable]::Synchronized(@{})
|
|
||||||
$sync.PSScriptRoot = $PSScriptRoot
|
|
||||||
$sync.version = "#{replaceme}"
|
|
||||||
$sync.configs = @{}
|
|
||||||
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
|
|
||||||
$sync.preferences = @{}
|
|
||||||
$sync.ProcessRunning = $false
|
|
||||||
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
|
|
||||||
$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
|
|
||||||
|
|
||||||
|
|
||||||
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||||
@@ -80,6 +66,26 @@ if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]:
|
|||||||
break
|
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()
|
||||||
|
$sync.preferences = @{}
|
||||||
|
$sync.ProcessRunning = $false
|
||||||
|
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
|
||||||
|
$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"
|
$dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
|
||||||
|
|
||||||
# Set the path for the winutil directory
|
# Set the path for the winutil directory
|
||||||
|
|||||||
@@ -5,10 +5,6 @@
|
|||||||
<settings pass="windowsPE">
|
<settings pass="windowsPE">
|
||||||
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
<UserData>
|
<UserData>
|
||||||
<ProductKey>
|
|
||||||
<Key>00000-00000-00000-00000-00000</Key>
|
|
||||||
<WillShowUI>Always</WillShowUI>
|
|
||||||
</ProductKey>
|
|
||||||
<AcceptEula>true</AcceptEula>
|
<AcceptEula>true</AcceptEula>
|
||||||
</UserData>
|
</UserData>
|
||||||
<UseConfigurationSet>false</UseConfigurationSet>
|
<UseConfigurationSet>false</UseConfigurationSet>
|
||||||
@@ -337,27 +333,7 @@ $scripts = @(
|
|||||||
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackDocs /t REG_DWORD /d 0 /f;
|
reg.exe add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v Start_TrackDocs /t REG_DWORD /d 0 /f;
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
Add-Type -TypeDefinition @"
|
Restart-Computer -Force;
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
public class Win32Broadcast {
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
|
||||||
public static extern IntPtr SendMessageTimeout(
|
|
||||||
IntPtr hWnd,
|
|
||||||
uint Msg,
|
|
||||||
IntPtr wParam,
|
|
||||||
string lParam,
|
|
||||||
uint fuFlags,
|
|
||||||
uint uTimeout,
|
|
||||||
out IntPtr lpdwResult);
|
|
||||||
}
|
|
||||||
"@;
|
|
||||||
[Win32Broadcast]::SendMessageTimeout( [IntPtr]0xffff, 0x1A, [IntPtr]::Zero, 'ImmersiveColorSet', 0x2, 100, [ref]([IntPtr]::Zero) );
|
|
||||||
};
|
|
||||||
{
|
|
||||||
Get-Process -Name 'explorer' -ErrorAction 'SilentlyContinue' | Where-Object -FilterScript {
|
|
||||||
$_.SessionId -eq ( Get-Process -Id $PID ).SessionId;
|
|
||||||
} | Stop-Process -Force;
|
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -438,15 +414,13 @@ $scripts = @(
|
|||||||
</File>
|
</File>
|
||||||
<File path="C:\Windows\Setup\Scripts\FirstLogon.ps1">
|
<File path="C:\Windows\Setup\Scripts\FirstLogon.ps1">
|
||||||
$scripts = @(
|
$scripts = @(
|
||||||
{
|
|
||||||
cmd.exe /c "rmdir C:\Windows.old";
|
|
||||||
};
|
|
||||||
{
|
{
|
||||||
Remove-Item -LiteralPath @(
|
Remove-Item -LiteralPath @(
|
||||||
'C:\Windows\Panther\unattend.xml';
|
'C:\Windows\Panther\unattend.xml';
|
||||||
'C:\Windows\Panther\unattend-original.xml';
|
'C:\Windows\Panther\unattend-original.xml';
|
||||||
'C:\Windows\Setup\Scripts\Wifi.xml';
|
'C:\Windows\Setup\Scripts\Wifi.xml';
|
||||||
) -Force -ErrorAction 'SilentlyContinue' -Verbose;
|
'C:\Windows.old';
|
||||||
|
) -Recurse -Force -ErrorAction 'SilentlyContinue';
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
reg.exe delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /v NoAutoUpdate /f;
|
reg.exe delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" /v NoAutoUpdate /f;
|
||||||
@@ -461,6 +435,14 @@ $scripts = @(
|
|||||||
reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\UsoSvc" /v Start /t REG_DWORD /d 2 /f;
|
reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\UsoSvc" /v Start /t REG_DWORD /d 2 /f;
|
||||||
reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc" /v Start /t REG_DWORD /d 3 /f;
|
reg.exe add "HKLM\SYSTEM\CurrentControlSet\Services\WaaSMedicSvc" /v Start /t REG_DWORD /d 3 /f;
|
||||||
};
|
};
|
||||||
|
{
|
||||||
|
reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Education" /f;
|
||||||
|
reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /f;
|
||||||
|
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /f;
|
||||||
|
reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Education" /v IsEducationEnvironment /t REG_DWORD /d 1 /f;
|
||||||
|
reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" /v HideRecommendedSection /t REG_DWORD /d 1 /f;
|
||||||
|
reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v HideRecommendedSection /t REG_DWORD /d 1 /f;
|
||||||
|
};
|
||||||
{
|
{
|
||||||
$recallFeature = Get-WindowsOptionalFeature -Online -ErrorAction SilentlyContinue | Where-Object { $_.State -eq 'Enabled' -and $_.FeatureName -like 'Recall' };
|
$recallFeature = Get-WindowsOptionalFeature -Online -ErrorAction SilentlyContinue | Where-Object { $_.State -eq 'Enabled' -and $_.FeatureName -like 'Recall' };
|
||||||
if( $recallFeature ) {
|
if( $recallFeature ) {
|
||||||
@@ -468,7 +450,6 @@ $scripts = @(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
$viveDir = Join-Path $env:TEMP 'ViVeTool';
|
$viveDir = Join-Path $env:TEMP 'ViVeTool';
|
||||||
$viveZip = Join-Path $env:TEMP 'ViVeTool.zip';
|
$viveZip = Join-Path $env:TEMP 'ViVeTool.zip';
|
||||||
Invoke-WebRequest 'https://github.com/thebookisclosed/ViVe/releases/download/v0.3.4/ViVeTool-v0.3.4-IntelAmd.zip' -OutFile $viveZip;
|
Invoke-WebRequest 'https://github.com/thebookisclosed/ViVe/releases/download/v0.3.4/ViVeTool-v0.3.4-IntelAmd.zip' -OutFile $viveZip;
|
||||||
@@ -476,7 +457,6 @@ $scripts = @(
|
|||||||
Remove-Item -Path $viveZip -Force;
|
Remove-Item -Path $viveZip -Force;
|
||||||
Start-Process -FilePath (Join-Path $viveDir 'ViVeTool.exe') -ArgumentList '/disable /id:47205210' -Wait -NoNewWindow;
|
Start-Process -FilePath (Join-Path $viveDir 'ViVeTool.exe') -ArgumentList '/disable /id:47205210' -Wait -NoNewWindow;
|
||||||
Remove-Item -Path $viveDir -Recurse -Force;
|
Remove-Item -Path $viveDir -Recurse -Force;
|
||||||
} catch {}
|
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
if( (Get-BitLockerVolume -MountPoint $Env:SystemDrive).ProtectionStatus -eq 'On' ) {
|
if( (Get-BitLockerVolume -MountPoint $Env:SystemDrive).ProtectionStatus -eq 'On' ) {
|
||||||
|
|||||||
@@ -273,22 +273,43 @@
|
|||||||
<Style TargetType="ComboBox">
|
<Style TargetType="ComboBox">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource ComboBoxForegroundColor}" />
|
<Setter Property="Foreground" Value="{DynamicResource ComboBoxForegroundColor}" />
|
||||||
<Setter Property="Background" Value="{DynamicResource ComboBoxBackgroundColor}" />
|
<Setter Property="Background" Value="{DynamicResource ComboBoxBackgroundColor}" />
|
||||||
|
<Setter Property="MinWidth" Value="{DynamicResource ButtonWidth}" />
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="ComboBox">
|
<ControlTemplate TargetType="ComboBox">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
<Border x:Name="OuterBorder"
|
||||||
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="{DynamicResource ButtonCornerRadius}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
<ToggleButton x:Name="ToggleButton"
|
<ToggleButton x:Name="ToggleButton"
|
||||||
Background="{TemplateBinding Background}"
|
Background="Transparent"
|
||||||
BorderBrush="{TemplateBinding Background}"
|
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
|
||||||
ClickMode="Press">
|
ClickMode="Press">
|
||||||
<TextBlock Text="{TemplateBinding SelectionBoxItem}"
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Grid.Column="0"
|
||||||
|
Text="{TemplateBinding SelectionBoxItem}"
|
||||||
Foreground="{TemplateBinding Foreground}"
|
Foreground="{TemplateBinding Foreground}"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2"
|
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||||
/>
|
Margin="6,3,2,3"/>
|
||||||
|
<Path Grid.Column="1"
|
||||||
|
Data="M 0,0 L 8,0 L 4,5 Z"
|
||||||
|
Fill="{TemplateBinding Foreground}"
|
||||||
|
Width="8" Height="5"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Stretch="Uniform"
|
||||||
|
Margin="4,0,6,0"/>
|
||||||
|
</Grid>
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
|
</Border>
|
||||||
<Popup x:Name="Popup"
|
<Popup x:Name="Popup"
|
||||||
IsOpen="{TemplateBinding IsDropDownOpen}"
|
IsOpen="{TemplateBinding IsDropDownOpen}"
|
||||||
Placement="Bottom"
|
Placement="Bottom"
|
||||||
@@ -297,11 +318,11 @@
|
|||||||
PopupAnimation="Slide">
|
PopupAnimation="Slide">
|
||||||
<Border x:Name="DropDownBorder"
|
<Border x:Name="DropDownBorder"
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
BorderBrush="{TemplateBinding Foreground}"
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="4">
|
CornerRadius="4">
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
<ItemsPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2"/>
|
<ItemsPresenter HorizontalAlignment="Left" VerticalAlignment="Center" Margin="4,2"/>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Border>
|
</Border>
|
||||||
</Popup>
|
</Popup>
|
||||||
@@ -922,13 +943,19 @@
|
|||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
<Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Name="WPFMainGrid" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
|
<Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Name="WPFMainGrid" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid Grid.Row="0" Background="{DynamicResource MainBackgroundColor}">
|
<!-- Offline banner -->
|
||||||
|
<Border Name="WPFOfflineBanner" Grid.Row="0" Background="#8B0000" Visibility="Collapsed" Padding="6,4">
|
||||||
|
<TextBlock Text="⚠ Offline Mode - No Internet Connection" Foreground="White" FontWeight="Bold"
|
||||||
|
HorizontalAlignment="Center" FontSize="13" Background="Transparent"/>
|
||||||
|
</Border>
|
||||||
|
<Grid Grid.Row="1" Background="{DynamicResource MainBackgroundColor}">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/> <!-- Navigation buttons -->
|
<ColumnDefinition Width="Auto"/> <!-- Navigation buttons -->
|
||||||
<ColumnDefinition Width="*"/> <!-- Search bar and buttons -->
|
<ColumnDefinition Width="*"/> <!-- Search bar and buttons -->
|
||||||
@@ -1153,6 +1180,7 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<Separator/>
|
<Separator/>
|
||||||
<MenuItem FontSize="{DynamicResource ButtonFontSize}" Header="About" Name="AboutMenuItem" Foreground="{DynamicResource MainForegroundColor}"/>
|
<MenuItem FontSize="{DynamicResource ButtonFontSize}" Header="About" Name="AboutMenuItem" Foreground="{DynamicResource MainForegroundColor}"/>
|
||||||
|
<MenuItem FontSize="{DynamicResource ButtonFontSize}" Header="Documentation" Name="DocumentationMenuItem" Foreground="{DynamicResource MainForegroundColor}"/>
|
||||||
<MenuItem FontSize="{DynamicResource ButtonFontSize}" Header="Sponsors" Name="SponsorMenuItem" Foreground="{DynamicResource MainForegroundColor}"/>
|
<MenuItem FontSize="{DynamicResource ButtonFontSize}" Header="Sponsors" Name="SponsorMenuItem" Foreground="{DynamicResource MainForegroundColor}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
@@ -1171,7 +1199,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<TabControl Name="WPFTabNav" Background="Transparent" Width="Auto" Height="Auto" BorderBrush="Transparent" BorderThickness="0" Grid.Row="1" Grid.Column="0" Padding="-1">
|
<TabControl Name="WPFTabNav" Background="Transparent" Width="Auto" Height="Auto" BorderBrush="Transparent" BorderThickness="0" Grid.Row="2" Grid.Column="0" Padding="-1">
|
||||||
<TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1">
|
<TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1">
|
||||||
<Grid Background="Transparent" >
|
<Grid Background="Transparent" >
|
||||||
|
|
||||||
@@ -1340,21 +1368,17 @@
|
|||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem Header="Win11ISO" Visibility="Collapsed" Name="WPFTab5">
|
<TabItem Header="Win11ISO" Visibility="Collapsed" Name="WPFTab5">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="{DynamicResource TabContentMargin}">
|
<Grid Name="Win11ISOPanel" Margin="{DynamicResource TabContentMargin}" Background="Transparent">
|
||||||
<Grid Background="Transparent" Name="Win11ISOPanel">
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/> <!-- Step 1: Select ISO -->
|
<RowDefinition Height="Auto"/> <!-- Steps 1-4 -->
|
||||||
<RowDefinition Height="Auto"/> <!-- Step 2: Mount & Verify -->
|
<RowDefinition Height="*"/> <!-- Log / Status -->
|
||||||
<RowDefinition Height="Auto"/> <!-- Step 3: Modify install.wim -->
|
|
||||||
<RowDefinition Height="Auto"/> <!-- Step 4: Output Options -->
|
|
||||||
<RowDefinition Height="Auto"/> <!-- Log / Status -->
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
<!-- Steps 1-4 -->
|
||||||
<!-- STEP 1 : Select Windows 11 ISO -->
|
<StackPanel Grid.Row="0">
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
|
||||||
<Border Grid.Row="0" Name="WPFWin11ISOSelectSection" Style="{StaticResource BorderStyle}">
|
<!-- ─── STEP 1 : Select Windows 11 ISO ─────────────── -->
|
||||||
<Grid Margin="5">
|
<Grid Name="WPFWin11ISOSelectSection" Margin="5" HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -1441,16 +1465,12 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
<!-- ─── STEP 2 : Mount & Verify ISO ──────────────────── -->
|
||||||
<!-- STEP 2 : Mount & Verify ISO -->
|
<Grid Name="WPFWin11ISOMountSection"
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
Margin="5"
|
||||||
<Border Grid.Row="1"
|
Visibility="Collapsed"
|
||||||
Name="WPFWin11ISOMountSection"
|
HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
|
||||||
Style="{StaticResource BorderStyle}"
|
|
||||||
Visibility="Collapsed">
|
|
||||||
<Grid Margin="5">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
@@ -1472,6 +1492,13 @@
|
|||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Width="Auto" Padding="12,0"
|
Width="Auto" Padding="12,0"
|
||||||
Height="{DynamicResource ButtonHeight}"/>
|
Height="{DynamicResource ButtonHeight}"/>
|
||||||
|
<CheckBox Name="WPFWin11ISOInjectDrivers"
|
||||||
|
Content="Inject current system drivers"
|
||||||
|
FontSize="{DynamicResource FontSize}"
|
||||||
|
Foreground="{DynamicResource MainForegroundColor}"
|
||||||
|
IsChecked="False"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
ToolTip="Exports all drivers from this machine and injects them into install.wim and boot.wim. Recommended for systems with unsupported NVMe or network controllers."/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Verification results panel -->
|
<!-- Verification results panel -->
|
||||||
@@ -1500,22 +1527,17 @@
|
|||||||
FontSize="{DynamicResource FontSize}"
|
FontSize="{DynamicResource FontSize}"
|
||||||
Foreground="{DynamicResource MainForegroundColor}"
|
Foreground="{DynamicResource MainForegroundColor}"
|
||||||
Background="{DynamicResource MainBackgroundColor}"
|
Background="{DynamicResource MainBackgroundColor}"
|
||||||
BorderBrush="{DynamicResource BorderColor}"
|
HorizontalAlignment="Left"
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Margin="0,0,0,0"/>
|
Margin="0,0,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
<!-- ─── STEP 3 : Modify install.wim ───────────────────── -->
|
||||||
<!-- STEP 3 : Modify install.wim -->
|
<StackPanel Name="WPFWin11ISOModifySection"
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
Margin="5"
|
||||||
<Border Grid.Row="2"
|
Visibility="Collapsed"
|
||||||
Name="WPFWin11ISOModifySection"
|
HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
|
||||||
Style="{StaticResource BorderStyle}"
|
|
||||||
Visibility="Collapsed">
|
|
||||||
<StackPanel Margin="5">
|
|
||||||
<TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold"
|
<TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold"
|
||||||
Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,8">
|
Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,8">
|
||||||
Step 3 - Modify install.wim
|
Step 3 - Modify install.wim
|
||||||
@@ -1534,15 +1556,12 @@
|
|||||||
Width="Auto" Padding="12,0"
|
Width="Auto" Padding="12,0"
|
||||||
Height="{DynamicResource ButtonHeight}"/>
|
Height="{DynamicResource ButtonHeight}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
<!-- ─── STEP 4 : Output Options ───────────────────────── -->
|
||||||
<!-- STEP 4 : Output Options -->
|
<StackPanel Name="WPFWin11ISOOutputSection"
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
Margin="5"
|
||||||
<Border Grid.Row="3"
|
Visibility="Collapsed"
|
||||||
Name="WPFWin11ISOOutputSection"
|
HorizontalAlignment="Left" MinWidth="{DynamicResource ButtonWidth}">
|
||||||
Style="{StaticResource BorderStyle}">
|
|
||||||
<StackPanel Margin="5">
|
|
||||||
<!-- Header row: title + Clean & Reset button -->
|
<!-- Header row: title + Clean & Reset button -->
|
||||||
<Grid Margin="0,0,0,12">
|
<Grid Margin="0,0,0,12">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -1579,7 +1598,7 @@
|
|||||||
Height="{DynamicResource ButtonHeight}"/>
|
Height="{DynamicResource ButtonHeight}"/>
|
||||||
<Button Grid.Column="2"
|
<Button Grid.Column="2"
|
||||||
Name="WPFWin11ISOChooseUSBButton"
|
Name="WPFWin11ISOChooseUSBButton"
|
||||||
Content="Write Directly to a USB Drive (erases drive)"
|
Content="Write Directly to a USB Drive (ERASES DRIVE)"
|
||||||
Foreground="OrangeRed"
|
Foreground="OrangeRed"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Width="Auto" Padding="12,0"
|
Width="Auto" Padding="12,0"
|
||||||
@@ -1613,7 +1632,7 @@
|
|||||||
Margin="0,0,6,0"/>
|
Margin="0,0,6,0"/>
|
||||||
<Button Grid.Column="1"
|
<Button Grid.Column="1"
|
||||||
Name="WPFWin11ISORefreshUSBButton"
|
Name="WPFWin11ISORefreshUSBButton"
|
||||||
Content="↻ Refresh"
|
Content="Refresh"
|
||||||
Width="Auto" Padding="8,0"
|
Width="Auto" Padding="8,0"
|
||||||
Height="{DynamicResource ButtonHeight}"/>
|
Height="{DynamicResource ButtonHeight}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -1626,34 +1645,37 @@
|
|||||||
Margin="0,0,0,10"/>
|
Margin="0,0,0,10"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
<!-- Status Log (fills remaining height) -->
|
||||||
<!-- Status / Log Output -->
|
<Grid Grid.Row="1" Margin="5">
|
||||||
<!-- ═══════════════════════════════════════════════════════════ -->
|
<Grid.RowDefinitions>
|
||||||
<Border Grid.Row="4" Style="{StaticResource BorderStyle}">
|
<RowDefinition Height="Auto"/>
|
||||||
<StackPanel>
|
<RowDefinition Height="*"/>
|
||||||
<TextBlock FontSize="{DynamicResource FontSize}" FontWeight="Bold"
|
</Grid.RowDefinitions>
|
||||||
Foreground="{DynamicResource MainForegroundColor}" Margin="0,0,0,6">
|
<TextBlock Grid.Row="0"
|
||||||
|
FontSize="{DynamicResource FontSize}" FontWeight="Bold"
|
||||||
|
Foreground="{DynamicResource MainForegroundColor}"
|
||||||
|
Margin="0,0,0,4">
|
||||||
Status Log
|
Status Log
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<TextBox Name="WPFWin11ISOStatusLog"
|
<TextBox Grid.Row="1"
|
||||||
|
Name="WPFWin11ISOStatusLog"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
TextWrapping="Wrap"
|
TextWrapping="Wrap"
|
||||||
VerticalScrollBarVisibility="Auto"
|
VerticalScrollBarVisibility="Visible"
|
||||||
Height="140" Padding="6"
|
VerticalAlignment="Stretch"
|
||||||
|
Padding="6"
|
||||||
Background="{DynamicResource MainBackgroundColor}"
|
Background="{DynamicResource MainBackgroundColor}"
|
||||||
Foreground="{DynamicResource MainForegroundColor}"
|
Foreground="{DynamicResource MainForegroundColor}"
|
||||||
BorderBrush="{DynamicResource BorderColor}"
|
BorderBrush="{DynamicResource BorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Text="Ready. Please select a Windows 11 ISO to begin."/>
|
Text="Ready. Please select a Windows 11 ISO to begin."/>
|
||||||
</StackPanel>
|
</Grid>
|
||||||
</Border>
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
Reference in New Issue
Block a user