mirror of
https://github.com/ChrisTitusTech/winutil
synced 2026-04-06 06:38:31 +00:00
Compare commits
30 Commits
26.02.18
...
58dacd5b0b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58dacd5b0b | ||
|
|
14ad9f7fea | ||
|
|
52afab2252 | ||
|
|
2ba3a5d324 | ||
|
|
f854d14117 | ||
|
|
19204534a2 | ||
|
|
a9d9b148db | ||
|
|
d5d0bf25f0 | ||
|
|
da3fd87f9a | ||
|
|
9e8cefc973 | ||
|
|
a532e9ec9d | ||
|
|
844979fee7 | ||
|
|
78302934ef | ||
|
|
349889b194 | ||
|
|
c619f3a830 | ||
|
|
d005a225a2 | ||
|
|
e79e946e76 | ||
|
|
3b957e1a77 | ||
|
|
d078d67b1d | ||
|
|
191fe95572 | ||
|
|
d10c9413ac | ||
|
|
e93753e5c9 | ||
|
|
5eec99df1c | ||
|
|
7e2ba41b8b | ||
|
|
d3dc3e7976 | ||
|
|
5a4d822710 | ||
|
|
2625478ef3 | ||
|
|
956a544c2e | ||
|
|
50dbf5bd05 | ||
|
|
338c3e7e57 |
12
.github/CONTRIBUTING.md
vendored
12
.github/CONTRIBUTING.md
vendored
@@ -68,9 +68,9 @@ graph TD
|
|||||||
### Fork the Repo
|
### Fork the Repo
|
||||||
* Fork the WinUtil Repository [here](https://github.com/ChrisTitusTech/winutil) to create a copy that will be available in your repository list.
|
* Fork the WinUtil Repository [here](https://github.com/ChrisTitusTech/winutil) to create a copy that will be available in your repository list.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Clone the Fork
|
### Clone the Fork
|
||||||
!!! tip
|
!!! tip
|
||||||
@@ -94,22 +94,22 @@ graph TD
|
|||||||
* Run the following command to compile and run WinUtil:
|
* Run the following command to compile and run WinUtil:
|
||||||
* `.\Compile.ps1 -run`
|
* `.\Compile.ps1 -run`
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
* After seeing that your changes work properly, feel free to commit the changes to the repository and make a PR. For help on that, follow the documentation below.
|
* After seeing that your changes work properly, feel free to commit the changes to the repository and make a PR. For help on that, follow the documentation below.
|
||||||
|
|
||||||
### Committing the changes
|
### Committing the changes
|
||||||
* Before committing your changes, please discard changes made to the `winutil.ps1` file, like the following:
|
* Before committing your changes, please discard changes made to the `winutil.ps1` file, like the following:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
* Now, commit your changes once you are happy with the result.
|
* Now, commit your changes once you are happy with the result.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
* Push the changes to upload them to your fork on github.com.
|
* Push the changes to upload them to your fork on github.com.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Making a PR
|
### Making a PR
|
||||||
* To make a PR on your repo under a new branch linking to the main branch, a button will show and say Preview and Create pull request. Click that button and fill in all the information that is provided on the template. Once all the information is filled in correctly, check your PR to make sure there is not a WinUtil.ps1 file attached to the PR. Once everything is good, make the PR and wait for Chris (the maintainer) to accept or deny your PR. Once it is accepted by Chris, you will be able to see your changes in the "/windev" build.
|
* To make a PR on your repo under a new branch linking to the main branch, a button will show and say Preview and Create pull request. Click that button and fill in all the information that is provided on the template. Once all the information is filled in correctly, check your PR to make sure there is not a WinUtil.ps1 file attached to the PR. Once everything is good, make the PR and wait for Chris (the maintainer) to accept or deny your PR. Once it is accepted by Chris, you will be able to see your changes in the "/windev" build.
|
||||||
|
|||||||
7
.github/workflows/auto-merge-docs.yaml
vendored
7
.github/workflows/auto-merge-docs.yaml
vendored
@@ -8,7 +8,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
auto-merge:
|
auto-merge:
|
||||||
if: github.event.pull_request.head.ref == 'docs-update' && github.event.pull_request.user.login == 'github-actions[bot]'
|
if: github.event.pull_request.head.ref == 'docs-update' && (github.event.pull_request.user.login == 'ChrisTitusTech' || github.event.pull_request.user.login == 'github-actions[bot]')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
@@ -18,13 +18,14 @@ jobs:
|
|||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Auto-approve PR
|
- name: Auto-approve PR
|
||||||
|
if: github.event.pull_request.user.login == 'github-actions[bot]'
|
||||||
run: gh pr review "$PR_NUMBER" --approve
|
run: gh pr review "$PR_NUMBER" --approve
|
||||||
env:
|
env:
|
||||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
GH_TOKEN: ${{ secrets.AUTO_MERGE }}
|
GH_TOKEN: ${{ secrets.AUTO_MERGE }}
|
||||||
|
|
||||||
- name: Enable auto-merge
|
- name: Enable auto-merge
|
||||||
run: gh pr merge "$PR_NUMBER" --squash --auto --delete-branch
|
run: gh pr merge "$PR_NUMBER" --squash --delete-branch --admin
|
||||||
env:
|
env:
|
||||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.AUTO_MERGE }}
|
||||||
|
|||||||
19
.github/workflows/docs.yaml
vendored
19
.github/workflows/docs.yaml
vendored
@@ -12,7 +12,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: read
|
||||||
pages: write
|
pages: write
|
||||||
id-token: write
|
id-token: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
@@ -47,23 +47,30 @@ jobs:
|
|||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
id: pages
|
id: pages
|
||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
|
|
||||||
- name: Generate Dev Docs from JSON
|
- name: Generate Dev Docs from JSON
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
Set-Location tools
|
Set-Location tools
|
||||||
./devdocs-generator.ps1
|
./devdocs-generator.ps1
|
||||||
|
|
||||||
- name: Create Pull Request 🚀
|
- name: Create Pull Request
|
||||||
id: cpr
|
id: cpr
|
||||||
uses: peter-evans/create-pull-request@v6
|
uses: peter-evans/create-pull-request@v8
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.AUTO_MERGE }}
|
||||||
commit-message: 'Update generated documentation'
|
commit-message: 'chore: Update generated dev docs'
|
||||||
title: 'chore: Update Generated Dev Docs'
|
title: 'chore: Update Generated Dev Docs'
|
||||||
body: 'Automated update of generated documentation from JSON sources'
|
body: 'Automated update of generated documentation from JSON sources'
|
||||||
branch: docs-update
|
branch: docs-update
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
labels: automated
|
add-paths: |
|
||||||
|
docs/content/dev/
|
||||||
|
config/tweaks.json
|
||||||
|
config/feature.json
|
||||||
|
labels: |
|
||||||
|
automated
|
||||||
|
documentation
|
||||||
|
|
||||||
- name: Check outputs
|
- name: Check outputs
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
37
.github/workflows/pre-release.yaml
vendored
37
.github/workflows/pre-release.yaml
vendored
@@ -3,6 +3,7 @@ name: Pre-Release WinUtil
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
actions: read
|
actions: read
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch: # Manual trigger added
|
workflow_dispatch: # Manual trigger added
|
||||||
@@ -22,25 +23,35 @@ jobs:
|
|||||||
Set-Location tools
|
Set-Location tools
|
||||||
./devdocs-generator.ps1
|
./devdocs-generator.ps1
|
||||||
|
|
||||||
- name: Commit Updated JSON Links
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git add config/tweaks.json config/feature.json
|
|
||||||
$changes = git diff --cached --quiet; if ($LASTEXITCODE -ne 0) {
|
|
||||||
git commit -m "Update documentation links in JSON configs"
|
|
||||||
git push
|
|
||||||
} else {
|
|
||||||
Write-Host "No JSON link changes to commit"
|
|
||||||
}
|
|
||||||
|
|
||||||
- name: Compile project
|
- name: Compile project
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
Set-ExecutionPolicy Bypass -Scope Process -Force; ./Compile.ps1
|
Set-ExecutionPolicy Bypass -Scope Process -Force; ./Compile.ps1
|
||||||
continue-on-error: false # Directly fail the job on error, removing the need for a separate check
|
continue-on-error: false # Directly fail the job on error, removing the need for a separate check
|
||||||
|
|
||||||
|
- name: Create Pull Request for Updated JSON Links
|
||||||
|
id: cpr
|
||||||
|
uses: peter-evans/create-pull-request@v8
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.AUTO_MERGE }}
|
||||||
|
commit-message: 'chore: Update documentation links in JSON configs'
|
||||||
|
title: 'chore: Update Generated Dev Docs'
|
||||||
|
body: 'Automated update of documentation links in JSON configs from pre-release build'
|
||||||
|
branch: docs-update
|
||||||
|
delete-branch: true
|
||||||
|
add-paths: |
|
||||||
|
config/tweaks.json
|
||||||
|
config/feature.json
|
||||||
|
labels: |
|
||||||
|
automated
|
||||||
|
documentation
|
||||||
|
|
||||||
|
- name: Check outputs
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||||
|
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
||||||
|
|
||||||
- name: Set Version to Todays Date
|
- name: Set Version to Todays Date
|
||||||
id: extract_version
|
id: extract_version
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/sponsors.yaml
vendored
2
.github/workflows/sponsors.yaml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create Pull Request 🚀
|
- name: Create Pull Request 🚀
|
||||||
id: cpr
|
id: cpr
|
||||||
uses: peter-evans/create-pull-request@v6
|
uses: peter-evans/create-pull-request@v8
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
commit-message: 'Update sponsors in README'
|
commit-message: 'Update sponsors in README'
|
||||||
|
|||||||
30
Compile.ps1
30
Compile.ps1
@@ -1,5 +1,4 @@
|
|||||||
param (
|
param (
|
||||||
[switch]$Debug,
|
|
||||||
[switch]$Run,
|
[switch]$Run,
|
||||||
[string]$Arguments
|
[string]$Arguments
|
||||||
)
|
)
|
||||||
@@ -104,19 +103,26 @@ $xaml
|
|||||||
'@
|
'@
|
||||||
"@)
|
"@)
|
||||||
|
|
||||||
|
Update-Progress "Adding: autounattend.xml" 95
|
||||||
|
$autounattendRaw = Get-Content "$workingdir\tools\autounattend.xml" -Raw
|
||||||
|
# Strip XML comments (<!-- ... -->, including multi-line)
|
||||||
|
$autounattendRaw = [regex]::Replace($autounattendRaw, '<!--.*?-->', '', [System.Text.RegularExpressions.RegexOptions]::Singleline)
|
||||||
|
# Drop blank lines and trim trailing whitespace per line
|
||||||
|
$autounattendXml = ($autounattendRaw -split "`r?`n" |
|
||||||
|
Where-Object { $_.Trim() -ne '' } |
|
||||||
|
ForEach-Object { $_.TrimEnd() }) -join "`r`n"
|
||||||
|
$script_content.Add(@"
|
||||||
|
`$WinUtilAutounattendXml = @'
|
||||||
|
$autounattendXml
|
||||||
|
'@
|
||||||
|
"@)
|
||||||
|
|
||||||
$script_content.Add($(Get-Content "scripts\main.ps1"))
|
$script_content.Add($(Get-Content "scripts\main.ps1"))
|
||||||
|
|
||||||
if ($Debug) {
|
Update-Progress "Removing temporary files" 99
|
||||||
Update-Progress "Writing debug files" 95
|
Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue
|
||||||
$appXamlContent | Out-File -FilePath "xaml\inputApp.xaml" -Encoding ascii
|
Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
|
||||||
$tweaksXamlContent | Out-File -FilePath "xaml\inputTweaks.xaml" -Encoding ascii
|
Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
|
||||||
$featuresXamlContent | Out-File -FilePath "xaml\inputFeatures.xaml" -Encoding ascii
|
|
||||||
} else {
|
|
||||||
Update-Progress "Removing temporary files" 99
|
|
||||||
Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue
|
|
||||||
Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
|
|
||||||
Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii
|
Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii
|
||||||
Write-Progress -Activity "Compiling" -Completed
|
Write-Progress -Activity "Compiling" -Completed
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
This utility is a compilation of Windows tasks I perform on each Windows system I use. It is meant to streamline *installs*, debloat with *tweaks*, troubleshoot with *config*, and fix Windows *updates*. I am extremely picky about any contributions to keep this project clean and efficient.
|
This utility is a compilation of Windows tasks I perform on each Windows system I use. It is meant to streamline *installs*, debloat with *tweaks*, troubleshoot with *config*, and fix Windows *updates*. I am extremely picky about any contributions to keep this project clean and efficient.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 💡 Usage
|
## 💡 Usage
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ You'll see a new file named `winutil.ps1`, which's created by `Compile.ps1` scri
|
|||||||
|
|
||||||
These are the sponsors that help keep this project alive with monthly contributions.
|
These are the sponsors that help keep this project alive with monthly contributions.
|
||||||
|
|
||||||
<!-- sponsors --><a href="https://github.com/dwelfusius"><img src="https://github.com/dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https://github.com/mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https://github.com/jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/robertsandrock"><img src="https://github.com/robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https://github.com/KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https://github.com/paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https://github.com/djones369.png" width="60px" alt="User avatar: Dave J (WhamGeek)" /></a><a href="https://github.com/anthonymendez"><img src="https://github.com/anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/FatBastard0"><img src="https://github.com/FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DursleyGuy"><img src="https://github.com/DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/quaszi"><img src="https://github.com/quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https://github.com/DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https://github.com/KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><a href="https://github.com/andrewpayne68"><img src="https://github.com/andrewpayne68.png" width="60px" alt="User avatar: Andrew P" /></a><!-- sponsors -->
|
<!-- sponsors --><a href="https://github.com/dwelfusius"><img src="https://github.com/dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https://github.com/mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https://github.com/jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/robertsandrock"><img src="https://github.com/robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https://github.com/KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https://github.com/paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https://github.com/djones369.png" width="60px" alt="User avatar: Dave J (WhamGeek)" /></a><a href="https://github.com/anthonymendez"><img src="https://github.com/anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/FatBastard0"><img src="https://github.com/FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DursleyGuy"><img src="https://github.com/DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/quaszi"><img src="https://github.com/quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https://github.com/DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https://github.com/KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><a href="https://github.com/andrewpayne68"><img src="https://github.com/andrewpayne68.png" width="60px" alt="User avatar: Andrew P" /></a><a href="https://github.com/nathanzilgo"><img src="https://github.com/nathanzilgo.png" width="60px" alt="User avatar: Nathan Fernandes Pedroza" /></a><!-- sponsors -->
|
||||||
|
|
||||||
## 🏅 Thanks to all Contributors
|
## 🏅 Thanks to all Contributors
|
||||||
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
|
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
|
||||||
|
|||||||
@@ -496,6 +496,14 @@
|
|||||||
"link": "https://dotnet.microsoft.com/download/dotnet/9.0",
|
"link": "https://dotnet.microsoft.com/download/dotnet/9.0",
|
||||||
"winget": "Microsoft.DotNet.DesktopRuntime.9"
|
"winget": "Microsoft.DotNet.DesktopRuntime.9"
|
||||||
},
|
},
|
||||||
|
"dotnet10": {
|
||||||
|
"category": "Microsoft Tools",
|
||||||
|
"choco": "dotnet-10.0-runtime",
|
||||||
|
"content": ".NET Desktop Runtime 10",
|
||||||
|
"description": ".NET Desktop Runtime 10 is a runtime environment required for running applications developed with .NET 10.",
|
||||||
|
"link": "https://dotnet.microsoft.com/download/dotnet/10.0",
|
||||||
|
"winget": "Microsoft.DotNet.DesktopRuntime.10"
|
||||||
|
},
|
||||||
"dmt": {
|
"dmt": {
|
||||||
"winget": "GNE.DualMonitorTools",
|
"winget": "GNE.DualMonitorTools",
|
||||||
"choco": "dual-monitor-tools",
|
"choco": "dual-monitor-tools",
|
||||||
@@ -3226,5 +3234,23 @@
|
|||||||
"link": "https://zed.dev/",
|
"link": "https://zed.dev/",
|
||||||
"winget": "ZedIndustries.Zed",
|
"winget": "ZedIndustries.Zed",
|
||||||
"foss": true
|
"foss": true
|
||||||
|
},
|
||||||
|
"LLLVM": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "llvm",
|
||||||
|
"winget": "LLVM.LLVM",
|
||||||
|
"description": "A collection of modular and reusable compiler and toolchain technologies.",
|
||||||
|
"content": "LLVM",
|
||||||
|
"link": "https://llvm.org",
|
||||||
|
"foss": true
|
||||||
|
},
|
||||||
|
"NASM": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "nasm",
|
||||||
|
"winget": "NASM.NASM",
|
||||||
|
"description": "A powerful assembler for the x86 platform.",
|
||||||
|
"content": "NASM",
|
||||||
|
"link": "https://nasm.us",
|
||||||
|
"foss": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.",
|
"Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a010_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"NetFx4-AdvSrvs",
|
"NetFx4-AdvSrvs",
|
||||||
"NetFx3"
|
"NetFx3"
|
||||||
@@ -17,7 +16,6 @@
|
|||||||
"Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.",
|
"Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a011_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"Microsoft-Hyper-V-All"
|
"Microsoft-Hyper-V-All"
|
||||||
],
|
],
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
"Description": "Enables legacy programs from previous versions of windows",
|
"Description": "Enables legacy programs from previous versions of windows",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a012_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"WindowsMediaPlayer",
|
"WindowsMediaPlayer",
|
||||||
"MediaPlayback",
|
"MediaPlayback",
|
||||||
@@ -46,7 +43,6 @@
|
|||||||
"Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.",
|
"Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a020_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"VirtualMachinePlatform",
|
"VirtualMachinePlatform",
|
||||||
"Microsoft-Windows-Subsystem-Linux"
|
"Microsoft-Windows-Subsystem-Linux"
|
||||||
@@ -59,7 +55,6 @@
|
|||||||
"Description": "Network File System (NFS) is a mechanism for storing files on a network.",
|
"Description": "Network File System (NFS) is a mechanism for storing files on a network.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a014_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"ServicesForNFS-ClientOnly",
|
"ServicesForNFS-ClientOnly",
|
||||||
"ClientForNFS-Infrastructure",
|
"ClientForNFS-Infrastructure",
|
||||||
@@ -79,7 +74,6 @@
|
|||||||
"Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.",
|
"Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a017_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
@@ -97,7 +91,6 @@
|
|||||||
"Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
"Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a018_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"bcdedit /set bootmenupolicy legacy"
|
"bcdedit /set bootmenupolicy legacy"
|
||||||
@@ -109,7 +102,6 @@
|
|||||||
"Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
"Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a019_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"bcdedit /set bootmenupolicy standard"
|
"bcdedit /set bootmenupolicy standard"
|
||||||
@@ -121,7 +113,6 @@
|
|||||||
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a021_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"Containers-DisposableClientVM"
|
"Containers-DisposableClientVM"
|
||||||
],
|
],
|
||||||
@@ -131,54 +122,54 @@
|
|||||||
"Content": "Install Features",
|
"Content": "Install Features",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a060_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFeatureInstall",
|
||||||
"link": "https://winutil.christitus.com/dev/features/features/install"
|
"link": "https://winutil.christitus.com/dev/features/features/install"
|
||||||
},
|
},
|
||||||
"WPFPanelAutologin": {
|
"WPFPanelAutologin": {
|
||||||
"Content": "Set Up Autologin",
|
"Content": "Set Up Autologin",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"Order": "a040_",
|
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFPanelAutologin",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/autologin"
|
"link": "https://winutil.christitus.com/dev/features/fixes/autologin"
|
||||||
},
|
},
|
||||||
"WPFFixesUpdate": {
|
"WPFFixesUpdate": {
|
||||||
"Content": "Reset Windows Update",
|
"Content": "Reset Windows Update",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a041_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFixesUpdate",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/update"
|
"link": "https://winutil.christitus.com/dev/features/fixes/update"
|
||||||
},
|
},
|
||||||
"WPFFixesNetwork": {
|
"WPFFixesNetwork": {
|
||||||
"Content": "Reset Network",
|
"Content": "Reset Network",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"Order": "a042_",
|
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFixesNetwork",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/network"
|
"link": "https://winutil.christitus.com/dev/features/fixes/network"
|
||||||
},
|
},
|
||||||
"WPFPanelDISM": {
|
"WPFPanelDISM": {
|
||||||
"Content": "System Corruption Scan",
|
"Content": "System Corruption Scan",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a043_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFSystemRepair",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/dism"
|
"link": "https://winutil.christitus.com/dev/features/fixes/dism"
|
||||||
},
|
},
|
||||||
"WPFFixesWinget": {
|
"WPFFixesWinget": {
|
||||||
"Content": "WinGet Reinstall",
|
"Content": "WinGet Reinstall",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a044_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFFixesWinget",
|
||||||
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
|
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
|
||||||
},
|
},
|
||||||
"WPFPanelControl": {
|
"WPFPanelControl": {
|
||||||
@@ -187,6 +178,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"control"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
|
||||||
},
|
},
|
||||||
"WPFPanelComputer": {
|
"WPFPanelComputer": {
|
||||||
@@ -195,6 +189,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"compmgmt.msc"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
|
||||||
},
|
},
|
||||||
"WPFPanelNetwork": {
|
"WPFPanelNetwork": {
|
||||||
@@ -203,6 +200,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"ncpa.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
|
||||||
},
|
},
|
||||||
"WPFPanelPower": {
|
"WPFPanelPower": {
|
||||||
@@ -211,6 +211,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"powercfg.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
|
||||||
},
|
},
|
||||||
"WPFPanelPrinter": {
|
"WPFPanelPrinter": {
|
||||||
@@ -219,6 +222,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"Start-Process 'shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}'"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
|
||||||
},
|
},
|
||||||
"WPFPanelRegion": {
|
"WPFPanelRegion": {
|
||||||
@@ -227,6 +233,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"intl.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
|
||||||
},
|
},
|
||||||
"WPFPanelRestore": {
|
"WPFPanelRestore": {
|
||||||
@@ -235,6 +244,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"rstrui.exe"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore"
|
||||||
},
|
},
|
||||||
"WPFPanelSound": {
|
"WPFPanelSound": {
|
||||||
@@ -243,6 +255,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"mmsys.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
|
||||||
},
|
},
|
||||||
"WPFPanelSystem": {
|
"WPFPanelSystem": {
|
||||||
@@ -251,6 +266,9 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"sysdm.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
|
||||||
},
|
},
|
||||||
"WPFPanelTimedate": {
|
"WPFPanelTimedate": {
|
||||||
@@ -259,33 +277,36 @@
|
|||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"InvokeScript": [
|
||||||
|
"timedate.cpl"
|
||||||
|
],
|
||||||
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate"
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate"
|
||||||
},
|
},
|
||||||
"WPFWinUtilInstallPSProfile": {
|
"WPFWinUtilInstallPSProfile": {
|
||||||
"Content": "Install CTT PowerShell Profile",
|
"Content": "Install CTT PowerShell Profile",
|
||||||
"category": "Powershell Profile Powershell 7+ Only",
|
"category": "Powershell Profile Powershell 7+ Only",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Order": "a083_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WinUtilInstallPSProfile",
|
||||||
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/installpsprofile"
|
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/installpsprofile"
|
||||||
},
|
},
|
||||||
"WPFWinUtilUninstallPSProfile": {
|
"WPFWinUtilUninstallPSProfile": {
|
||||||
"Content": "Uninstall CTT PowerShell Profile",
|
"Content": "Uninstall CTT PowerShell Profile",
|
||||||
"category": "Powershell Profile Powershell 7+ Only",
|
"category": "Powershell Profile Powershell 7+ Only",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Order": "a084_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WinUtilUninstallPSProfile",
|
||||||
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/uninstallpsprofile"
|
"link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/uninstallpsprofile"
|
||||||
},
|
},
|
||||||
"WPFWinUtilSSHServer": {
|
"WPFWinUtilSSHServer": {
|
||||||
"Content": "Enable OpenSSH Server",
|
"Content": "Enable OpenSSH Server",
|
||||||
"category": "Remote Access",
|
"category": "Remote Access",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Order": "a084_",
|
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300",
|
"ButtonWidth": "300",
|
||||||
|
"function": "Invoke-WPFSSHServer",
|
||||||
"link": "https://winutil.christitus.com/dev/features/remote-access/sshserver"
|
"link": "https://winutil.christitus.com/dev/features/remote-access/sshserver"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
],
|
],
|
||||||
"Minimal": [
|
"Minimal": [
|
||||||
"WPFTweaksConsumerFeatures",
|
"WPFTweaksConsumerFeatures",
|
||||||
"WPFTweaksDisableExplorerAutoDiscovery",
|
|
||||||
"WPFTweaksWPBT",
|
"WPFTweaksWPBT",
|
||||||
"WPFTweaksServices",
|
"WPFTweaksServices",
|
||||||
"WPFTweaksTelemetry"
|
"WPFTweaksTelemetry"
|
||||||
|
|||||||
@@ -65,10 +65,12 @@
|
|||||||
"ButtonTweaksBackgroundColor": "#F7F7F7",
|
"ButtonTweaksBackgroundColor": "#F7F7F7",
|
||||||
"ButtonConfigBackgroundColor": "#F7F7F7",
|
"ButtonConfigBackgroundColor": "#F7F7F7",
|
||||||
"ButtonUpdatesBackgroundColor": "#F7F7F7",
|
"ButtonUpdatesBackgroundColor": "#F7F7F7",
|
||||||
|
"ButtonWin11ISOBackgroundColor": "#F7F7F7",
|
||||||
"ButtonInstallForegroundColor": "#232629",
|
"ButtonInstallForegroundColor": "#232629",
|
||||||
"ButtonTweaksForegroundColor": "#232629",
|
"ButtonTweaksForegroundColor": "#232629",
|
||||||
"ButtonConfigForegroundColor": "#232629",
|
"ButtonConfigForegroundColor": "#232629",
|
||||||
"ButtonUpdatesForegroundColor": "#232629",
|
"ButtonUpdatesForegroundColor": "#232629",
|
||||||
|
"ButtonWin11ISOForegroundColor": "#232629",
|
||||||
"ButtonBackgroundColor": "#F5F5F5",
|
"ButtonBackgroundColor": "#F5F5F5",
|
||||||
"ButtonBackgroundPressedColor": "#1A1A1A",
|
"ButtonBackgroundPressedColor": "#1A1A1A",
|
||||||
"ButtonBackgroundMouseoverColor": "#C2C2C2",
|
"ButtonBackgroundMouseoverColor": "#C2C2C2",
|
||||||
@@ -105,10 +107,12 @@
|
|||||||
"ButtonTweaksBackgroundColor": "#333333",
|
"ButtonTweaksBackgroundColor": "#333333",
|
||||||
"ButtonConfigBackgroundColor": "#444444",
|
"ButtonConfigBackgroundColor": "#444444",
|
||||||
"ButtonUpdatesBackgroundColor": "#555555",
|
"ButtonUpdatesBackgroundColor": "#555555",
|
||||||
|
"ButtonWin11ISOBackgroundColor": "#666666",
|
||||||
"ButtonInstallForegroundColor": "#F7F7F7",
|
"ButtonInstallForegroundColor": "#F7F7F7",
|
||||||
"ButtonTweaksForegroundColor": "#F7F7F7",
|
"ButtonTweaksForegroundColor": "#F7F7F7",
|
||||||
"ButtonConfigForegroundColor": "#F7F7F7",
|
"ButtonConfigForegroundColor": "#F7F7F7",
|
||||||
"ButtonUpdatesForegroundColor": "#F7F7F7",
|
"ButtonUpdatesForegroundColor": "#F7F7F7",
|
||||||
|
"ButtonWin11ISOForegroundColor": "#F7F7F7",
|
||||||
"ButtonBackgroundColor": "#1E3747",
|
"ButtonBackgroundColor": "#1E3747",
|
||||||
"ButtonBackgroundPressedColor": "#F7F7F7",
|
"ButtonBackgroundPressedColor": "#F7F7F7",
|
||||||
"ButtonBackgroundMouseoverColor": "#3B4252",
|
"ButtonBackgroundMouseoverColor": "#3B4252",
|
||||||
|
|||||||
@@ -1907,7 +1907,7 @@
|
|||||||
},
|
},
|
||||||
"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. WARNING: this will also block all Windows third-party driver installations.",
|
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"registry": [
|
"registry": [
|
||||||
@@ -2246,7 +2246,7 @@
|
|||||||
},
|
},
|
||||||
"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.",
|
"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.",
|
||||||
"category": "Customize Preferences",
|
"category": "Customize Preferences",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Toggle",
|
"Type": "Toggle",
|
||||||
@@ -2615,7 +2615,7 @@
|
|||||||
},
|
},
|
||||||
"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.",
|
"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",
|
||||||
"category": "Essential Tweaks",
|
"category": "Essential Tweaks",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ If you are still having issues, try using a **VPN**, or changing your **DNS prov
|
|||||||
| Cloudflare | `1.1.1.1` | `1.0.0.1` |
|
| Cloudflare | `1.1.1.1` | `1.0.0.1` |
|
||||||
| Google | `8.8.8.8` | `8.8.4.4` |
|
| Google | `8.8.8.8` | `8.8.4.4` |
|
||||||
|
|
||||||
|
### Script Won't Run
|
||||||
|
|
||||||
|
If your PowerShell session is running in **Constrained Language Mode**, some scripts and commands may fail to execute. To check the current language mode, run:
|
||||||
|
```powershell
|
||||||
|
$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.
|
||||||
|
|
||||||
### Script blocked by Execution Policy
|
### 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.
|
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.
|
||||||
|
|||||||
@@ -42,3 +42,11 @@ toc: false
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
{{< autolinks section="dev/features/features" >}}
|
{{< autolinks section="dev/features/features" >}}
|
||||||
|
|
||||||
|
### Remote Access
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/remote-access" >}}
|
||||||
|
|
||||||
|
### Powershell Profile Powershell 7+ Only
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/powershell-profile-powershell-7--only" >}}
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "Disable Legacy F8 Boot Recovery"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=107}
|
```json {filename="config/feature.json",linenos=inline,linenostart=100}
|
||||||
"WPFFeatureDisableLegacyRecovery": {
|
"WPFFeatureDisableLegacyRecovery": {
|
||||||
"Content": "Disable Legacy F8 Boot Recovery",
|
"Content": "Disable Legacy F8 Boot Recovery",
|
||||||
"Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
"Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a019_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"bcdedit /set bootmenupolicy standard"
|
"bcdedit /set bootmenupolicy standard"
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "Enable Legacy F8 Boot Recovery"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=95}
|
```json {filename="config/feature.json",linenos=inline,linenostart=89}
|
||||||
"WPFFeatureEnableLegacyRecovery": {
|
"WPFFeatureEnableLegacyRecovery": {
|
||||||
"Content": "Enable Legacy F8 Boot Recovery",
|
"Content": "Enable Legacy F8 Boot Recovery",
|
||||||
"Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
"Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a018_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"bcdedit /set bootmenupolicy legacy"
|
"bcdedit /set bootmenupolicy legacy"
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "Enable Daily Registry Backup Task 12.30am"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=77}
|
```json {filename="config/feature.json",linenos=inline,linenostart=72}
|
||||||
"WPFFeatureRegBackup": {
|
"WPFFeatureRegBackup": {
|
||||||
"Content": "Enable Daily Registry Backup Task 12.30am",
|
"Content": "Enable Daily Registry Backup Task 12.30am",
|
||||||
"Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.",
|
"Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a017_",
|
|
||||||
"feature": [],
|
"feature": [],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "Windows Sandbox"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=119}
|
```json {filename="config/feature.json",linenos=inline,linenostart=111}
|
||||||
"WPFFeaturesSandbox": {
|
"WPFFeaturesSandbox": {
|
||||||
"Content": "Windows Sandbox",
|
"Content": "Windows Sandbox",
|
||||||
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a021_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"Containers-DisposableClientVM"
|
"Containers-DisposableClientVM"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ description: ""
|
|||||||
"Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.",
|
"Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a010_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"NetFx4-AdvSrvs",
|
"NetFx4-AdvSrvs",
|
||||||
"NetFx3"
|
"NetFx3"
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "HyperV Virtualization"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=15}
|
```json {filename="config/feature.json",linenos=inline,linenostart=14}
|
||||||
"WPFFeatureshyperv": {
|
"WPFFeatureshyperv": {
|
||||||
"Content": "HyperV Virtualization",
|
"Content": "HyperV Virtualization",
|
||||||
"Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.",
|
"Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a011_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"Microsoft-Hyper-V-All"
|
"Microsoft-Hyper-V-All"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "Legacy Media (WMP, DirectPlay)"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=29}
|
```json {filename="config/feature.json",linenos=inline,linenostart=27}
|
||||||
"WPFFeatureslegacymedia": {
|
"WPFFeatureslegacymedia": {
|
||||||
"Content": "Legacy Media (WMP, DirectPlay)",
|
"Content": "Legacy Media (WMP, DirectPlay)",
|
||||||
"Description": "Enables legacy programs from previous versions of windows",
|
"Description": "Enables legacy programs from previous versions of windows",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a012_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"WindowsMediaPlayer",
|
"WindowsMediaPlayer",
|
||||||
"MediaPlayback",
|
"MediaPlayback",
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "NFS - Network File System"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=57}
|
```json {filename="config/feature.json",linenos=inline,linenostart=53}
|
||||||
"WPFFeaturenfs": {
|
"WPFFeaturenfs": {
|
||||||
"Content": "NFS - Network File System",
|
"Content": "NFS - Network File System",
|
||||||
"Description": "Network File System (NFS) is a mechanism for storing files on a network.",
|
"Description": "Network File System (NFS) is a mechanism for storing files on a network.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a014_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"ServicesForNFS-ClientOnly",
|
"ServicesForNFS-ClientOnly",
|
||||||
"ClientForNFS-Infrastructure",
|
"ClientForNFS-Infrastructure",
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ title: "Windows Subsystem for Linux"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/feature.json",linenos=inline,linenostart=44}
|
```json {filename="config/feature.json",linenos=inline,linenostart=41}
|
||||||
"WPFFeaturewsl": {
|
"WPFFeaturewsl": {
|
||||||
"Content": "Windows Subsystem for Linux",
|
"Content": "Windows Subsystem for Linux",
|
||||||
"Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.",
|
"Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a020_",
|
|
||||||
"feature": [
|
"feature": [
|
||||||
"VirtualMachinePlatform",
|
"VirtualMachinePlatform",
|
||||||
"Microsoft-Windows-Subsystem-Linux"
|
"Microsoft-Windows-Subsystem-Linux"
|
||||||
|
|||||||
@@ -8,13 +8,15 @@ function Invoke-WPFSystemRepair {
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Checks for system corruption using SFC, and DISM
|
Checks for system corruption using SFC, and DISM
|
||||||
|
Checks for disk failure using Chkdsk
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
1. SFC - Fixes system file corruption, and fixes DISM if it was corrupted
|
1. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
||||||
2. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
2. SFC - scans protected system files for corruption and fixes them
|
||||||
3. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
3. DISM - Repair a corrupted Windows operating system image
|
||||||
#>
|
#>
|
||||||
Start-Process cmd.exe -ArgumentList "/c chkdsk.exe /scan /perf" -NoNewWindow -Wait
|
|
||||||
|
Start-Process cmd.exe -ArgumentList "/c chkdsk /scan /perf" -NoNewWindow -Wait
|
||||||
Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -NoNewWindow -Wait
|
Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -NoNewWindow -Wait
|
||||||
Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait
|
Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait
|
||||||
|
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Computer Management"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=186}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelComputer": {
|
||||||
<#
|
"Content": "Computer Management",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"compmgmt.msc"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Control Panel"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=175}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelControl": {
|
||||||
<#
|
"Content": "Control Panel",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"control"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Network Connections"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=197}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelNetwork": {
|
||||||
<#
|
"Content": "Network Connections",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"ncpa.cpl"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Power Panel"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=208}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelPower": {
|
||||||
<#
|
"Content": "Power Panel",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"powercfg.cpl"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Printer Panel"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=219}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelPrinter": {
|
||||||
<#
|
"Content": "Printer Panel",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"Start-Process 'shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}'"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Region"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=230}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelRegion": {
|
||||||
<#
|
"Content": "Region",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"intl.cpl"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Windows Restore"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=241}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelRestore": {
|
||||||
<#
|
"Content": "Windows Restore",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"rstrui.exe"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Sound Settings"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=252}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelSound": {
|
||||||
<#
|
"Content": "Sound Settings",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"mmsys.cpl"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "System Properties"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=263}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelSystem": {
|
||||||
<#
|
"Content": "System Properties",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"sysdm.cpl"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,31 +3,14 @@ title: "Time and Date"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```powershell {filename="functions/public/Invoke-WPFControlPanel.ps1",linenos=inline,linenostart=1}
|
```json {filename="config/feature.json",linenos=inline,linenostart=274}
|
||||||
function Invoke-WPFControlPanel {
|
"WPFPanelTimedate": {
|
||||||
<#
|
"Content": "Time and Date",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
.SYNOPSIS
|
"panel": "2",
|
||||||
Opens the requested legacy panel
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
.PARAMETER Panel
|
"InvokeScript": [
|
||||||
The panel to open
|
"timedate.cpl"
|
||||||
|
],
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: "Install CTT PowerShell Profile"
|
||||||
|
description: ""
|
||||||
|
---
|
||||||
|
|
||||||
|
```powershell {filename="functions/private/Invoke-WinUtilInstallPSProfile.ps1",linenos=inline,linenostart=1}
|
||||||
|
function Invoke-WinUtilInstallPSProfile {
|
||||||
|
|
||||||
|
if (Test-Path $Profile) {
|
||||||
|
Rename-Item $Profile -NewName ($Profile + '.bak')
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Process pwsh -ArgumentList '-Command "irm https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1 | iex"'
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
title: "Uninstall CTT PowerShell Profile"
|
||||||
|
description: ""
|
||||||
|
---
|
||||||
|
|
||||||
|
```powershell {filename="functions/private/Invoke-WinUtilUninstallPSProfile.ps1",linenos=inline,linenostart=1}
|
||||||
|
function Invoke-WinUtilUninstallPSProfile {
|
||||||
|
if (Test-Path ($Profile + '.bak')) {
|
||||||
|
Remove-Item $Profile
|
||||||
|
Rename-Item ($Profile + '.bak') -NewName $Profile
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Remove-Item $Profile
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Successfully uninstalled CTT Powershell Profile" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "Powershell Profile Powershell 7+ Only"
|
||||||
|
weight: 5
|
||||||
|
toc: false
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/powershell-profile-powershell-7--only" >}}
|
||||||
24
docs/content/dev/features/Remote-Access/SSHServer.md
Normal file
24
docs/content/dev/features/Remote-Access/SSHServer.md
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
title: "Enable OpenSSH Server"
|
||||||
|
description: ""
|
||||||
|
---
|
||||||
|
|
||||||
|
```powershell {filename="functions/public/Invoke-WPFSSHServer.ps1",linenos=inline,linenostart=1}
|
||||||
|
function Invoke-WPFSSHServer {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Invokes the OpenSSH Server install in a runspace
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
Invoke-WPFRunspace -ScriptBlock {
|
||||||
|
|
||||||
|
Invoke-WinUtilSSHServer
|
||||||
|
|
||||||
|
Write-Host "======================================="
|
||||||
|
Write-Host "-- OpenSSH Server installed! ---"
|
||||||
|
Write-Host "======================================="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
7
docs/content/dev/features/Remote-Access/_index.md
Normal file
7
docs/content/dev/features/Remote-Access/_index.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: "Remote Access"
|
||||||
|
weight: 4
|
||||||
|
toc: false
|
||||||
|
---
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/remote-access" >}}
|
||||||
@@ -15,3 +15,11 @@ toc: false
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
{{< autolinks section="dev/features/features" >}}
|
{{< autolinks section="dev/features/features" >}}
|
||||||
|
|
||||||
|
### Remote Access
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/remote-access" >}}
|
||||||
|
|
||||||
|
### Powershell Profile Powershell 7+ Only
|
||||||
|
|
||||||
|
{{< autolinks section="dev/features/powershell-profile-powershell-7--only" >}}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Bing Search in Start Menu"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2186}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2185}
|
||||||
"WPFToggleBingSearch": {
|
"WPFToggleBingSearch": {
|
||||||
"Content": "Bing Search in Start Menu",
|
"Content": "Bing Search in Start Menu",
|
||||||
"Description": "If enable then includes web search results from Bing in your Start Menu search.",
|
"Description": "If enable then includes web search results from Bing in your Start Menu search.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Dark Theme for Windows"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2144}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2143}
|
||||||
"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=2537}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2541}
|
||||||
"WPFToggleDetailedBSoD": {
|
"WPFToggleDetailedBSoD": {
|
||||||
"Content": "Detailed BSoD",
|
"Content": "Detailed BSoD",
|
||||||
"Description": "If Enabled then you will see a detailed Blue Screen of Death (BSOD) with more information.",
|
"Description": "If Enabled then 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=2667}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2671}
|
||||||
"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=2422}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2421}
|
||||||
"WPFToggleHiddenFiles": {
|
"WPFToggleHiddenFiles": {
|
||||||
"Content": "Show Hidden Files",
|
"Content": "Show Hidden Files",
|
||||||
"Description": "If Enabled then Hidden Files will be shown.",
|
"Description": "If Enabled then Hidden Files will be shown.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Remove Settings Home Page"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2292}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2291}
|
||||||
"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=2310}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2309}
|
||||||
"WPFToggleMouseAcceleration": {
|
"WPFToggleMouseAcceleration": {
|
||||||
"Content": "Mouse Acceleration",
|
"Content": "Mouse Acceleration",
|
||||||
"Description": "If Enabled then Cursor movement is affected by the speed of your physical mouse movements.",
|
"Description": "If Enabled then 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=2404}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2403}
|
||||||
"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=2362}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2361}
|
||||||
"WPFToggleNewOutlook": {
|
"WPFToggleNewOutlook": {
|
||||||
"Content": "New Outlook",
|
"Content": "New Outlook",
|
||||||
"Description": "If disabled it removes the toggle for new Outlook, disables the new Outlook migration and makes sure the Outlook Application actually uses the old Outlook.",
|
"Description": "If disabled it removes the toggle for new Outlook, disables the new Outlook migration and makes sure the Outlook Application actually uses the old Outlook.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "NumLock on Startup"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2204}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2203}
|
||||||
"WPFToggleNumLock": {
|
"WPFToggleNumLock": {
|
||||||
"Content": "NumLock on Startup",
|
"Content": "NumLock 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=2563}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2567}
|
||||||
"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=2450}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2449}
|
||||||
"WPFToggleShowExt": {
|
"WPFToggleShowExt": {
|
||||||
"Content": "Show File Extensions",
|
"Content": "Show File Extensions",
|
||||||
"Description": "If enabled then File extensions (e.g., .txt, .jpg) are visible.",
|
"Description": "If enabled then File extensions (e.g., .txt, .jpg) are visible.",
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ title: "Recommendations in Start Menu"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2248}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2247}
|
||||||
"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.",
|
"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.",
|
||||||
"category": "Customize Preferences",
|
"category": "Customize Preferences",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Toggle",
|
"Type": "Toggle",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Sticky Keys"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2344}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2343}
|
||||||
"WPFToggleStickyKeys": {
|
"WPFToggleStickyKeys": {
|
||||||
"Content": "Sticky Keys",
|
"Content": "Sticky Keys",
|
||||||
"Description": "If Enabled then 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 then 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=2496}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2495}
|
||||||
"WPFToggleTaskView": {
|
"WPFToggleTaskView": {
|
||||||
"Content": "Task View Button in Taskbar",
|
"Content": "Task View Button in Taskbar",
|
||||||
"Description": "If Enabled then Task View Button in Taskbar will be shown.",
|
"Description": "If Enabled then 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=2514}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2513}
|
||||||
"WPFToggleTaskbarAlignment": {
|
"WPFToggleTaskbarAlignment": {
|
||||||
"Content": "Center Taskbar Items",
|
"Content": "Center Taskbar Items",
|
||||||
"Description": "[Windows 11] If Enabled then the Taskbar Items will be shown on the Center, otherwise the Taskbar Items will be shown on the Left.",
|
"Description": "[Windows 11] If Enabled then the Taskbar Items will be shown on the Center, otherwise the Taskbar Items will be shown on the Left.",
|
||||||
@@ -25,6 +25,11 @@ description: ""
|
|||||||
Invoke-WinUtilExplorerUpdate -action \"restart\"
|
Invoke-WinUtilExplorerUpdate -action \"restart\"
|
||||||
"
|
"
|
||||||
],
|
],
|
||||||
|
"UndoScript": [
|
||||||
|
"
|
||||||
|
Invoke-WinUtilExplorerUpdate -action \"restart\"
|
||||||
|
"
|
||||||
|
],
|
||||||
```
|
```
|
||||||
|
|
||||||
## Registry Changes
|
## Registry Changes
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Search Button in Taskbar"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2478}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2477}
|
||||||
"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=2230}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2229}
|
||||||
"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: "Delete Temporary Files"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2039}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2038}
|
||||||
"WPFTweaksDeleteTempFiles": {
|
"WPFTweaksDeleteTempFiles": {
|
||||||
"Content": "Delete Temporary Files",
|
"Content": "Delete Temporary Files",
|
||||||
"Description": "Erases TEMP Folders",
|
"Description": "Erases TEMP Folders",
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ title: "Disable Explorer Automatic Folder Discovery"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2612}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2616}
|
||||||
"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.",
|
"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",
|
||||||
"category": "Essential Tweaks",
|
"category": "Essential Tweaks",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Run Disk Cleanup"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2026}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2025}
|
||||||
"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.",
|
||||||
|
|||||||
@@ -967,46 +967,3 @@ description: ""
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
```
|
```
|
||||||
#Function
|
|
||||||
```powershell {filename="functions/private/Set-WinUtilService.ps1",linenos=inline,linenostart=1}
|
|
||||||
Function Set-WinUtilService {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Changes the startup type of the given service
|
|
||||||
|
|
||||||
.PARAMETER Name
|
|
||||||
The name of the service to modify
|
|
||||||
|
|
||||||
.PARAMETER StartupType
|
|
||||||
The startup type to set the service to
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
Set-WinUtilService -Name "HomeGroupListener" -StartupType "Manual"
|
|
||||||
|
|
||||||
#>
|
|
||||||
param (
|
|
||||||
$Name,
|
|
||||||
$StartupType
|
|
||||||
)
|
|
||||||
try {
|
|
||||||
Write-Host "Setting Service $Name to $StartupType"
|
|
||||||
|
|
||||||
# Check if the service exists
|
|
||||||
$service = Get-Service -Name $Name -ErrorAction Stop
|
|
||||||
|
|
||||||
# Service exists, proceed with changing properties -- while handling auto delayed start for PWSH 5
|
|
||||||
if (($PSVersionTable.PSVersion.Major -lt 7) -and ($StartupType -eq "AutomaticDelayedStart")) {
|
|
||||||
sc.exe config $Name start=delayed-auto
|
|
||||||
} else {
|
|
||||||
$service | Set-Service -StartupType $StartupType -ErrorAction Stop
|
|
||||||
}
|
|
||||||
} catch [System.ServiceProcess.ServiceNotFoundException] {
|
|
||||||
Write-Warning "Service $Name was not found"
|
|
||||||
} catch {
|
|
||||||
Write-Warning "Unable to set $Name due to unhandled exception"
|
|
||||||
Write-Warning $_.Exception.Message
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Windows Platform Binary Table (WPBT)"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1893}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1892}
|
||||||
"WPFTweaksWPBT": {
|
"WPFTweaksWPBT": {
|
||||||
"Content": "Disable Windows Platform Binary Table (WPBT)",
|
"Content": "Disable Windows Platform Binary Table (WPBT)",
|
||||||
"Description": "If enabled then allows your computer vendor to execute a program each time it boots. It enables computer vendors to force install anti-theft software, software drivers, or a software program conveniently. This could also be a security risk.",
|
"Description": "If enabled then allows your computer vendor to execute a program each time it boots. It enables computer vendors to force install anti-theft software, software drivers, or a software program conveniently. This could also be a security risk.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Adobe Network Block"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1974}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1973}
|
||||||
"WPFTweaksBlockAdobeNet": {
|
"WPFTweaksBlockAdobeNet": {
|
||||||
"Content": "Adobe Network Block",
|
"Content": "Adobe Network Block",
|
||||||
"Description": "Reduce user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs",
|
"Description": "Reduce user interruptions by selectively blocking connections to Adobe's activation and telemetry servers. Credit: Ruddernation-Designs",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Background Apps"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2112}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2111}
|
||||||
"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 Win11",
|
"Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Win11",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Fullscreen Optimizations"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2128}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2127}
|
||||||
"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=2090}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2089}
|
||||||
"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=1951}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1950}
|
||||||
"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: "Prefer IPv4 over IPv6"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2052}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2051}
|
||||||
"WPFTweaksIPv46": {
|
"WPFTweaksIPv46": {
|
||||||
"Content": "Prefer IPv4 over IPv6",
|
"Content": "Prefer IPv4 over IPv6",
|
||||||
"Description": "To set the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
|
"Description": "To set the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.",
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ title: "Block Razer Software Installs"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=1909}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=1908}
|
||||||
"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. WARNING: this will also block all Windows third-party driver installations.",
|
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"registry": [
|
"registry": [
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ description: ""
|
|||||||
$Sid = (Get-LocalUser $Env:UserName).Sid.Value
|
$Sid = (Get-LocalUser $Env:UserName).Sid.Value
|
||||||
New-Item \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\EndOfLife\\$Sid\\$Appx\" -Force
|
New-Item \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\EndOfLife\\$Sid\\$Appx\" -Force
|
||||||
Remove-AppxPackage $Appx
|
Remove-AppxPackage $Appx
|
||||||
}
|
|
||||||
"
|
"
|
||||||
],
|
],
|
||||||
"UndoScript": [
|
"UndoScript": [
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Set Classic Right-Click Menu "
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2004}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2003}
|
||||||
"WPFTweaksRightClickMenu": {
|
"WPFTweaksRightClickMenu": {
|
||||||
"Content": "Set Classic Right-Click Menu ",
|
"Content": "Set Classic Right-Click Menu ",
|
||||||
"Description": "Great Windows 11 tweak to bring back good context menus when right clicking things in explorer.",
|
"Description": "Great Windows 11 tweak to bring back good context menus when right clicking things in explorer.",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "Disable Teredo"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2068}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2067}
|
||||||
"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: "DNS"
|
|||||||
description: ""
|
description: ""
|
||||||
---
|
---
|
||||||
|
|
||||||
```json {filename="config/tweaks.json",linenos=inline,linenostart=2588}
|
```json {filename="config/tweaks.json",linenos=inline,linenostart=2592}
|
||||||
"WPFchangedns": {
|
"WPFchangedns": {
|
||||||
"Content": "DNS",
|
"Content": "DNS",
|
||||||
"category": "z__Advanced Tweaks - CAUTION",
|
"category": "z__Advanced Tweaks - CAUTION",
|
||||||
|
|||||||
@@ -31,9 +31,10 @@ Winutil is designed for:
|
|||||||
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](store/)** - Learn to install software easily
|
2. **[Application Store](application/)** - Learn to install software easily
|
||||||
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
|
||||||
|
|
||||||
## Main Features
|
## Main Features
|
||||||
|
|
||||||
@@ -41,7 +42,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 →](store/)**
|
**[Read the Store Guide →](application/)**
|
||||||
|
|
||||||
### ⚙️ System Tweaks
|
### ⚙️ System Tweaks
|
||||||
|
|
||||||
@@ -79,16 +80,23 @@ Automate Winutil configurations for:
|
|||||||
|
|
||||||
**[Read the Automation Guide →](automation/)**
|
**[Read the Automation Guide →](automation/)**
|
||||||
|
|
||||||
|
### 💿 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.
|
||||||
|
|
||||||
|
**[Read the Win11 Creator Guide →](win11Creator/)**
|
||||||
|
|
||||||
## Quick Links
|
## Quick Links
|
||||||
|
|
||||||
| 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](store/) |
|
| Install applications quickly | [Application Store](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/) |
|
||||||
| Understand what tweaks do | [Tweaks Guide](tweaks/) |
|
| Understand what tweaks do | [Tweaks Guide](tweaks/) |
|
||||||
|
| Build a custom Windows 11 ISO | [Win11 Creator](win11Creator/) |
|
||||||
|
|
||||||
## Safety and Best Practices
|
## Safety and Best Practices
|
||||||
|
|
||||||
@@ -143,9 +151,10 @@ 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](store/)** - Installing software, using presets
|
2. **[Application Store](application/)** - Installing software, using presets
|
||||||
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
|
||||||
6. **[Updates](updates/)** - Managing Windows Update behavior
|
6. **[Updates](updates/)** - Managing Windows Update behavior
|
||||||
7. **[Automation](automation/)** - Scripting and batch deployments
|
7. **[Automation](automation/)** - Scripting and batch deployments
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Store
|
title: Applications
|
||||||
weight: 2
|
weight: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: Getting Started with Winutil
|
title: Getting Started
|
||||||
weight: 1
|
weight: 1
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@ 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](../store/) - Learn about installing software
|
- [Application Installation Guide](../application/) - Learn about installing 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
|
||||||
|
|
||||||
153
docs/content/userguide/win11Creator/_index.md
Normal file
153
docs/content/userguide/win11Creator/_index.md
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
---
|
||||||
|
title: Win 11 Creator
|
||||||
|
weight: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
> [!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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 1 — Select Your ISO
|
||||||
|
|
||||||
|
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).
|
||||||
|
3. The file path and size will appear on screen once selected.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 2 — Mount & Verify
|
||||||
|
|
||||||
|
1. Click **Mount & Verify ISO**.
|
||||||
|
2. Winutil mounts the ISO, checks for a valid `install.wim` or `install.esd`, and reads the available editions (Home, Pro, Enterprise, etc.).
|
||||||
|
3. Once verified, select your desired **edition** from the dropdown — Pro is selected by default if available.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This step takes around 10–30 seconds depending on your drive speed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 3 — Run the Modification
|
||||||
|
|
||||||
|
Click **Run Windows ISO Modification and Creator** to start the customization process. Winutil will:
|
||||||
|
|
||||||
|
- **Remove 40+ bloat apps** — Clipchamp, Teams, Copilot, Dev Home, new Outlook, Bing apps, Solitaire, and more
|
||||||
|
- **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
|
||||||
|
- **Enable local account setup** — injects an `autounattend.xml` that skips the Microsoft account screen during OOBE
|
||||||
|
- **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
|
||||||
|
- **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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 4 — Export Your Result
|
||||||
|
|
||||||
|
Once modification is complete, choose how to save your image:
|
||||||
|
|
||||||
|
{{< tabs items="Save as ISO,Write to USB" defaultIndex="0" >}}
|
||||||
|
|
||||||
|
{{< tab >}}
|
||||||
|
1. Click **Save as an ISO File**.
|
||||||
|
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`.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `oscdimg.exe` (part of the Windows ADK) is required. If it's not found, Winutil will attempt to install it automatically via winget. If that fails, install it manually: `winget install -e --id Microsoft.OSCDIMG`
|
||||||
|
|
||||||
|
**Typical output size:** 2.5–3.5 GB (down from 5–6 GB original)
|
||||||
|
{{< /tab >}}
|
||||||
|
|
||||||
|
{{< tab >}}
|
||||||
|
1. Click **Write Directly to a USB Drive**.
|
||||||
|
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**.
|
||||||
|
4. Winutil formats the drive as GPT with a 512 MB EFI partition and copies the modified Windows files.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Double-check you have selected the correct drive before confirming. This operation cannot be undone.
|
||||||
|
|
||||||
|
**Minimum USB size:** 8 GB recommended. Writing takes 10–20 minutes.
|
||||||
|
{{< /tab >}}
|
||||||
|
|
||||||
|
{{< /tabs >}}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### What the Modified ISO Does Differently
|
||||||
|
|
||||||
|
When you install Windows 11 from your modified ISO:
|
||||||
|
|
||||||
|
- **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
|
||||||
|
- **Dark mode enabled by default**
|
||||||
|
- **Empty taskbar and Start Menu** — no pinned apps
|
||||||
|
- **Windows Update re-enabled automatically** after first login (it's paused during OOBE to prevent interruption)
|
||||||
|
- **BitLocker disabled**, Recall disabled, desktop shortcuts removed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
|
||||||
|
| Problem | Fix |
|
||||||
|
|---------|-----|
|
||||||
|
| "install.wim not found" | Not a valid Windows 11 ISO — download a fresh one from Microsoft |
|
||||||
|
| "oscdimg.exe not found" | Run `winget install -e --id Microsoft.OSCDIMG` then retry |
|
||||||
|
| USB drive not showing up | Plug it in, wait a few seconds, then click **Refresh** |
|
||||||
|
| Modification seems stuck | The WIM dismount step is slow — wait at least 10 minutes before assuming it's frozen |
|
||||||
|
| "Access Denied" error | Make sure Winutil is running as Administrator |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
A list of the best free and open source tools for downloading, creating and flashing Windows ISOs.
|
||||||
|
|
||||||
|
## Download Windows ISOs
|
||||||
|
|
||||||
|
| 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/) |
|
||||||
|
| **[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) |
|
||||||
|
|
||||||
|
|
||||||
|
## Customize Windows ISOs
|
||||||
|
|
||||||
|
| Tool | Description | Website |
|
||||||
|
|------|-------------|---------|
|
||||||
|
| **[MicroWin](https://github.com/CodingWonders/microwin)** | A C# desktop app for building stripped-down, customized Windows ISOs — the original predecessor to Winutil's old MicroWin feature | [github.com](https://github.com/CodingWonders/microwin) |
|
||||||
|
| **[Tiny11 Builder](https://github.com/ntdevlabs/tiny11builder)** | PowerShell script that strips a Windows 11 ISO down to the bare minimum — removes bloatware and bypasses hardware requirements | [github.com](https://github.com/ntdevlabs/tiny11builder) |
|
||||||
|
| **[NTLite](https://www.ntlite.com/)** | Remove Windows components, integrate drivers and updates, and build a custom ISO before installation | [ntlite.com](https://www.ntlite.com/) |
|
||||||
|
|
||||||
|
|
||||||
|
## Flash ISOs to USB
|
||||||
|
|
||||||
|
| Tool | Description | Website |
|
||||||
|
|------|-------------|---------|
|
||||||
|
| **[Rufus](https://rufus.ie/)** | The go-to tool for creating bootable Windows USB drives. Supports bypassing Windows 11 TPM/Secure Boot requirements and downloading ISOs directly | [rufus.ie](https://rufus.ie/) |
|
||||||
|
| **[Ventoy](https://www.ventoy.net/)** | Install once, then just copy any ISO files onto the USB — supports booting multiple ISOs from a single drive without re-flashing | [ventoy.net](https://www.ventoy.net/) |
|
||||||
|
| **[balenaEtcher](https://etcher.balena.io/)** | Simple, beginner-friendly ISO flasher with a clean interface | [etcher.balena.io](https://etcher.balena.io/) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> [!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.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Always download Windows ISOs from official Microsoft sources or trusted tools like Rufus/UUP Dump to avoid tampered images.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Newer Windows 11 ISOs may not boot correctly on older versions of Ventoy — make sure Ventoy is up to date before use. If issues persist after updating, this is a Ventoy compatibility limitation outside of Winutil's control.
|
||||||
@@ -15,9 +15,9 @@ function Get-WinUtilSelectedPackages
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ($PackageList.count -eq 1) {
|
if ($PackageList.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
|
|
||||||
$packages = [System.Collections.Hashtable]::new()
|
$packages = [System.Collections.Hashtable]::new()
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ function Hide-WPFInstallAppBusy {
|
|||||||
Hides the busy overlay in the install app area of the WPF form.
|
Hides the busy overlay in the install app area of the WPF form.
|
||||||
This is used to indicate that an install or uninstall has finished.
|
This is used to indicate that an install or uninstall has finished.
|
||||||
#>
|
#>
|
||||||
$sync.form.Dispatcher.Invoke([action]{
|
Invoke-WPFUIThread -ScriptBlock {
|
||||||
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed
|
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed
|
||||||
$sync.InstallAppAreaBorder.IsEnabled = $true
|
$sync.InstallAppAreaBorder.IsEnabled = $true
|
||||||
$sync.InstallAppAreaScrollViewer.Effect.Radius = 0
|
$sync.InstallAppAreaScrollViewer.Effect.Radius = 0
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ function Install-WinUtilProgramChoco {
|
|||||||
[int]$totalPrograms
|
[int]$totalPrograms
|
||||||
)
|
)
|
||||||
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
|
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) }
|
||||||
}
|
}
|
||||||
|
|
||||||
function Install-ChocoPackage {
|
function Install-ChocoPackage {
|
||||||
@@ -234,7 +234,7 @@ function Install-WinUtilProgramChoco {
|
|||||||
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
|
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
|
||||||
$Program = $Programs[$currentIndex]
|
$Program = $Programs[$currentIndex]
|
||||||
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
|
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)})
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)}
|
||||||
|
|
||||||
switch ($Action) {
|
switch ($Action) {
|
||||||
"Install" {
|
"Install" {
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ Function Install-WinUtilProgramWinget {
|
|||||||
$Program = $Programs[$i]
|
$Program = $Programs[$i]
|
||||||
$result = $false
|
$result = $false
|
||||||
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100)
|
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100)
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i / $count)})
|
Invoke-WPFUIThread -ScriptBlock{ Set-WinUtilTaskbaritem -value ($i / $count)}
|
||||||
|
|
||||||
$result = switch ($Action) {
|
$result = switch ($Action) {
|
||||||
"Install" {Invoke-Install -Program $Program}
|
"Install" {Invoke-Install -Program $Program}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function Invoke-WinUtilExplorerUpdate {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ($action -eq "refresh") {
|
if ($action -eq "refresh") {
|
||||||
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ScriptBlock {
|
||||||
# Define the Win32 type only if it doesn't exist
|
# Define the Win32 type only if it doesn't exist
|
||||||
if (-not ([System.Management.Automation.PSTypeName]'Win32').Type) {
|
if (-not ([System.Management.Automation.PSTypeName]'Win32').Type) {
|
||||||
Add-Type -TypeDefinition @"
|
Add-Type -TypeDefinition @"
|
||||||
|
|||||||
@@ -10,46 +10,40 @@ function Invoke-WinUtilFeatureInstall {
|
|||||||
$CheckBox
|
$CheckBox
|
||||||
)
|
)
|
||||||
|
|
||||||
$x = 0
|
if($sync.configs.feature.$CheckBox.feature) {
|
||||||
|
Foreach( $feature in $sync.configs.feature.$CheckBox.feature ) {
|
||||||
$CheckBox | ForEach-Object {
|
|
||||||
if($sync.configs.feature.$psitem.feature) {
|
|
||||||
Foreach( $feature in $sync.configs.feature.$psitem.feature ) {
|
|
||||||
try {
|
try {
|
||||||
Write-Host "Installing $feature"
|
Write-Host "Installing $feature"
|
||||||
Enable-WindowsOptionalFeature -Online -FeatureName $feature -All -NoRestart
|
Enable-WindowsOptionalFeature -Online -FeatureName $feature -All -NoRestart
|
||||||
} catch {
|
} catch {
|
||||||
if ($psitem.Exception.Message -like "*requires elevation*") {
|
if ($CheckBox.Exception.Message -like "*requires elevation*") {
|
||||||
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" }
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
Write-Warning "Unable to Install $feature due to unhandled exception"
|
Write-Warning "Unable to Install $feature due to unhandled exception"
|
||||||
Write-Warning $psitem.Exception.StackTrace
|
Write-Warning $CheckBox.Exception.StackTrace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($sync.configs.feature.$psitem.InvokeScript) {
|
if($sync.configs.feature.$CheckBox.InvokeScript) {
|
||||||
Foreach( $script in $sync.configs.feature.$psitem.InvokeScript ) {
|
Foreach( $script in $sync.configs.feature.$CheckBox.InvokeScript ) {
|
||||||
try {
|
try {
|
||||||
$Scriptblock = [scriptblock]::Create($script)
|
$Scriptblock = [scriptblock]::Create($script)
|
||||||
|
|
||||||
Write-Host "Running Script for $psitem"
|
Write-Host "Running Script for $CheckBox"
|
||||||
Invoke-Command $scriptblock -ErrorAction stop
|
Invoke-Command $scriptblock -ErrorAction stop
|
||||||
} catch {
|
} catch {
|
||||||
if ($psitem.Exception.Message -like "*requires elevation*") {
|
if ($CheckBox.Exception.Message -like "*requires elevation*") {
|
||||||
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
Write-Warning "Unable to Install $feature due to permissions. Are you running as admin?"
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" }
|
||||||
Write-Warning "Unable to Install $feature due to unhandled exception"
|
Write-Warning "Unable to Install $feature due to unhandled exception"
|
||||||
Write-Warning $psitem.Exception.StackTrace
|
Write-Warning $CheckBox.Exception.StackTrace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$X++
|
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
function Invoke-WinUtilGPU {
|
|
||||||
$gpuInfo = Get-CimInstance Win32_VideoController
|
|
||||||
|
|
||||||
# GPUs to blacklist from using Demanding Theming
|
|
||||||
$lowPowerGPUs = (
|
|
||||||
"*NVIDIA GeForce*M*",
|
|
||||||
"*NVIDIA GeForce*Laptop*",
|
|
||||||
"*NVIDIA GeForce*GT*",
|
|
||||||
"*AMD Radeon(TM)*",
|
|
||||||
"*Intel(R) HD Graphics*",
|
|
||||||
"*UHD*"
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($gpu in $gpuInfo) {
|
|
||||||
foreach ($gpuPattern in $lowPowerGPUs) {
|
|
||||||
if ($gpu.Name -like $gpuPattern) {
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
818
functions/private/Invoke-WinUtilISO.ps1
Normal file
818
functions/private/Invoke-WinUtilISO.ps1
Normal file
@@ -0,0 +1,818 @@
|
|||||||
|
function Write-Win11ISOLog {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Appends a timestamped message to the Win11ISO status log TextBox.
|
||||||
|
.PARAMETER Message
|
||||||
|
The message to append.
|
||||||
|
#>
|
||||||
|
param([string]$Message)
|
||||||
|
$timestamp = (Get-Date).ToString("HH:mm:ss")
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$current = $sync["WPFWin11ISOStatusLog"].Text
|
||||||
|
if ($current -eq "Ready. Please select a Windows 11 ISO to begin.") {
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Text = "[$timestamp] $Message"
|
||||||
|
} else {
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Text += "`n[$timestamp] $Message"
|
||||||
|
}
|
||||||
|
$sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length
|
||||||
|
$sync["WPFWin11ISOStatusLog"].ScrollToEnd()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
$dlg = [System.Windows.Forms.OpenFileDialog]::new()
|
||||||
|
$dlg.Title = "Select Windows 11 ISO"
|
||||||
|
$dlg.Filter = "ISO files (*.iso)|*.iso|All files (*.*)|*.*"
|
||||||
|
$dlg.InitialDirectory = [System.Environment]::GetFolderPath("Desktop")
|
||||||
|
|
||||||
|
if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return }
|
||||||
|
|
||||||
|
$isoPath = $dlg.FileName
|
||||||
|
|
||||||
|
# ── Basic size sanity-check (a Win11 ISO is typically > 4 GB) ──
|
||||||
|
$fileSizeGB = [math]::Round((Get-Item $isoPath).Length / 1GB, 2)
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOPath"].Text = $isoPath
|
||||||
|
$sync["WPFWin11ISOFileInfo"].Text = "File size: $fileSizeGB GB"
|
||||||
|
$sync["WPFWin11ISOFileInfo"].Visibility = "Visible"
|
||||||
|
|
||||||
|
# Reveal Step 2
|
||||||
|
$sync["WPFWin11ISOMountSection"].Visibility = "Visible"
|
||||||
|
|
||||||
|
# Collapse all later steps whenever a new ISO is chosen
|
||||||
|
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed"
|
||||||
|
|
||||||
|
Write-Win11ISOLog "ISO selected: $isoPath ($fileSizeGB GB)"
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($isoPath) -or $isoPath -eq "No ISO selected...") {
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"Please select an ISO file first.",
|
||||||
|
"No ISO Selected", "OK", "Warning")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Win11ISOLog "Mounting ISO: $isoPath"
|
||||||
|
Set-WinUtilProgressBar -Label "Mounting ISO..." -Percent 10
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Mount the ISO
|
||||||
|
$diskImage = Mount-DiskImage -ImagePath $isoPath -PassThru -ErrorAction Stop
|
||||||
|
$driveLetter = ($diskImage | Get-Volume).DriveLetter + ":"
|
||||||
|
Write-Win11ISOLog "Mounted at drive $driveLetter"
|
||||||
|
|
||||||
|
Set-WinUtilProgressBar -Label "Verifying ISO contents..." -Percent 30
|
||||||
|
|
||||||
|
# ── Verify install.wim / install.esd presence ──
|
||||||
|
$wimPath = Join-Path $driveLetter "sources\install.wim"
|
||||||
|
$esdPath = Join-Path $driveLetter "sources\install.esd"
|
||||||
|
|
||||||
|
if (-not (Test-Path $wimPath) -and -not (Test-Path $esdPath)) {
|
||||||
|
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
||||||
|
Write-Win11ISOLog "ERROR: install.wim/install.esd not found — not a valid Windows ISO."
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"This does not appear to be a valid Windows ISO.`n`ninstall.wim / install.esd was not found.",
|
||||||
|
"Invalid ISO", "OK", "Error")
|
||||||
|
Set-WinUtilProgressBar -Label "" -Percent 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$activeWim = if (Test-Path $wimPath) { $wimPath } else { $esdPath }
|
||||||
|
|
||||||
|
# ── Read edition / architecture info ──
|
||||||
|
Set-WinUtilProgressBar -Label "Reading image metadata..." -Percent 55
|
||||||
|
|
||||||
|
$imageInfo = Get-WindowsImage -ImagePath $activeWim | Select-Object ImageIndex, ImageName
|
||||||
|
|
||||||
|
# ── Verify at least one Win11 edition is present ──
|
||||||
|
$isWin11 = $imageInfo | Where-Object { $_.ImageName -match "Windows 11" }
|
||||||
|
if (-not $isWin11) {
|
||||||
|
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
||||||
|
Write-Win11ISOLog "ERROR: No 'Windows 11' edition found in the image."
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"No Windows 11 edition was found in this ISO.`n`nOnly official Windows 11 ISOs are supported.",
|
||||||
|
"Not a Windows 11 ISO", "OK", "Error")
|
||||||
|
Set-WinUtilProgressBar -Label "" -Percent 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Store edition info for later index lookup
|
||||||
|
$sync["Win11ISOImageInfo"] = $imageInfo
|
||||||
|
|
||||||
|
# ── Populate UI ──
|
||||||
|
$sync["WPFWin11ISOMountDriveLetter"].Text = "Mounted at: $driveLetter | Image file: $(Split-Path $activeWim -Leaf)"
|
||||||
|
$sync["WPFWin11ISOEditionComboBox"].Dispatcher.Invoke([action]{
|
||||||
|
$sync["WPFWin11ISOEditionComboBox"].Items.Clear()
|
||||||
|
foreach ($img in $imageInfo) {
|
||||||
|
[void]$sync["WPFWin11ISOEditionComboBox"].Items.Add("$($img.ImageIndex): $($img.ImageName)")
|
||||||
|
}
|
||||||
|
if ($sync["WPFWin11ISOEditionComboBox"].Items.Count -gt 0) {
|
||||||
|
# Default to Windows 11 Pro; fall back to first item if not found
|
||||||
|
$proIndex = -1
|
||||||
|
for ($i = 0; $i -lt $sync["WPFWin11ISOEditionComboBox"].Items.Count; $i++) {
|
||||||
|
if ($sync["WPFWin11ISOEditionComboBox"].Items[$i] -match "Windows 11 Pro(?![\w ])") {
|
||||||
|
$proIndex = $i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sync["WPFWin11ISOEditionComboBox"].SelectedIndex = if ($proIndex -ge 0) { $proIndex } else { 0 }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Visible"
|
||||||
|
|
||||||
|
# Store for later steps
|
||||||
|
$sync["Win11ISODriveLetter"] = $driveLetter
|
||||||
|
$sync["Win11ISOWimPath"] = $activeWim
|
||||||
|
$sync["Win11ISOImagePath"] = $isoPath
|
||||||
|
|
||||||
|
# Reveal Step 3
|
||||||
|
$sync["WPFWin11ISOModifySection"].Visibility = "Visible"
|
||||||
|
|
||||||
|
Set-WinUtilProgressBar -Label "ISO verified ✔" -Percent 100
|
||||||
|
Write-Win11ISOLog "ISO verified OK. Editions found: $($imageInfo.Count)"
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Win11ISOLog "ERROR during mount/verify: $_"
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"An error occurred while mounting or verifying the ISO:`n`n$_",
|
||||||
|
"Error", "OK", "Error")
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Start-Sleep -Milliseconds 800
|
||||||
|
Set-WinUtilProgressBar -Label "" -Percent 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"]
|
||||||
|
$driveLetter= $sync["Win11ISODriveLetter"]
|
||||||
|
$wimPath = $sync["Win11ISOWimPath"]
|
||||||
|
|
||||||
|
if (-not $isoPath) {
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"No verified ISO found. Please complete Steps 1 and 2 first.",
|
||||||
|
"Not Ready", "OK", "Warning")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Resolve selected edition index from the ComboBox ──
|
||||||
|
$selectedItem = $sync["WPFWin11ISOEditionComboBox"].SelectedItem
|
||||||
|
$selectedWimIndex = 1 # default fallback
|
||||||
|
if ($selectedItem -and $selectedItem -match '^(\d+):') {
|
||||||
|
$selectedWimIndex = [int]$Matches[1]
|
||||||
|
} elseif ($sync["Win11ISOImageInfo"]) {
|
||||||
|
$selectedWimIndex = $sync["Win11ISOImageInfo"][0].ImageIndex
|
||||||
|
}
|
||||||
|
$selectedEditionName = if ($selectedItem) { ($selectedItem -replace '^\d+:\s*', '') } else { "Unknown" }
|
||||||
|
Write-Win11ISOLog "Selected edition: $selectedEditionName (Index $selectedWimIndex)"
|
||||||
|
|
||||||
|
# Disable the modify button to prevent double-click
|
||||||
|
$sync["WPFWin11ISOModifyButton"].IsEnabled = $false
|
||||||
|
|
||||||
|
$existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.PSIsContainer } |
|
||||||
|
Sort-Object LastWriteTime -Descending |
|
||||||
|
Select-Object -First 1
|
||||||
|
|
||||||
|
$workDir = if ($existingWorkDir) {
|
||||||
|
Write-Win11ISOLog "Reusing existing temp directory: $($existingWorkDir.FullName)"
|
||||||
|
$existingWorkDir.FullName
|
||||||
|
} else {
|
||||||
|
Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── 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) {
|
||||||
|
$WinUtilAutounattendXml
|
||||||
|
} else {
|
||||||
|
$toolsXml = Join-Path $PSScriptRoot "..\..\tools\autounattend.xml"
|
||||||
|
if (Test-Path $toolsXml) { Get-Content $toolsXml -Raw } else { "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Run modification in a background runspace ──
|
||||||
|
$runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
|
||||||
|
$runspace.ApartmentState = "STA"
|
||||||
|
$runspace.ThreadOptions = "ReuseThread"
|
||||||
|
$runspace.Open()
|
||||||
|
$runspace.SessionStateProxy.SetVariable("sync", $sync)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("isoPath", $isoPath)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("driveLetter", $driveLetter)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("wimPath", $wimPath)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("workDir", $workDir)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("selectedWimIndex", $selectedWimIndex)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("selectedEditionName", $selectedEditionName)
|
||||||
|
$runspace.SessionStateProxy.SetVariable("autounattendContent", $autounattendContent)
|
||||||
|
|
||||||
|
# Serialize functions so they are available inside the runspace
|
||||||
|
$isoScriptFuncDef = "function Invoke-WinUtilISOScript {`n" + `
|
||||||
|
${function:Invoke-WinUtilISOScript}.ToString() + "`n}"
|
||||||
|
$runspace.SessionStateProxy.SetVariable("isoScriptFuncDef", $isoScriptFuncDef)
|
||||||
|
|
||||||
|
$win11ISOLogFuncDef = "function Write-Win11ISOLog {`n" + `
|
||||||
|
${function:Write-Win11ISOLog}.ToString() + "`n}"
|
||||||
|
$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.Runspace = $runspace
|
||||||
|
$script.AddScript({
|
||||||
|
|
||||||
|
# Import helper functions into this runspace
|
||||||
|
. ([scriptblock]::Create($isoScriptFuncDef))
|
||||||
|
. ([scriptblock]::Create($win11ISOLogFuncDef))
|
||||||
|
. ([scriptblock]::Create($refreshUSBFuncDef))
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
# ── Hide Steps 1-3 while modification is running; expand log to fill screen ──
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOMountSection"].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"
|
||||||
|
$isoContents = Join-Path $workDir "iso_contents"
|
||||||
|
$mountDir = Join-Path $workDir "wim_mount"
|
||||||
|
New-Item -ItemType Directory -Path $isoContents, $mountDir -Force | Out-Null
|
||||||
|
SetProgress "Copying ISO contents..." 10
|
||||||
|
|
||||||
|
# ── 2. Copy all ISO contents to the working directory ──
|
||||||
|
Log "Copying ISO contents from $driveLetter to $isoContents..."
|
||||||
|
$robocopyArgs = @($driveLetter, $isoContents, "/E", "/NFL", "/NDL", "/NJH", "/NJS")
|
||||||
|
& robocopy @robocopyArgs | Out-Null
|
||||||
|
Log "ISO contents copied."
|
||||||
|
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"
|
||||||
|
if (-not (Test-Path $localWim)) {
|
||||||
|
# ESD path
|
||||||
|
$localWim = Join-Path $isoContents "sources\install.esd"
|
||||||
|
}
|
||||||
|
# Ensure the file is writable
|
||||||
|
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..."
|
||||||
|
Mount-WindowsImage -ImagePath $localWim -Index $selectedWimIndex -Path $mountDir -ErrorAction Stop | Out-Null
|
||||||
|
SetProgress "Modifying install.wim..." 45
|
||||||
|
|
||||||
|
# ── Apply all WinUtil modifications via Invoke-WinUtilISOScript ──
|
||||||
|
Log "Applying WinUtil modifications to install.wim..."
|
||||||
|
Invoke-WinUtilISOScript -ScratchDir $mountDir -ISOContentsDir $isoContents -AutoUnattendXml $autounattendContent -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
|
||||||
|
Log "Running DISM component store cleanup (/ResetBase)..."
|
||||||
|
& dism /English "/image:$mountDir" /Cleanup-Image /StartComponentCleanup /ResetBase | ForEach-Object { Log $_ }
|
||||||
|
Log "Component store cleanup complete."
|
||||||
|
|
||||||
|
# ── 5. Save and dismount the WIM ──
|
||||||
|
SetProgress "Saving modified install.wim..." 65
|
||||||
|
Log "Dismounting and saving install.wim. This will take several minutes..."
|
||||||
|
Dismount-WindowsImage -Path $mountDir -Save -ErrorAction Stop | Out-Null
|
||||||
|
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
|
||||||
|
Log "Exporting edition '$selectedEditionName' (Index $selectedWimIndex) to a single-edition install.wim..."
|
||||||
|
$exportWim = Join-Path $isoContents "sources\install_export.wim"
|
||||||
|
Export-WindowsImage `
|
||||||
|
-SourceImagePath $localWim `
|
||||||
|
-SourceIndex $selectedWimIndex `
|
||||||
|
-DestinationImagePath $exportWim `
|
||||||
|
-ErrorAction Stop | Out-Null
|
||||||
|
Remove-Item -Path $localWim -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"
|
||||||
|
Log "Unused editions removed. install.wim now contains only '$selectedEditionName'."
|
||||||
|
|
||||||
|
SetProgress "Dismounting source ISO..." 80
|
||||||
|
|
||||||
|
# ── 6. Dismount the original ISO ──
|
||||||
|
Log "Dismounting original ISO..."
|
||||||
|
Dismount-DiskImage -ImagePath $isoPath | Out-Null
|
||||||
|
|
||||||
|
# Store work directory for output steps
|
||||||
|
$sync["Win11ISOWorkDir"] = $workDir
|
||||||
|
$sync["Win11ISOContentsDir"] = $isoContents
|
||||||
|
|
||||||
|
SetProgress "Modification complete ✔" 100
|
||||||
|
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"].Visibility = "Visible"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Log "ERROR during modification: $_"
|
||||||
|
|
||||||
|
# ── Cleanup: dismount WIM if still mounted ──
|
||||||
|
try {
|
||||||
|
if (Test-Path $mountDir) {
|
||||||
|
$mountedImages = Get-WindowsImage -Mounted -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.Path -eq $mountDir }
|
||||||
|
if ($mountedImages) {
|
||||||
|
Log "Cleaning up: dismounting install.wim (discarding changes)..."
|
||||||
|
Dismount-WindowsImage -Path $mountDir -Discard -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Log "Warning: could not dismount install.wim during cleanup: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Cleanup: dismount the source ISO ──
|
||||||
|
try {
|
||||||
|
$mountedISO = Get-DiskImage -ImagePath $isoPath -ErrorAction SilentlyContinue
|
||||||
|
if ($mountedISO -and $mountedISO.Attached) {
|
||||||
|
Log "Cleaning up: dismounting source ISO..."
|
||||||
|
Dismount-DiskImage -ImagePath $isoPath -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Log "Warning: could not dismount ISO during cleanup: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Cleanup: remove temp working directory ──
|
||||||
|
try {
|
||||||
|
if (Test-Path $workDir) {
|
||||||
|
Log "Cleaning up: removing temp directory $workDir..."
|
||||||
|
Remove-Item -Path $workDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Log "Warning: could not remove temp directory during cleanup: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"An error occurred during install.wim modification:`n`n$_",
|
||||||
|
"Modification Error", "OK", "Error")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Start-Sleep -Milliseconds 800
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{
|
||||||
|
$sync.progressBarTextBlock.Text = ""
|
||||||
|
$sync.progressBarTextBlock.ToolTip = ""
|
||||||
|
$sync.ProgressBar.Value = 0
|
||||||
|
$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") {
|
||||||
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
|
||||||
|
$sync["WPFWin11ISOMountSection"].Visibility = "Visible"
|
||||||
|
$sync["WPFWin11ISOModifySection"].Visibility = "Visible"
|
||||||
|
}
|
||||||
|
$sync["Win11ISOLogExpanded"] = $false
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Height = 140
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}) | Out-Null
|
||||||
|
|
||||||
|
$script.BeginInvoke() | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Invoke-WinUtilISOCleanAndReset {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Deletes the temporary working directory created during ISO modification
|
||||||
|
and resets the entire ISO UI back to its initial state (Step 1 only).
|
||||||
|
#>
|
||||||
|
|
||||||
|
$workDir = $sync["Win11ISOWorkDir"]
|
||||||
|
|
||||||
|
if ($workDir -and (Test-Path $workDir)) {
|
||||||
|
$confirm = [System.Windows.MessageBox]::Show(
|
||||||
|
"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")
|
||||||
|
if ($confirm -ne "Yes") { return }
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Win11ISOLog "Deleting temp directory: $workDir"
|
||||||
|
Remove-Item -Path $workDir -Recurse -Force -ErrorAction Stop
|
||||||
|
Write-Win11ISOLog "Temp directory deleted."
|
||||||
|
} catch {
|
||||||
|
Write-Win11ISOLog "WARNING: could not fully delete temp directory: $_"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clear all stored ISO state
|
||||||
|
$sync["Win11ISOWorkDir"] = $null
|
||||||
|
$sync["Win11ISOContentsDir"] = $null
|
||||||
|
$sync["Win11ISOImagePath"] = $null
|
||||||
|
$sync["Win11ISODriveLetter"] = $null
|
||||||
|
$sync["Win11ISOWimPath"] = $null
|
||||||
|
$sync["Win11ISOImageInfo"] = $null
|
||||||
|
$sync["Win11ISOUSBDisks"] = $null
|
||||||
|
|
||||||
|
# Reset the UI to the initial state
|
||||||
|
$sync["WPFWin11ISOPath"].Text = "No ISO selected..."
|
||||||
|
$sync["WPFWin11ISOFileInfo"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOOptionUSB"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOModifySection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOMountSection"].Visibility = "Collapsed"
|
||||||
|
$sync["WPFWin11ISOSelectSection"].Visibility = "Visible"
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin."
|
||||||
|
$sync["WPFWin11ISOStatusLog"].Height = 140
|
||||||
|
$sync["WPFWin11ISOModifyButton"].IsEnabled = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
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"]
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
|
||||||
|
$dlg = [System.Windows.Forms.SaveFileDialog]::new()
|
||||||
|
$dlg.Title = "Save Modified Windows 11 ISO"
|
||||||
|
$dlg.Filter = "ISO files (*.iso)|*.iso"
|
||||||
|
$dlg.FileName = "Win11_Modified_$(Get-Date -Format 'yyyyMMdd').iso"
|
||||||
|
$dlg.InitialDirectory = [System.Environment]::GetFolderPath("Desktop")
|
||||||
|
|
||||||
|
if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return }
|
||||||
|
|
||||||
|
$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)
|
||||||
|
$oscdimg = Get-ChildItem "C:\Program Files (x86)\Windows Kits" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
||||||
|
Select-Object -First 1 -ExpandProperty FullName
|
||||||
|
if (-not $oscdimg) {
|
||||||
|
$oscdimg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.FullName -match 'Microsoft\.OSCDIMG' } |
|
||||||
|
Select-Object -First 1 -ExpandProperty FullName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $oscdimg) {
|
||||||
|
Write-Win11ISOLog "oscdimg.exe not found. Attempting to install via winget..."
|
||||||
|
Set-WinUtilProgressBar -Label "Installing oscdimg..." -Percent 5
|
||||||
|
try {
|
||||||
|
$winget = Get-Command winget -ErrorAction Stop
|
||||||
|
$result = & $winget install -e --id Microsoft.OSCDIMG --accept-package-agreements --accept-source-agreements 2>&1
|
||||||
|
Write-Win11ISOLog "winget output: $result"
|
||||||
|
# Re-scan after install
|
||||||
|
$oscdimg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Recurse -Filter "oscdimg.exe" -ErrorAction SilentlyContinue |
|
||||||
|
Where-Object { $_.FullName -match 'Microsoft\.OSCDIMG' } |
|
||||||
|
Select-Object -First 1 -ExpandProperty FullName
|
||||||
|
} catch {
|
||||||
|
Write-Win11ISOLog "winget not available or install failed: $_"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $oscdimg) {
|
||||||
|
Set-WinUtilProgressBar -Label "" -Percent 0
|
||||||
|
Write-Win11ISOLog "oscdimg.exe still not found after install attempt."
|
||||||
|
[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 Not Found", "OK", "Warning")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Write-Win11ISOLog "oscdimg.exe installed successfully."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build boot parameters (BIOS + UEFI dual-boot)
|
||||||
|
$bootData = "2#p0,e,b`"$contentsDir\boot\etfsboot.com`"#pEF,e,b`"$contentsDir\efi\microsoft\boot\efisys.bin`""
|
||||||
|
$oscdimgArgs = @(
|
||||||
|
"-m", # ignore source path max size
|
||||||
|
"-o", # optimise storage
|
||||||
|
"-u2", # UDF 2.01
|
||||||
|
"-udfver102",
|
||||||
|
"-bootdata:$bootData",
|
||||||
|
"-l`"CTOS_MODIFIED`"",
|
||||||
|
"`"$contentsDir`"",
|
||||||
|
"`"$outputISO`""
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Win11ISOLog "Running oscdimg..."
|
||||||
|
$psi = [System.Diagnostics.ProcessStartInfo]::new()
|
||||||
|
$psi.FileName = $oscdimg
|
||||||
|
$psi.Arguments = $oscdimgArgs -join " "
|
||||||
|
$psi.RedirectStandardOutput = $true
|
||||||
|
$psi.RedirectStandardError = $true
|
||||||
|
$psi.UseShellExecute = $false
|
||||||
|
$psi.CreateNoWindow = $true
|
||||||
|
|
||||||
|
$proc = [System.Diagnostics.Process]::new()
|
||||||
|
$proc.StartInfo = $psi
|
||||||
|
$proc.Start() | Out-Null
|
||||||
|
|
||||||
|
# Stream stdout and stderr line-by-line to the status log
|
||||||
|
$stdoutTask = $proc.StandardOutput.ReadToEndAsync()
|
||||||
|
$stderrTask = $proc.StandardError.ReadToEndAsync()
|
||||||
|
$proc.WaitForExit()
|
||||||
|
[System.Threading.Tasks.Task]::WaitAll($stdoutTask, $stderrTask)
|
||||||
|
|
||||||
|
foreach ($line in ($stdoutTask.Result -split "`r?`n")) {
|
||||||
|
if ($line.Trim()) { Write-Win11ISOLog $line }
|
||||||
|
}
|
||||||
|
foreach ($line in ($stderrTask.Result -split "`r?`n")) {
|
||||||
|
if ($line.Trim()) { Write-Win11ISOLog "[stderr]$line" }
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($proc.ExitCode -eq 0) {
|
||||||
|
Set-WinUtilProgressBar -Label "ISO exported ✔" -Percent 100
|
||||||
|
Write-Win11ISOLog "ISO exported successfully: $outputISO"
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"ISO exported successfully!`n`n$outputISO",
|
||||||
|
"Export Complete", "OK", "Info")
|
||||||
|
} else {
|
||||||
|
Write-Win11ISOLog "oscdimg exited with code $($proc.ExitCode)."
|
||||||
|
[System.Windows.MessageBox]::Show(
|
||||||
|
"oscdimg exited with code $($proc.ExitCode).`nCheck the status log for details.",
|
||||||
|
"Export Error", "OK", "Error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
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"].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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
$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
|
||||||
|
}
|
||||||
335
functions/private/Invoke-WinUtilISOScript.ps1
Normal file
335
functions/private/Invoke-WinUtilISOScript.ps1
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
function Invoke-WinUtilISOScript {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Applies WinUtil modifications to a mounted Windows 11 install.wim image.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Performs the following operations against an already-mounted WIM image:
|
||||||
|
|
||||||
|
1. Removes provisioned AppX bloatware packages via DISM.
|
||||||
|
2. Removes OneDriveSetup.exe from the system image.
|
||||||
|
3. Loads offline registry hives (COMPONENTS, DEFAULT, NTUSER, SOFTWARE, SYSTEM)
|
||||||
|
and applies the following tweaks:
|
||||||
|
- 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
|
||||||
|
(e.g. Invoke-WinUtilISO).
|
||||||
|
|
||||||
|
.PARAMETER ScratchDir
|
||||||
|
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
|
||||||
|
Optional. Root directory of the extracted ISO contents.
|
||||||
|
When supplied, autounattend.xml is also written here so Windows Setup picks it
|
||||||
|
up automatically at boot, and the support\ folder is deleted from that location.
|
||||||
|
|
||||||
|
.PARAMETER AutoUnattendXml
|
||||||
|
Optional. Full XML content for autounattend.xml.
|
||||||
|
In compiled winutil.ps1 this is the embedded $WinUtilAutounattendXml here-string;
|
||||||
|
in dev mode it is read from tools\autounattend.xml.
|
||||||
|
If empty, the OOBE bypass file is skipped and a warning is logged.
|
||||||
|
|
||||||
|
.PARAMETER Log
|
||||||
|
Optional ScriptBlock used for progress/status logging.
|
||||||
|
Receives a single [string] message argument.
|
||||||
|
Defaults to { param($m) Write-Output $m } when not supplied.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Invoke-WinUtilISOScript -ScratchDir "C:\Temp\wim_mount"
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Invoke-WinUtilISOScript `
|
||||||
|
-ScratchDir $mountDir `
|
||||||
|
-ISOContentsDir $isoRoot `
|
||||||
|
-AutoUnattendXml (Get-Content .\tools\autounattend.xml -Raw) `
|
||||||
|
-Log { param($m) Write-Host $m }
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
Author : Chris Titus @christitustech
|
||||||
|
GitHub : https://github.com/ChrisTitusTech
|
||||||
|
Version : 26.02.22
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[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 = "",
|
||||||
|
# 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 = "",
|
||||||
|
[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')
|
||||||
|
$adminGroup = $adminSID.Translate([System.Security.Principal.NTAccount])
|
||||||
|
|
||||||
|
# ── Local helpers ─────────────────────────────────────────────────────────
|
||||||
|
function Set-ISOScriptReg {
|
||||||
|
param ([string]$path, [string]$name, [string]$type, [string]$value)
|
||||||
|
try {
|
||||||
|
& reg add $path /v $name /t $type /d $value /f
|
||||||
|
& $Log "Set registry value: $path\$name"
|
||||||
|
} catch {
|
||||||
|
& $Log "Error setting registry value: $_"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Remove-ISOScriptReg {
|
||||||
|
param ([string]$path)
|
||||||
|
try {
|
||||||
|
& reg delete $path /f
|
||||||
|
& $Log "Removed registry key: $path"
|
||||||
|
} catch {
|
||||||
|
& $Log "Error removing registry key: $_"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
# 1. Remove provisioned AppX packages
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
& $Log "Removing provisioned AppX packages..."
|
||||||
|
|
||||||
|
$packages = & dism /English "/image:$ScratchDir" /Get-ProvisionedAppxPackages |
|
||||||
|
ForEach-Object {
|
||||||
|
if ($_ -match 'PackageName : (.*)') { $matches[1] }
|
||||||
|
}
|
||||||
|
|
||||||
|
$packagePrefixes = @(
|
||||||
|
'AppUp.IntelManagementandSecurityStatus',
|
||||||
|
'Clipchamp.Clipchamp',
|
||||||
|
'DolbyLaboratories.DolbyAccess',
|
||||||
|
'DolbyLaboratories.DolbyDigitalPlusDecoderOEM',
|
||||||
|
'Microsoft.BingNews',
|
||||||
|
'Microsoft.BingSearch',
|
||||||
|
'Microsoft.BingWeather',
|
||||||
|
'Microsoft.Copilot',
|
||||||
|
'Microsoft.Windows.CrossDevice',
|
||||||
|
'Microsoft.GetHelp',
|
||||||
|
'Microsoft.Getstarted',
|
||||||
|
'Microsoft.Microsoft3DViewer',
|
||||||
|
'Microsoft.MicrosoftOfficeHub',
|
||||||
|
'Microsoft.MicrosoftSolitaireCollection',
|
||||||
|
'Microsoft.MicrosoftStickyNotes',
|
||||||
|
'Microsoft.MixedReality.Portal',
|
||||||
|
'Microsoft.MSPaint',
|
||||||
|
'Microsoft.Office.OneNote',
|
||||||
|
'Microsoft.OfficePushNotificationUtility',
|
||||||
|
'Microsoft.OutlookForWindows',
|
||||||
|
'Microsoft.Paint',
|
||||||
|
'Microsoft.People',
|
||||||
|
'Microsoft.PowerAutomateDesktop',
|
||||||
|
'Microsoft.SkypeApp',
|
||||||
|
'Microsoft.StartExperiencesApp',
|
||||||
|
'Microsoft.Todos',
|
||||||
|
'Microsoft.Wallet',
|
||||||
|
'Microsoft.Windows.DevHome',
|
||||||
|
'Microsoft.Windows.Copilot',
|
||||||
|
'Microsoft.Windows.Teams',
|
||||||
|
'Microsoft.WindowsAlarms',
|
||||||
|
'Microsoft.WindowsCamera',
|
||||||
|
'microsoft.windowscommunicationsapps',
|
||||||
|
'Microsoft.WindowsFeedbackHub',
|
||||||
|
'Microsoft.WindowsMaps',
|
||||||
|
'Microsoft.WindowsSoundRecorder',
|
||||||
|
'Microsoft.ZuneMusic',
|
||||||
|
'Microsoft.ZuneVideo',
|
||||||
|
'MicrosoftCorporationII.MicrosoftFamily',
|
||||||
|
'MicrosoftCorporationII.QuickAssist',
|
||||||
|
'MSTeams',
|
||||||
|
'MicrosoftTeams'
|
||||||
|
)
|
||||||
|
|
||||||
|
$packagesToRemove = $packages | Where-Object {
|
||||||
|
$pkg = $_
|
||||||
|
$packagePrefixes | Where-Object { $pkg -like "*$_*" }
|
||||||
|
}
|
||||||
|
foreach ($package in $packagesToRemove) {
|
||||||
|
& dism /English "/image:$ScratchDir" /Remove-ProvisionedAppxPackage "/PackageName:$package"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
# 2. Remove OneDrive
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
& $Log "Removing OneDrive..."
|
||||||
|
& takeown /f "$ScratchDir\Windows\System32\OneDriveSetup.exe" | 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
|
||||||
|
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
# 3. Registry tweaks
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
& $Log "Loading offline registry hives..."
|
||||||
|
reg load HKLM\zCOMPONENTS "$ScratchDir\Windows\System32\config\COMPONENTS"
|
||||||
|
reg load HKLM\zDEFAULT "$ScratchDir\Windows\System32\config\default"
|
||||||
|
reg load HKLM\zNTUSER "$ScratchDir\Users\Default\ntuser.dat"
|
||||||
|
reg load HKLM\zSOFTWARE "$ScratchDir\Windows\System32\config\SOFTWARE"
|
||||||
|
reg load HKLM\zSYSTEM "$ScratchDir\Windows\System32\config\SYSTEM"
|
||||||
|
|
||||||
|
& $Log "Bypassing system requirements..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' 'SV1' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' 'SV2' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassCPUCheck' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassRAMCheck' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassSecureBootCheck' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassStorageCheck' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\LabConfig' 'BypassTPMCheck' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\Setup\MoSetup' 'AllowUpgradesWithUnsupportedTPMOrCPU' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Disabling sponsored apps..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'OemPreInstalledAppsEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SilentInstalledAppsEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableWindowsConsumerFeatures' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'ContentDeliveryAllowed' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' 'ConfigureStartPins' 'REG_SZ' '{"pinnedList": [{}]}'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'FeatureManagementEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'PreInstalledAppsEverEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SoftLandingEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContentEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-310093Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338388Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338389Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-338393Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-353694Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SubscribedContent-353696Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' 'SystemPaneSuggestionsEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' 'DisablePushToInstall' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' 'DontOfferThroughWUAU' 'REG_DWORD' '1'
|
||||||
|
Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\Subscriptions'
|
||||||
|
Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\SuggestedApps'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableConsumerAccountStateContent' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' 'DisableCloudOptimizedContent' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Enabling local accounts on OOBE..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' 'BypassNRO' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
if ($AutoUnattendXml) {
|
||||||
|
# ── Place autounattend.xml inside the WIM (Sysprep) ──────────────────
|
||||||
|
$sysprepDest = "$ScratchDir\Windows\System32\Sysprep\autounattend.xml"
|
||||||
|
Set-Content -Path $sysprepDest -Value $AutoUnattendXml -Encoding UTF8 -Force
|
||||||
|
& $Log "Written autounattend.xml to Sysprep directory."
|
||||||
|
|
||||||
|
# ── 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)) {
|
||||||
|
$isoDest = Join-Path $ISOContentsDir "autounattend.xml"
|
||||||
|
Set-Content -Path $isoDest -Value $AutoUnattendXml -Encoding UTF8 -Force
|
||||||
|
& $Log "Written autounattend.xml to ISO root ($isoDest)."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
& $Log "Warning: autounattend.xml content is empty — skipping OOBE bypass file."
|
||||||
|
}
|
||||||
|
|
||||||
|
& $Log "Disabling reserved storage..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' 'ShippedWithReserves' 'REG_DWORD' '0'
|
||||||
|
|
||||||
|
& $Log "Disabling BitLocker device encryption..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' 'PreventDeviceEncryption' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Disabling Chat icon..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' 'ChatIcon' 'REG_DWORD' '3'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' 'TaskbarMn' 'REG_DWORD' '0'
|
||||||
|
|
||||||
|
& $Log "Disabling OneDrive folder backup..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive' 'DisableFileSyncNGSC' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Disabling telemetry..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' 'Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' 'TailoredExperiencesWithDiagnosticDataEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' 'HasAccepted' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' 'Enabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' 'RestrictImplicitInkCollection' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' 'RestrictImplicitTextCollection' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' 'HarvestContacts' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' 'AcceptedPrivacyPolicy' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' 'AllowTelemetry' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' 'Start' 'REG_DWORD' '4'
|
||||||
|
|
||||||
|
& $Log "Preventing installation of DevHome and Outlook..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||||
|
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate'
|
||||||
|
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate'
|
||||||
|
|
||||||
|
& $Log "Disabling Copilot..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' 'TurnOffWindowsCopilot' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' 'HubsSidebarEnabled' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' 'DisableSearchBoxSuggestions' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Disabling Windows Update during OOBE (re-enabled on first logon via FirstLogon.ps1)..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'NoAutoUpdate' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'AUOptions' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' 'UseWUServer' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'DisableWindowsUpdateAccess' 'REG_DWORD' '1'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'WUServer' 'REG_SZ' 'http://localhost:8080'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' 'WUStatusServer' 'REG_SZ' 'http://localhost:8080'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' 'workCompleted' 'REG_DWORD' '1'
|
||||||
|
Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config' 'DODownloadMode' 'REG_DWORD' '0'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\BITS' 'Start' 'REG_DWORD' '4'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' 'Start' 'REG_DWORD' '4'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' 'Start' 'REG_DWORD' '4'
|
||||||
|
Set-ISOScriptReg 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSvc' 'Start' 'REG_DWORD' '4'
|
||||||
|
|
||||||
|
& $Log "Preventing installation of Teams..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' 'DisableInstallation' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Preventing installation of new Outlook..."
|
||||||
|
Set-ISOScriptReg 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' 'PreventRun' 'REG_DWORD' '1'
|
||||||
|
|
||||||
|
& $Log "Unloading offline registry hives..."
|
||||||
|
reg unload HKLM\zCOMPONENTS
|
||||||
|
reg unload HKLM\zDEFAULT
|
||||||
|
reg unload HKLM\zNTUSER
|
||||||
|
reg unload HKLM\zSOFTWARE
|
||||||
|
reg unload HKLM\zSYSTEM
|
||||||
|
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
# 4. Delete scheduled task definition files
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
& $Log "Deleting scheduled task definition files..."
|
||||||
|
$tasksPath = "$ScratchDir\Windows\System32\Tasks"
|
||||||
|
|
||||||
|
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\Application Experience\ProgramDataUpdater" -Force -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item "$tasksPath\Microsoft\Windows\Chkdsk\Proxy" -Force -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item "$tasksPath\Microsoft\Windows\Windows Error Reporting\QueueReporting" -Force -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item "$tasksPath\Microsoft\Windows\InstallService" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item "$tasksPath\Microsoft\Windows\UpdateOrchestrator" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item "$tasksPath\Microsoft\Windows\UpdateAssistant" -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\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
& $Log "Scheduled task files deleted."
|
||||||
|
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
# 5. Remove ISO support folder (fresh-install only; not needed)
|
||||||
|
# ═════════════════════════════════════════════════════════════════════════
|
||||||
|
if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) {
|
||||||
|
& $Log "Removing ISO support\ folder..."
|
||||||
|
Remove-Item -Path (Join-Path $ISOContentsDir "support") -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
& $Log "ISO support\ folder removed."
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,11 +14,15 @@ function Set-WinUtilProgressbar{
|
|||||||
[int]$Percent
|
[int]$Percent
|
||||||
)
|
)
|
||||||
|
|
||||||
$sync.form.Dispatcher.Invoke([action]{$sync.progressBarTextBlock.Text = $label})
|
if($PARAM_NOUI) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{$sync.progressBarTextBlock.ToolTip = $label})
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $label}
|
||||||
|
Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $label}
|
||||||
if ($percent -lt 5 ) {
|
if ($percent -lt 5 ) {
|
||||||
$percent = 5 # Ensure the progress bar is not empty, as it looks weird
|
$percent = 5 # Ensure the progress bar is not empty, as it looks weird
|
||||||
}
|
}
|
||||||
$sync.form.Dispatcher.Invoke([action]{ $sync.ProgressBar.Value = $percent})
|
Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $percent}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ function Show-WPFInstallAppBusy {
|
|||||||
param (
|
param (
|
||||||
$text = "Installing apps..."
|
$text = "Installing apps..."
|
||||||
)
|
)
|
||||||
$sync.form.Dispatcher.Invoke([action]{
|
Invoke-WPFUIThread -ScriptBlock {
|
||||||
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
|
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible
|
||||||
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
$sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
||||||
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
$sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4)
|
||||||
$sync.InstallAppAreaOverlayText.Text = $text
|
$sync.InstallAppAreaOverlayText.Text = $text
|
||||||
$sync.InstallAppAreaBorder.IsEnabled = $false
|
$sync.InstallAppAreaBorder.IsEnabled = $false
|
||||||
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
|
$sync.InstallAppAreaScrollViewer.Effect.Radius = 5
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,6 +18,31 @@ function Invoke-WPFButton {
|
|||||||
Set-WinUtilProgressBar -label "" -percent 0
|
Set-WinUtilProgressBar -label "" -percent 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if button is defined in feature config with function or InvokeScript
|
||||||
|
if ($sync.configs.feature.$Button) {
|
||||||
|
$buttonConfig = $sync.configs.feature.$Button
|
||||||
|
|
||||||
|
# If button has a function defined, call it
|
||||||
|
if ($buttonConfig.function) {
|
||||||
|
$functionName = $buttonConfig.function
|
||||||
|
if (Get-Command $functionName -ErrorAction SilentlyContinue) {
|
||||||
|
& $functionName
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# If button has InvokeScript defined, execute the scripts
|
||||||
|
if ($buttonConfig.InvokeScript -and $buttonConfig.InvokeScript.Count -gt 0) {
|
||||||
|
foreach ($script in $buttonConfig.InvokeScript) {
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($script)) {
|
||||||
|
Invoke-Expression $script
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fallback to hard-coded switch for buttons not in feature.json
|
||||||
Switch -Wildcard ($Button) {
|
Switch -Wildcard ($Button) {
|
||||||
"WPFTab?BT" {Invoke-WPFTab $Button}
|
"WPFTab?BT" {Invoke-WPFTab $Button}
|
||||||
"WPFInstall" {Invoke-WPFInstall}
|
"WPFInstall" {Invoke-WPFInstall}
|
||||||
@@ -34,34 +59,14 @@ function Invoke-WPFButton {
|
|||||||
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
||||||
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
||||||
"WPFundoall" {Invoke-WPFundoall}
|
"WPFundoall" {Invoke-WPFundoall}
|
||||||
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
|
|
||||||
"WPFPanelDISM" {Invoke-WPFSystemRepair}
|
|
||||||
"WPFPanelAutologin" {Invoke-WPFPanelAutologin}
|
|
||||||
"WPFPanelComputer" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelControl" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelNetwork" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelPower" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelPrinter" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelRegion" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelRestore" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelSound" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelSystem" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelTimedate" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFPanelUser" {Invoke-WPFControlPanel -Panel $button}
|
|
||||||
"WPFUpdatesdefault" {Invoke-WPFUpdatesdefault}
|
"WPFUpdatesdefault" {Invoke-WPFUpdatesdefault}
|
||||||
"WPFFixesUpdate" {Invoke-WPFFixesUpdate}
|
|
||||||
"WPFFixesWinget" {Invoke-WPFFixesWinget}
|
|
||||||
"WPFRunAdobeCCCleanerTool" {Invoke-WPFRunAdobeCCCleanerTool}
|
"WPFRunAdobeCCCleanerTool" {Invoke-WPFRunAdobeCCCleanerTool}
|
||||||
"WPFFixesNetwork" {Invoke-WPFFixesNetwork}
|
|
||||||
"WPFUpdatesdisable" {Invoke-WPFUpdatesdisable}
|
"WPFUpdatesdisable" {Invoke-WPFUpdatesdisable}
|
||||||
"WPFUpdatessecurity" {Invoke-WPFUpdatessecurity}
|
"WPFUpdatessecurity" {Invoke-WPFUpdatessecurity}
|
||||||
"WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
|
"WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
|
||||||
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
|
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
|
||||||
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
|
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
|
||||||
"WPFCloseButton" {Invoke-WPFCloseButton}
|
"WPFCloseButton" {$sync.Form.Close(); Write-Host "Bye bye!"}
|
||||||
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
|
|
||||||
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
|
|
||||||
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
|
|
||||||
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
|
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
|
||||||
"WPFToggleFOSSHighlight" {
|
"WPFToggleFOSSHighlight" {
|
||||||
if ($sync.WPFToggleFOSSHighlight.IsChecked) {
|
if ($sync.WPFToggleFOSSHighlight.IsChecked) {
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
function Invoke-WPFCloseButton {
|
|
||||||
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Close application
|
|
||||||
|
|
||||||
.PARAMETER Button
|
|
||||||
#>
|
|
||||||
$sync["Form"].Close()
|
|
||||||
Write-Host "Bye bye!"
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
function Invoke-WPFControlPanel {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Opens the requested legacy panel
|
|
||||||
|
|
||||||
.PARAMETER Panel
|
|
||||||
The panel to open
|
|
||||||
|
|
||||||
#>
|
|
||||||
param($Panel)
|
|
||||||
|
|
||||||
switch ($Panel) {
|
|
||||||
"WPFPanelControl" {control}
|
|
||||||
"WPFPanelComputer" {compmgmt.msc}
|
|
||||||
"WPFPanelNetwork" {ncpa.cpl}
|
|
||||||
"WPFPanelPower" {powercfg.cpl}
|
|
||||||
"WPFPanelPrinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
|
|
||||||
"WPFPanelRegion" {intl.cpl}
|
|
||||||
"WPFPanelRestore" {rstrui.exe}
|
|
||||||
"WPFPanelSound" {mmsys.cpl}
|
|
||||||
"WPFPanelSystem" {sysdm.cpl}
|
|
||||||
"WPFPanelTimedate" {timedate.cpl}
|
|
||||||
"WPFPanelUser" {control userpasswords2}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,21 +12,25 @@ function Invoke-WPFFeatureInstall {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$handle = Invoke-WPFRunspace -ScriptBlock {
|
||||||
$Features = $sync.selectedFeatures
|
$Features = $sync.selectedFeatures
|
||||||
|
|
||||||
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
|
|
||||||
param($Features, $DebugPreference)
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
if ($Features.count -eq 1) {
|
if ($Features.count -eq 1) {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }
|
||||||
} else {
|
} else {
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke-WinUtilFeatureInstall $Features
|
$x = 0
|
||||||
|
|
||||||
|
$Features | ForEach-Object {
|
||||||
|
Invoke-WinUtilFeatureInstall $Feature
|
||||||
|
$X++
|
||||||
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) }
|
||||||
|
}
|
||||||
|
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
|
|
||||||
Write-Host "==================================="
|
Write-Host "==================================="
|
||||||
Write-Host "--- Features are Installed ---"
|
Write-Host "--- Features are Installed ---"
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ function Invoke-WPFGetInstalled {
|
|||||||
}
|
}
|
||||||
$managerPreference = $sync["ManagerPreference"]
|
$managerPreference = $sync["ManagerPreference"]
|
||||||
|
|
||||||
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -ScriptBlock {
|
||||||
param (
|
param (
|
||||||
[string]$checkbox,
|
[string]$checkbox,
|
||||||
[PackageManagers]$managerPreference
|
[PackageManagers]$managerPreference
|
||||||
)
|
)
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "Indeterminate" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" }
|
||||||
|
|
||||||
if ($checkbox -eq "winget") {
|
if ($checkbox -eq "winget") {
|
||||||
Write-Host "Getting Installed Programs..."
|
Write-Host "Getting Installed Programs..."
|
||||||
@@ -48,6 +48,6 @@ function Invoke-WPFGetInstalled {
|
|||||||
|
|
||||||
Write-Host "Done..."
|
Write-Host "Done..."
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "None" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,9 +71,11 @@ function Invoke-WPFImpex {
|
|||||||
# $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value })
|
# $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value })
|
||||||
$flattenedJson = $jsonFile
|
$flattenedJson = $jsonFile
|
||||||
Update-WinUtilSelections -flatJson $flattenedJson
|
Update-WinUtilSelections -flatJson $flattenedJson
|
||||||
# TODO test with toggles
|
|
||||||
|
if (!$PARAM_NOUI) {
|
||||||
Reset-WPFCheckBoxes -doToggles $true
|
Reset-WPFCheckBoxes -doToggles $true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
Write-Error "An error occurred while importing: $_"
|
Write-Error "An error occurred while importing: $_"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
function Invoke-WPFInstall {
|
function Invoke-WPFInstall {
|
||||||
param (
|
|
||||||
[Parameter(Mandatory=$false)]
|
|
||||||
[PSObject[]]$PackagesToInstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
|
|
||||||
)
|
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Installs the selected programs using winget, if one or more of the selected programs are already installed on the system, winget will try and perform an upgrade if there's a newer version to install.
|
Installs the selected programs using winget, if one or more of the selected programs are already installed on the system, winget will try and perform an upgrade if there's a newer version to install.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
|
$PackagesToInstall = $sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ }
|
||||||
|
|
||||||
|
|
||||||
if($sync.ProcessRunning) {
|
if($sync.ProcessRunning) {
|
||||||
$msg = "[Invoke-WPFInstall] An Install process is currently running."
|
$msg = "[Invoke-WPFInstall] An Install process is currently running."
|
||||||
[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)
|
||||||
@@ -22,8 +21,8 @@ function Invoke-WPFInstall {
|
|||||||
|
|
||||||
$ManagerPreference = $sync["ManagerPreference"]
|
$ManagerPreference = $sync["ManagerPreference"]
|
||||||
|
|
||||||
Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
|
$handle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock {
|
||||||
param($PackagesToInstall, $ManagerPreference, $DebugPreference)
|
param($PackagesToInstall, $ManagerPreference)
|
||||||
|
|
||||||
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
|
$packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
|
||||||
|
|
||||||
@@ -45,12 +44,12 @@ function Invoke-WPFInstall {
|
|||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "-- Installs have finished ---"
|
Write-Host "-- Installs have finished ---"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }
|
||||||
} catch {
|
} catch {
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "Error: $_"
|
Write-Host "Error: $_"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -overlay "warning" })
|
Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" }
|
||||||
}
|
}
|
||||||
$sync.ProcessRunning = $False
|
$sync.ProcessRunning = $False
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ function Invoke-WPFRunspace {
|
|||||||
Param (
|
Param (
|
||||||
$ScriptBlock,
|
$ScriptBlock,
|
||||||
$ArgumentList,
|
$ArgumentList,
|
||||||
$ParameterList,
|
$ParameterList
|
||||||
$DebugPreference
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a PowerShell instance
|
# Create a PowerShell instance
|
||||||
@@ -41,7 +40,7 @@ function Invoke-WPFRunspace {
|
|||||||
foreach ($parameter in $ParameterList) {
|
foreach ($parameter in $ParameterList) {
|
||||||
$script:powershell.AddParameter($parameter[0], $parameter[1])
|
$script:powershell.AddParameter($parameter[0], $parameter[1])
|
||||||
}
|
}
|
||||||
$script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block
|
|
||||||
$script:powershell.RunspacePool = $sync.runspace
|
$script:powershell.RunspacePool = $sync.runspace
|
||||||
|
|
||||||
# Execute the RunspacePool
|
# Execute the RunspacePool
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ function Invoke-WPFSSHServer {
|
|||||||
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ScriptBlock {
|
||||||
|
|
||||||
Invoke-WinUtilSSHServer
|
Invoke-WinUtilSSHServer
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ function Invoke-WPFSystemRepair {
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Checks for system corruption using SFC, and DISM
|
Checks for system corruption using SFC, and DISM
|
||||||
|
Checks for disk failure using Chkdsk
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
1. SFC - Fixes system file corruption, and fixes DISM if it was corrupted
|
1. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
||||||
2. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
|
2. SFC - scans protected system files for corruption and fixes them
|
||||||
3. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure
|
3. DISM - Repair a corrupted Windows operating system image
|
||||||
#>
|
#>
|
||||||
Start-Process cmd.exe -ArgumentList "/c chkdsk.exe /scan /perf" -NoNewWindow -Wait
|
|
||||||
|
Start-Process cmd.exe -ArgumentList "/c chkdsk /scan /perf" -NoNewWindow -Wait
|
||||||
Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -NoNewWindow -Wait
|
Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -NoNewWindow -Wait
|
||||||
Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait
|
Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait
|
||||||
|
|
||||||
|
|||||||
21
functions/public/Invoke-WPFUIThread.ps1
Normal file
21
functions/public/Invoke-WPFUIThread.ps1
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
function Invoke-WPFUIThread {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates and runs a task on Winutil's WPF Forms thread.
|
||||||
|
|
||||||
|
.PARAMETER ScriptBlock
|
||||||
|
The scriptblock to invoke in the thread
|
||||||
|
#>
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param (
|
||||||
|
$ScriptBlock
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($PARAM_NOUI) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync.form.Dispatcher.Invoke([action]$ScriptBlock)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user