Compare commits
317 Commits
832f08c18b
...
24.07.25
Author | SHA1 | Date | |
---|---|---|---|
8ae328c4b5 | |||
1032d3d5aa | |||
84a84fd34d | |||
b23c685580 | |||
214eb1d332 | |||
5083b84233 | |||
4553f3e758 | |||
8baacc2966 | |||
a8c47e64d7 | |||
fcc48a2b22 | |||
f2a5574a8c | |||
363ed1c41b | |||
706328e674 | |||
2f43975735 | |||
d1a40217c1 | |||
790afac860 | |||
efee03b940 | |||
8beca950a8 | |||
9bc6adf191 | |||
fb34c7cbd8 | |||
ae1b22552a | |||
57f4eba692 | |||
22684da35b | |||
7acb213a77 | |||
b9e8b9f697 | |||
300439c851 | |||
0e7ac225af | |||
0bbbe67446 | |||
376cc1d745 | |||
499848d643 | |||
601e338929 | |||
8045a78c44 | |||
df2fe4a4c6 | |||
8a6116cea1 | |||
e82870da89 | |||
e784604a1a | |||
e8022b8556 | |||
e7ed7829cf | |||
508f909fc9 | |||
60a6c387e2 | |||
1307abc1d6 | |||
45a103f76b | |||
b84c0d9248 | |||
f51c30023a | |||
bce4868896 | |||
8141baa879 | |||
280f8a7dbc | |||
0a472c06c4 | |||
1c72007a29 | |||
07434f706b | |||
4176435ebf | |||
a38cfb14d3 | |||
b319c32ae6 | |||
829e46b3a8 | |||
2304b06f68 | |||
c90363181c | |||
5d3d47eeb5 | |||
bc213d34d9 | |||
df2cd71d1e | |||
a760400aeb | |||
07a78fc3d8 | |||
78a6a60d96 | |||
1fb986a05d | |||
51e5af41ed | |||
7dba867101 | |||
ce787a9074 | |||
425ec42cb5 | |||
b2cd7d7897 | |||
ad9cc6fffd | |||
594ee94f49 | |||
30bea93dde | |||
2e26ae7ef1 | |||
0138a76601 | |||
8340aca48f | |||
265f4eb705 | |||
40cf1f80ef | |||
e182d2433f | |||
4831828b27 | |||
c9934a53b0 | |||
904e0ad468 | |||
792a5c4b38 | |||
ff0b3d29cf | |||
ac9b4fd645 | |||
84ca02a033 | |||
8cfd47e1b7 | |||
8df9a7c590 | |||
1d01b7490f | |||
3245756935 | |||
54ad3198dd | |||
7904380c8b | |||
81e8ca7fdc | |||
86cf331e01 | |||
150a99026f | |||
272a993099 | |||
d4faee5fbc | |||
e5ba389606 | |||
af36d76e65 | |||
5b7f0a0edf | |||
7294064aaa | |||
1e7b73df33 | |||
c68b8d0f75 | |||
2c1031865f | |||
b1e995fcaf | |||
e798ec9126 | |||
c4daafbe79 | |||
1f0ee72834 | |||
950bd59e2f | |||
05267d8a37 | |||
37089aeb5c | |||
bdb60b0b44 | |||
84242db2db | |||
2844b0df54 | |||
b2e3487989 | |||
01837b028a | |||
af1743066f | |||
d261f42ae4 | |||
02f335f4f3 | |||
3cb9a4f0ea | |||
d5c68029fe | |||
5375675347 | |||
8ed7732cbf | |||
fb932d7e10 | |||
78f2aa5979 | |||
5176e3d4ff | |||
b4aff6f7d3 | |||
ae240af11f | |||
cedc752be5 | |||
a1f534e6b5 | |||
cb1aed3bdd | |||
9e155c94d0 | |||
700a785092 | |||
80c7f6045f | |||
3466ea222d | |||
448d27f064 | |||
90f9c16446 | |||
0a821f6e21 | |||
aaaf5f7f85 | |||
d7c2e2cf2a | |||
9f3ad1b998 | |||
88612b4225 | |||
5c14d44afa | |||
d62d41347a | |||
6aaeb09e73 | |||
96d80c486b | |||
47dbbfb4ff | |||
ce7d14b227 | |||
79afb8c1bd | |||
65f76c2a77 | |||
cf9cb52cdb | |||
7dcd0ed67e | |||
49b7224a6f | |||
f04c87f5a3 | |||
d732c40b9a | |||
8984c177a0 | |||
747b1d76fd | |||
1b1ac22251 | |||
bcc8ad8171 | |||
6b73f71876 | |||
b47036630c | |||
e5ca44a0bd | |||
e7d49fe48b | |||
a5fbff142b | |||
e830894819 | |||
d4dc9aec9b | |||
e4d0e16b26 | |||
d6102e8954 | |||
227cb21c24 | |||
1891ea7966 | |||
6c49a8f2c9 | |||
ab384029f1 | |||
0c32d016b4 | |||
45818fd80c | |||
d08954945c | |||
a7ab24e3c9 | |||
a924d91d65 | |||
676e46f59f | |||
37b9c552df | |||
2e12176b2d | |||
7d1e4a8d82 | |||
4f8e7a8ea7 | |||
6c4c24b26d | |||
d205e75030 | |||
12561aba2c | |||
84fd1bc71c | |||
b9cd563915 | |||
58df438b92 | |||
9086b30a75 | |||
b268f98b91 | |||
25a4ebe062 | |||
60f5ef1f8e | |||
491b0b534c | |||
a59a30f905 | |||
227babe0e8 | |||
a0c4b33483 | |||
b831901967 | |||
d0427403f1 | |||
312f42f39a | |||
f68c9bf213 | |||
7b6a624ec6 | |||
43304808a9 | |||
ad0ed09940 | |||
b9813f86b9 | |||
2c5707e18f | |||
b646b139b8 | |||
5b369250b6 | |||
9274c683a2 | |||
f559de3a8c | |||
1e71020757 | |||
83ef15ccaf | |||
c2938f9339 | |||
b2be290be2 | |||
b6723bebf0 | |||
42c1ef434c | |||
a6ad919f16 | |||
52fd667ef9 | |||
04130231ff | |||
a510b52acb | |||
48581d6aad | |||
c3a77e71ad | |||
3d7b232248 | |||
b6d1dc50cb | |||
f6af93afbd | |||
0c841f98e8 | |||
e4c44e4878 | |||
8a78c960ea | |||
cb3b64e195 | |||
83f93ceba4 | |||
9ac93fd2dc | |||
13712b4c77 | |||
8d65f3bcf8 | |||
5c937efa9b | |||
ade1c3b830 | |||
8ded42a3ce | |||
65b91330ed | |||
98f8b07951 | |||
acaad991a7 | |||
e00bc5f723 | |||
a5fd8e355d | |||
8a2e1391e0 | |||
81c3722881 | |||
279e707a7a | |||
e894613f68 | |||
be08211cdc | |||
118c3e3964 | |||
3f4e353d13 | |||
a09ae3e251 | |||
f9c09495fc | |||
de424ce636 | |||
c28760e11a | |||
53090a6164 | |||
4661bf31ba | |||
5c687c98c6 | |||
495e08db05 | |||
a23d63613f | |||
acbabd4962 | |||
45a18b335f | |||
c23ea45e61 | |||
1f01933cc0 | |||
4958c5efe9 | |||
5dd3bb492f | |||
9d6d21bd40 | |||
ff80ef491a | |||
4bc54de8cd | |||
864f063878 | |||
009ab5066c | |||
a735a02257 | |||
360cc15b4b | |||
1e906696f5 | |||
b6902c116a | |||
8ace1a32bf | |||
4fcd3f5b2f | |||
c942287172 | |||
7c58eb0e78 | |||
9be030a4e2 | |||
4348f052c3 | |||
ad81bab274 | |||
3a83203298 | |||
09b1e56967 | |||
af94adbabe | |||
a609f771c8 | |||
2b80e14bf9 | |||
1325ef54b8 | |||
8a76641d20 | |||
3dca1ee43e | |||
7b6decb28a | |||
774b64b092 | |||
02ea93c80f | |||
5e10883547 | |||
a8af90a112 | |||
2354645b47 | |||
9ef050442d | |||
c8ae4a812e | |||
ad080f267e | |||
fec5b68b10 | |||
57ff8b0188 | |||
9eceae6751 | |||
88a622c368 | |||
4a7c8a35bf | |||
c3b12e89f8 | |||
f776717f67 | |||
54a575274d | |||
5cd75c0ed6 | |||
6e7c5336c2 | |||
ca9c764cd7 | |||
23af79852a | |||
7bfcd7cb25 | |||
4de1ac39ef | |||
4ac5b79fc8 | |||
420f37f205 | |||
c6c3f0cd03 | |||
dd2e4fb337 | |||
31c6622926 | |||
e745d798b1 | |||
a29364984b | |||
07eeed310b | |||
8e00077e50 | |||
fc505872d2 |
11
.gitattributes
vendored
@ -1,3 +1,12 @@
|
|||||||
|
* text=auto
|
||||||
|
|
||||||
|
*.ps1 text eol=crlf
|
||||||
|
*.json text eol=crlf
|
||||||
|
*.cfg text eol=crlf
|
||||||
|
|
||||||
|
*.png binary
|
||||||
|
*.jpg binary
|
||||||
|
|
||||||
config/* diff
|
config/* diff
|
||||||
config/applications.json diff
|
config/applications.json diff
|
||||||
*.json diff
|
*.json diff
|
||||||
|
11
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -4,24 +4,23 @@ about: Create a report to help us improve
|
|||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Describe the bug**
|
## Describe the bug
|
||||||
A clear and concise description of what the bug is.
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
**To Reproduce**
|
## To Reproduce
|
||||||
Steps to reproduce the behavior:
|
Steps to reproduce the behavior:
|
||||||
1. Go to '...'
|
1. Go to '...'
|
||||||
2. Click on '....'
|
2. Click on '....'
|
||||||
3. Scroll down to '....'
|
3. Scroll down to '....'
|
||||||
4. See error
|
4. See error
|
||||||
|
|
||||||
**Expected behavior**
|
## Expected behavior
|
||||||
A clear and concise description of what you expected to happen.
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
**Screenshots**
|
## Screenshots
|
||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Additional context**
|
## Additional context
|
||||||
Add any other context about the problem here.
|
Add any other context about the problem here.
|
||||||
|
36
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Pull Request
|
||||||
|
|
||||||
|
## Title
|
||||||
|
[Provide a succinct and descriptive title for the pull request.]
|
||||||
|
|
||||||
|
## Type of Change
|
||||||
|
- [ ] New feature
|
||||||
|
- [ ] Bug fix
|
||||||
|
- [ ] Documentation update
|
||||||
|
- [ ] Refactoring
|
||||||
|
- [ ] Hotfix
|
||||||
|
- [ ] Security patch
|
||||||
|
- [ ] UI/UX improvement
|
||||||
|
|
||||||
|
## Description
|
||||||
|
[Provide a detailed explanation of the changes you have made. Include the reasons behind these changes and any relevant context. Link any related issues.]
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
[Detail the testing you have performed to ensure that these changes function as intended. Include information about any added tests.]
|
||||||
|
|
||||||
|
## Impact
|
||||||
|
[Discuss the impact of your changes on the project. This might include effects on performance, new dependencies, or changes in behaviour.]
|
||||||
|
|
||||||
|
## Issue related to PR
|
||||||
|
[What issue/discussion is related to this PR (if any)]
|
||||||
|
- Resolves #
|
||||||
|
|
||||||
|
## Additional Information
|
||||||
|
[Any additional information that reviewers should be aware of.]
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
- [ ] My code adheres to the coding and style guidelines of the project.
|
||||||
|
- [ ] I have performed a self-review of my own code.
|
||||||
|
- [ ] I have commented my code, particularly in hard-to-understand areas.
|
||||||
|
- [ ] I have made corresponding changes to the documentation.
|
||||||
|
- [ ] My changes generate no errors/warnings/merge conflicts.
|
9
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
ignore:
|
||||||
|
- dependency-name: "actions/stale"
|
||||||
|
versions: '>= 9'
|
38
.github/workflows/close-discussion.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
name: Close Discussion on PR Merge
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [closed]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
closeDiscussion:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check if PR was merged
|
||||||
|
if: github.event.pull_request.merged == true
|
||||||
|
run: echo "PR was merged"
|
||||||
|
|
||||||
|
- name: Extract Discussion Number & Close If any Where Found
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
if: github.event.pull_request.merged == true
|
||||||
|
id: extract-discussion
|
||||||
|
run: |
|
||||||
|
echo '${{ github.event.pull_request.body }}' > pr_body.txt
|
||||||
|
|
||||||
|
discussion_ids_arr=()
|
||||||
|
cat pr_body.txt | grep -i -Po '^\s*(-|\d+\.)?\s*(Resolve(s|d)?)\s*#\d+\s*$|^\s*(-|\d+\.)?\s*(Fix(es|ed)?)\s*#\d+\s*$|^\s*(-|\d+\.)?\s*(Close(s|d)?)\s*#\d+\s*$' | awk -F '#' '{print $2}' > discussion_ids_list.txt
|
||||||
|
while read -r line; do
|
||||||
|
discussion_ids_arr+=("$line")
|
||||||
|
done < discussion_ids_list.txt
|
||||||
|
|
||||||
|
number_of_ids=${#discussion_ids_arr[@]}
|
||||||
|
for (( i=0; i<${number_of_ids}; i++ ));
|
||||||
|
do
|
||||||
|
discussion_id=${discussion_ids_arr[$i]}
|
||||||
|
echo "$discussion_id"
|
||||||
|
curl -X PATCH -H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
-d '{"state": "closed"}' \
|
||||||
|
'https://api.github.com/repos/${{ github.repository }}/discussions/$discussion_id'
|
||||||
|
done
|
||||||
|
shell: bash
|
76
.github/workflows/close-old-issues.yaml
vendored
@ -4,62 +4,36 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *' # Run daily
|
- cron: '0 0 * * *' # Run daily
|
||||||
workflow_dispatch: # This line enables manual triggering
|
workflow_dispatch: # This line enables manual triggering
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
close-issues:
|
close-issues:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
issues: write # Ensure necessary permissions for issues
|
issues: write # Ensure necessary permissions for issues
|
||||||
|
pull-requests: none
|
||||||
|
contents: none
|
||||||
steps:
|
steps:
|
||||||
- name: Close inactive issues
|
- name: Close inactive issues
|
||||||
uses: actions/github-script@v7
|
uses: actions/stale@v8
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
# A list of labels to reference when looking through issues,
|
||||||
script: |
|
# and only when one (or even more) of these labels are found..
|
||||||
const octokit = github;
|
# then skip this issue, and never try to stale and/or close it.
|
||||||
|
exempt-issue-labels: "Keep Issue Open"
|
||||||
// Get the repository owner and name
|
# Split it into two weeks, after one week the issue will be marked as stale,
|
||||||
const { owner, repo } = context.repo;
|
# after another week have pasted without any update.. the issue will then be closed.
|
||||||
|
days-before-issue-stale: 7
|
||||||
// Define the inactivity period (14 days)
|
days-before-issue-close: 7
|
||||||
const inactivityPeriod = new Date();
|
# NEVER mark PRs as Stale or Close + this workflow should never have write permissions on PRs, EVER!
|
||||||
inactivityPeriod.setDate(inactivityPeriod.getDate() - 14);
|
days-before-pr-stale: -1
|
||||||
|
days-before-pr-close: -1
|
||||||
try {
|
# Sends a message for both the Stale and Close events of an issue.
|
||||||
// Get all open issues with pagination
|
stale-issue-message: "This issue was marked as stale because it has been inactive for 7 days"
|
||||||
for await (const response of octokit.paginate.iterator(octokit.rest.issues.listForRepo, {
|
close-issue-message: "This issue was closed because it has been inactive for 7 days since it was marked as stale"
|
||||||
owner,
|
# Increase this value if the project receives a lot of
|
||||||
repo,
|
# PRs (yes.. apparently they're processed no matter what) & Issues.
|
||||||
state: 'open',
|
# Default value for it (according to the docs) is 30
|
||||||
})) {
|
operations-per-run: 200
|
||||||
const issues = response.data;
|
# Make this field equal true if you want to test your configuration if it works correctly or not
|
||||||
|
debug-only: false
|
||||||
// Close issues inactive for more than the inactivity period
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
for (const issue of issues) {
|
|
||||||
const lastCommentDate = issue.updated_at;
|
|
||||||
if (new Date(lastCommentDate) < inactivityPeriod) {
|
|
||||||
try {
|
|
||||||
// Close the issue
|
|
||||||
await octokit.rest.issues.update({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
issue_number: issue.number,
|
|
||||||
state: 'closed',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add a comment
|
|
||||||
await octokit.rest.issues.createComment({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
issue_number: issue.number,
|
|
||||||
body: 'Closed due to inactivity',
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error updating or commenting on issue #${issue.number}: ${error}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error fetching issues: ${error}`);
|
|
||||||
}
|
|
||||||
|
25
.github/workflows/compile.yaml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: Compile
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- test*
|
||||||
|
workflow_dispatch: # Manual trigger added
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-runspace:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
- name: Compile project
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
|
with:
|
||||||
|
commit_message: Compile Winutil
|
||||||
|
if: success()
|
113
.github/workflows/createchangelog.yml
vendored
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
name: Update changelog.md on Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published, created, edited, deleted]
|
||||||
|
workflow_dispatch: # Add this line to enable manual triggering
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-file:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Get all releases and update changelog.md file
|
||||||
|
run: |
|
||||||
|
# Initialize some values
|
||||||
|
changelog_path="docs/changelog.md"
|
||||||
|
gh release list --exclude-drafts --json tagName,name,isLatest,isPrerelease --limit 1000000 > releases.txt
|
||||||
|
declare -rA number_of_releases=$(cat releases.txt | grep -Po '"tagName"' | wc --lines)
|
||||||
|
|
||||||
|
# Clear the contents of changelog file
|
||||||
|
echo "" > $changelog_path
|
||||||
|
|
||||||
|
# Write some Initial Content to changelog file
|
||||||
|
echo "# Changelog" >> $changelog_path
|
||||||
|
echo "" >> $changelog_path
|
||||||
|
echo "WinUtil change log received from GitHub Releases, it's autogenerated using GitHub Actions." >> $changelog_path
|
||||||
|
echo "" >> $changelog_path
|
||||||
|
echo "> [!WARNING]" >> $changelog_path
|
||||||
|
echo "> This file **SHOULD NOT** be edited directly, any PRs that tries changing it directly will either be requested on not changing it, or it'll get rejected." >> $changelog_path
|
||||||
|
echo "" >> $changelog_path
|
||||||
|
|
||||||
|
# Make array for git tag names
|
||||||
|
tag_arr=()
|
||||||
|
cat releases.txt | grep -Po '"tagName":\s*.*?[^\\]"' | awk -F ':' '{print $2}' | sed s/\"//g > tags_list.txt
|
||||||
|
while read -r line; do
|
||||||
|
tag_arr+=("$line")
|
||||||
|
done < tags_list.txt
|
||||||
|
|
||||||
|
# Make array for releases names
|
||||||
|
name_arr=()
|
||||||
|
cat releases.txt | grep -Po '"name":\s*.*?[^\\]"' | awk -F ':' '{print $2}' | sed s/\"//g > releases_names_list.txt
|
||||||
|
while read -r line; do
|
||||||
|
name_arr+=("$line")
|
||||||
|
done < releases_names_list.txt
|
||||||
|
|
||||||
|
# Make array for isPrerelease
|
||||||
|
isprerelease_arr=()
|
||||||
|
cat releases.txt | grep -Po '"isPrerelease":\s*(false|true)' | awk -F ':' '{print $2}' | sed s/\"//g > isprerelease_list.txt
|
||||||
|
while read -r line; do
|
||||||
|
isprerelease_arr+=("$line")
|
||||||
|
done < isprerelease_list.txt
|
||||||
|
|
||||||
|
# Make array for isLatest
|
||||||
|
islatest_arr=()
|
||||||
|
cat releases.txt | grep -Po '"isLatest":\s*(false|true)' | awk -F ':' '{print $2}' | sed s/\"//g > islatest_list.txt
|
||||||
|
while read -r line; do
|
||||||
|
islatest_arr+=("$line")
|
||||||
|
done < islatest_list.txt
|
||||||
|
|
||||||
|
# Debug Output
|
||||||
|
echo "Tag Array: " ${tag_arr[@]}
|
||||||
|
echo "Array Length: " ${#tag_arr[@]}
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "Release Name Array: " ${name_arr[@]}
|
||||||
|
echo "Array Length: " ${#name_arr[@]}
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "IsPrerelease Array: " ${isprerelease_arr[@]}
|
||||||
|
echo "Array Length: " ${#isprerelease_arr[@]}
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "IsLatest Array: " ${islatest_arr[@]}
|
||||||
|
echo "Array Length: " ${#islatest_arr[@]}
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Exit when this impossible condition is met (just to be safe)
|
||||||
|
if [[ ! (${#tag_arr[@]}==${#name_arr[@]} && ${#tag_arr[@]}==${#isprerelease_arr[@]} && ${#tag_arr[@]}==${#islatest_arr[@]} ) ]] ; then
|
||||||
|
echo "Impossible Condition has been met, the Name Array Length Does Not match Tag Array Length, exiting..."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Main loop that does the heavy lifting (Content Generation)
|
||||||
|
for (( i=0; i<${number_of_releases}; i++ ));
|
||||||
|
do
|
||||||
|
# The Variables to use on each iteration
|
||||||
|
tag=${tag_arr[$i]}
|
||||||
|
name=${name_arr[$i]}
|
||||||
|
isprerelease=${isprerelease_arr[$i]}
|
||||||
|
islatest=${islatest_arr[$i]}
|
||||||
|
body=$(gh release view "$tag" --json body --jq .body)
|
||||||
|
|
||||||
|
# The generation of changelog file contents
|
||||||
|
echo "# $name" >> $changelog_path
|
||||||
|
echo "" >> $changelog_path
|
||||||
|
echo "$body" >> $changelog_path
|
||||||
|
echo "" >> $changelog_path
|
||||||
|
done
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
|
||||||
|
- name: Commit and Push Changes
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
git config --global user.name 'github-actions[bot]'
|
||||||
|
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||||
|
git add docs/changelog.md
|
||||||
|
git commit -m "Update changelog.md with all releases"
|
||||||
|
git push
|
22
.github/workflows/github-pages.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
name: GitHub Pages Deploy
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published, prereleased]
|
||||||
|
workflow_dispatch:
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
key: ${{ github.ref }}
|
||||||
|
path: .cache
|
||||||
|
- run: pip install mkdocs-material
|
||||||
|
- run: pip install pillow cairosvg
|
||||||
|
- run: mkdocs gh-deploy --force
|
45
.github/workflows/issue-slash-commands.yaml
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
name: Close issue on /close
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created, edited]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
closeIssueOnClose:
|
||||||
|
# Skip this job if the comment was created/edited on a PR
|
||||||
|
if: ${{ !github.event.issue.pull_request }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: none
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check for /close comment
|
||||||
|
id: check_comment
|
||||||
|
run: |
|
||||||
|
if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then
|
||||||
|
echo "comment=true" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "comment=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check if the user is allowed
|
||||||
|
id: check_user
|
||||||
|
if: env.comment == 'true'
|
||||||
|
run: |
|
||||||
|
ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC")
|
||||||
|
if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then
|
||||||
|
echo "user=true" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "user=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Close issue if conditions are met
|
||||||
|
if: env.comment == 'true' && env.user == 'true'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||||
|
run: |
|
||||||
|
echo Closing the issue...
|
||||||
|
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
|
48
.github/workflows/pre-release.yaml
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
name: Pre-Release WinUtil
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
actions: read
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch: # Manual trigger added
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-runspace:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Extract Version from winutil.ps1
|
||||||
|
id: extract_version
|
||||||
|
run: |
|
||||||
|
$version = (Get-Date -Format "yy.MM.dd")
|
||||||
|
echo "version=$version" >> $env:GITHUB_ENV
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
- name: Create Tag
|
||||||
|
id: create_tag
|
||||||
|
run: |
|
||||||
|
$tagExists = git tag -l $env:VERSION
|
||||||
|
if ($tagExists -eq "") {
|
||||||
|
git tag $env:VERSION
|
||||||
|
git push origin $env:VERSION
|
||||||
|
} else {
|
||||||
|
Write-Host "Tag $env:VERSION already exists, skipping tag creation"
|
||||||
|
}
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
- name: Create and Upload Release
|
||||||
|
id: create_release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ env.VERSION }}
|
||||||
|
name: Pre-Release ${{ env.VERSION }}
|
||||||
|
body: ""
|
||||||
|
append_body: false
|
||||||
|
files: ./winutil.ps1
|
||||||
|
prerelease: true
|
||||||
|
generate_release_notes: true
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
51
.github/workflows/release.yaml
vendored
@ -1,21 +1,44 @@
|
|||||||
name: Update Branch
|
name: Release WinUtil
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_dispatch: # Manual trigger added
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- test*
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-runspace:
|
build-runspace:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.extract_version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- name: Checkout Repository
|
||||||
with:
|
uses: actions/checkout@v4
|
||||||
ref: ${{ github.head_ref }}
|
|
||||||
- name: Create local changes
|
- name: Extract Version from winutil.ps1
|
||||||
run: |
|
id: extract_version
|
||||||
powershell.exe -f Compile.ps1
|
run: |
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v4.16.0
|
$version = ''
|
||||||
with:
|
Get-Content ./winutil.ps1 -TotalCount 30 | ForEach-Object {
|
||||||
commit_message: Compile Winutil
|
if ($_ -match 'Version\s*:\s*(\d{2}\.\d{2}\.\d{2})') {
|
||||||
|
$version = $matches[1]
|
||||||
|
echo "version=$version" >> $GITHUB_OUTPUT
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not $version) {
|
||||||
|
Write-Error "Version not found in winutil.ps1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
- name: Create and Upload Release
|
||||||
|
id: create_release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ steps.extract_version.outputs.version }}
|
||||||
|
name: Release ${{ steps.extract_version.outputs.version }}
|
||||||
|
body: ""
|
||||||
|
append_body: true
|
||||||
|
files: ./winutil.ps1
|
||||||
|
prerelease: false
|
||||||
|
make_latest: "true"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
25
.github/workflows/sponsors.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: Generate Sponsors README
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: 30 15 * * 0-6
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout 🛎️
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Generate Sponsors 💖
|
||||||
|
uses: JamesIves/github-sponsors-readme-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.PAT }}
|
||||||
|
file: 'README.md'
|
||||||
|
|
||||||
|
- name: Deploy to GitHub Pages 🚀
|
||||||
|
uses: JamesIves/github-pages-deploy-action@v4
|
||||||
|
with:
|
||||||
|
branch: main
|
||||||
|
folder: '.'
|
12
.github/workflows/unittests.yaml
vendored
@ -1,14 +1,14 @@
|
|||||||
name: Unit Tests
|
name: Unit Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
name: PS Script Analyzer
|
name: PS Script Analyzer
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: lint
|
- name: lint
|
||||||
uses: devblackops/github-action-psscriptanalyzer@master
|
uses: devblackops/github-action-psscriptanalyzer@master
|
||||||
with:
|
with:
|
||||||
@ -22,19 +22,19 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Pester
|
- name: Install Pester
|
||||||
run: |
|
run: |
|
||||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
|
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
|
||||||
Install-Module -Name Pester -Force -AllowClobber
|
Install-Module -Name Pester -Force -SkipPublisherCheck -AllowClobber
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Run Pester tests
|
- name: Run Pester tests
|
||||||
run: |
|
run: |
|
||||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
|
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
|
||||||
Invoke-Pester -Path 'pester/*.Tests.ps1' -EnableExit
|
Invoke-Pester -Path 'pester/*.Tests.ps1' -Output Detailed
|
||||||
|
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
env:
|
env:
|
||||||
TEMP: ${{ runner.temp }}
|
TEMP: ${{ runner.temp }}
|
6
.gitignore
vendored
@ -15,6 +15,11 @@ winutil.pdb
|
|||||||
# Folder config file
|
# Folder config file
|
||||||
[Dd]esktop.ini
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Ignore Generated XAML Files
|
||||||
|
xaml/inputApp.xaml
|
||||||
|
xaml/inputFeatures.xaml
|
||||||
|
xaml/inputTweaks.xaml
|
||||||
|
|
||||||
# Executables and Configs
|
# Executables and Configs
|
||||||
winget.msixbundle
|
winget.msixbundle
|
||||||
pester.ps1
|
pester.ps1
|
||||||
@ -39,3 +44,4 @@ Microsoft.PowerShell.ConsoleHost.dll
|
|||||||
microwin.log
|
microwin.log
|
||||||
True
|
True
|
||||||
test.ps1
|
test.ps1
|
||||||
|
winutil.ps1
|
||||||
|
140
Compile.ps1
@ -1,47 +1,143 @@
|
|||||||
|
param (
|
||||||
|
[switch]$Debug,
|
||||||
|
[switch]$Run
|
||||||
|
)
|
||||||
$OFS = "`r`n"
|
$OFS = "`r`n"
|
||||||
$scriptname = "winutil.ps1"
|
$scriptname = "winutil.ps1"
|
||||||
|
|
||||||
# Variable to sync between runspaces
|
# Variable to sync between runspaces
|
||||||
$sync = [Hashtable]::Synchronized(@{})
|
$sync = [Hashtable]::Synchronized(@{})
|
||||||
$sync.PSScriptRoot = $PSScriptRoot
|
$sync.PSScriptRoot = $PSScriptRoot
|
||||||
$sync.configs = @{}
|
$sync.configs = @{}
|
||||||
|
|
||||||
if (Test-Path -Path "$($scriptname)")
|
function Update-Progress {
|
||||||
{
|
param (
|
||||||
Remove-Item -Force "$($scriptname)"
|
[Parameter(Mandatory, position=0)]
|
||||||
|
[string]$StatusMessage,
|
||||||
|
|
||||||
|
[Parameter(Mandatory, position=1)]
|
||||||
|
[ValidateRange(0,100)]
|
||||||
|
[int]$Percent,
|
||||||
|
|
||||||
|
[Parameter(position=2)]
|
||||||
|
[string]$Activity = "Compiling"
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Progress -Activity $Activity -Status $StatusMessage -PercentComplete $Percent
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-output '
|
$header = @"
|
||||||
################################################################################################################
|
################################################################################################################
|
||||||
### ###
|
### ###
|
||||||
### WARNING: This file is automatically generated DO NOT modify this file directly as it will be overwritten ###
|
### WARNING: This file is automatically generated DO NOT modify this file directly as it will be overwritten ###
|
||||||
### ###
|
### ###
|
||||||
################################################################################################################
|
################################################################################################################
|
||||||
' | Out-File ./$scriptname -Append -Encoding ascii
|
"@
|
||||||
|
|
||||||
(Get-Content .\scripts\start.ps1).replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)") | Out-File ./$scriptname -Append -Encoding ascii
|
|
||||||
|
|
||||||
|
# Create the script in memory.
|
||||||
|
Update-Progress "Pre-req: Allocating Memory" 0
|
||||||
|
$script_content = [System.Collections.Generic.List[string]]::new()
|
||||||
|
|
||||||
|
Update-Progress "Adding: Header" 5
|
||||||
|
$script_content.Add($header)
|
||||||
|
|
||||||
|
Update-Progress "Adding: Version" 10
|
||||||
|
$script_content.Add($(Get-Content .\scripts\start.ps1).replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)"))
|
||||||
|
|
||||||
|
Update-Progress "Adding: Functions" 20
|
||||||
Get-ChildItem .\functions -Recurse -File | ForEach-Object {
|
Get-ChildItem .\functions -Recurse -File | ForEach-Object {
|
||||||
Get-Content $psitem.FullName | Out-File ./$scriptname -Append -Encoding ascii
|
$script_content.Add($(Get-Content $psitem.FullName))
|
||||||
|
}
|
||||||
|
Update-Progress "Adding: Config *.json" 40
|
||||||
|
Get-ChildItem .\config | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
|
||||||
|
|
||||||
|
$json = (Get-Content $psitem.FullName).replace("'","''")
|
||||||
|
|
||||||
|
# Replace every XML Special Character so it'll render correctly in final build
|
||||||
|
# Only do so if json files has content to be displayed (for example the applications, tweaks, features json files)
|
||||||
|
# Make an Array List containing every name at first level of Json File
|
||||||
|
$jsonAsObject = $json | convertfrom-json
|
||||||
|
$firstLevelJsonList = [System.Collections.ArrayList]::new()
|
||||||
|
$jsonAsObject.PSObject.Properties.Name | ForEach-Object {$null = $firstLevelJsonList.Add($_)}
|
||||||
|
# Note:
|
||||||
|
# Avoid using HTML Entity Codes, for example '”' (stands for "Right Double Quotation Mark"),
|
||||||
|
# Use **HTML decimal/hex codes instead**, as using HTML Entity Codes will result in XML parse Error when running the compiled script.
|
||||||
|
for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) {
|
||||||
|
$firstLevelName = $firstLevelJsonList[$i]
|
||||||
|
if ($jsonAsObject.$firstLevelName.content -ne $null) {
|
||||||
|
$jsonAsObject.$firstLevelName.content = $jsonAsObject.$firstLevelName.content.replace('&','&').replace('“','“').replace('”','”').replace("'",''').replace('<','<').replace('>','>').replace('—','—')
|
||||||
|
$jsonAsObject.$firstLevelName.content = $jsonAsObject.$firstLevelName.content.replace('''',"'") # resolves the Double Apostrophe caused by the first replace function in the main loop
|
||||||
|
}
|
||||||
|
if ($jsonAsObject.$firstLevelName.description -ne $null) {
|
||||||
|
$jsonAsObject.$firstLevelName.description = $jsonAsObject.$firstLevelName.description.replace('&','&').replace('“','“').replace('”','”').replace("'",''').replace('<','<').replace('>','>').replace('—','—')
|
||||||
|
$jsonAsObject.$firstLevelName.description = $jsonAsObject.$firstLevelName.description.replace('''',"'") # resolves the Double Apostrophe caused by the first replace function in the main loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file
|
||||||
|
if ($psitem.Name -eq "applications.json") {
|
||||||
|
for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) {
|
||||||
|
$appEntryName = $firstLevelJsonList[$i]
|
||||||
|
$appEntryContent = $jsonAsObject.$appEntryName
|
||||||
|
# Remove the entire app entry, so we could add it later with a different name
|
||||||
|
$jsonAsObject.PSObject.Properties.Remove($appEntryName)
|
||||||
|
# Add the app entry, but with a different name (WPFInstall + The App Entry Name)
|
||||||
|
$jsonAsObject | Add-Member -MemberType NoteProperty -Name "WPFInstall$appEntryName" -Value $appEntryContent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# The replace at the end is required, as without it the output of 'converto-json' will be somewhat weird for Multiline Strings
|
||||||
|
# Most Notably is the scripts in some json files, making it harder for users who want to review these scripts, which're found in the compiled script
|
||||||
|
$json = ($jsonAsObject | convertto-json -Depth 3).replace('\r\n',"`r`n")
|
||||||
|
|
||||||
|
$sync.configs.$($psitem.BaseName) = $json | convertfrom-json
|
||||||
|
$script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" ))
|
||||||
}
|
}
|
||||||
|
|
||||||
$xaml = (Get-Content .\xaml\inputXML.xaml).replace("'","''")
|
$xaml = (Get-Content .\xaml\inputXML.xaml).replace("'","''")
|
||||||
Write-output "`$inputXML = '$xaml'" | Out-File ./$scriptname -Append -Encoding ascii
|
|
||||||
|
|
||||||
Get-ChildItem .\config | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
|
|
||||||
$json = (Get-Content $psitem.FullName).replace("'","''")
|
|
||||||
$sync.configs.$($psitem.BaseName) = $json | convertfrom-json
|
|
||||||
Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" | Out-File ./$scriptname -Append -Encoding ascii
|
|
||||||
}
|
|
||||||
|
|
||||||
# Dot-source the Get-TabXaml function
|
# Dot-source the Get-TabXaml function
|
||||||
. .\functions\private\Get-TabXaml.ps1
|
. .\functions\private\Get-TabXaml.ps1
|
||||||
|
|
||||||
## Xaml Manipulation
|
Update-Progress "Building: Xaml " 75
|
||||||
$tabColumns = Get-TabXaml "applications" 5
|
$appXamlContent = Get-TabXaml "applications" 5
|
||||||
$tabColumns | Out-File -FilePath ".\xaml\inputApp.xaml" -Encoding ascii
|
$tweaksXamlContent = Get-TabXaml "tweaks"
|
||||||
$tabColumns = Get-TabXaml "tweaks"
|
$featuresXamlContent = Get-TabXaml "feature"
|
||||||
$tabColumns | Out-File -FilePath ".\xaml\inputTweaks.xaml" -Encoding ascii
|
|
||||||
$tabColumns = Get-TabXaml "feature"
|
|
||||||
$tabColumns | Out-File -FilePath ".\xaml\inputFeatures.xaml" -Encoding ascii
|
|
||||||
|
|
||||||
Get-Content .\scripts\main.ps1 | Out-File ./$scriptname -Append -Encoding ascii
|
|
||||||
|
Update-Progress "Adding: Xaml " 90
|
||||||
|
# Replace the placeholder in $inputXML with the content of inputApp.xaml
|
||||||
|
$xaml = $xaml -replace "{{InstallPanel_applications}}", $appXamlContent
|
||||||
|
$xaml = $xaml -replace "{{InstallPanel_tweaks}}", $tweaksXamlContent
|
||||||
|
$xaml = $xaml -replace "{{InstallPanel_features}}", $featuresXamlContent
|
||||||
|
|
||||||
|
$script_content.Add($(Write-output "`$inputXML = '$xaml'"))
|
||||||
|
|
||||||
|
$script_content.Add($(Get-Content .\scripts\main.ps1))
|
||||||
|
|
||||||
|
if ($Debug){
|
||||||
|
Update-Progress "Writing debug files" 95
|
||||||
|
$appXamlContent | Out-File -FilePath ".\xaml\inputApp.xaml" -Encoding ascii
|
||||||
|
$tweaksXamlContent | Out-File -FilePath ".\xaml\inputTweaks.xaml" -Encoding ascii
|
||||||
|
$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
|
||||||
|
Write-Progress -Activity "Compiling" -Completed
|
||||||
|
|
||||||
|
if ($run){
|
||||||
|
try {
|
||||||
|
Start-Process -FilePath "pwsh" -ArgumentList ".\$scriptname"
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Start-Process -FilePath "powershell" -ArgumentList ".\$scriptname"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
## Known Issues and Fixes
|
|
||||||
- Windows taking longer to shut down:
|
|
||||||
- [#69](https://github.com/ChrisTitusTech/winutil/issues/69) Turn on fast startup: Press Windows key + R, then type:
|
|
||||||
```
|
|
||||||
control /name Microsoft.PowerOptions /page pageGlobalSettings
|
|
||||||
```
|
|
||||||
- If that doesn't work, Disable Hibernation: Press Windows Key+X and select 'PowerShell (Admin)' (Windows 10) or 'Windows Terminal (Admin)' (Windows 11) and enter:
|
|
||||||
```
|
|
||||||
powercfg /H off
|
|
||||||
```
|
|
||||||
- [#69](https://github.com/ChrisTitusTech/winutil/issues/69) [95](https://github.com/ChrisTitusTech/winutil/issues/95) [#232](https://github.com/ChrisTitusTech/winutil/issues/232) Windows Search does not work: Enable Background Apps
|
|
||||||
- [#198](https://github.com/ChrisTitusTech/winutil/issues/198) Xbox Game Bar Activation Broken: Set the Xbox Accessory Management Service to Automatic
|
|
||||||
```
|
|
||||||
Get-Service -Name "XboxGipSvc" | Set-Service -StartupType Automatic
|
|
||||||
```
|
|
||||||
- Windows Insider Builds not installing: Telemetry needs to be enabled
|
|
||||||
```
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name "AllowTelemetry" -Type DWord -Value 0
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -Type DWord -Value 0
|
|
||||||
```
|
|
||||||
- Winget requires interaction on first run: Manually type 'y' and 'enter' into the PowerShell console to continue
|
|
||||||
- (Windows 11) Quick Settings no longer works: Launch the Script and click 'Enable Action Center'
|
|
||||||
- Explorer no longer launches: Go to Control Panel, File Explorer Options, Change the 'Open File Explorer to' option to 'This PC'.
|
|
||||||
- Script doesn't run/PowerShell crashes:
|
|
||||||
1. Press Windows Key+X and select 'PowerShell (Admin)' (Windows 10) or 'Windows Terminal (Admin)' (Windows 11)
|
|
||||||
2. Run:
|
|
||||||
```
|
|
||||||
Set-ExecutionPolicy Unrestricted -Scope Process -Force
|
|
||||||
```
|
|
||||||
3. Run:
|
|
||||||
```
|
|
||||||
irm christitus.com/win | iex
|
|
||||||
```
|
|
131
README.md
@ -1,16 +1,20 @@
|
|||||||
# Chris Titus Tech's Windows Utility
|
# Chris Titus Tech's Windows Utility
|
||||||
|
|
||||||
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.
|
[](https://github.com/ChrisTitusTech/winutil/releases/latest)
|
||||||
|

|
||||||
|
[](https://discord.gg/RUbZUZyByQ)
|
||||||
|
|
||||||

|
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
|
||||||
|
|
||||||
Winutil must be run in Admin mode because it performs system-wide tweaks. To achieve this, open PowerShell or Windows Terminal as an administrator. Here are a few ways to do it:
|
Winutil must be run in Admin mode because it performs system-wide tweaks. To achieve this, open PowerShell or Windows Terminal as an administrator. Here are a few ways to do it:
|
||||||
|
|
||||||
1. **Right-Click Method:**
|
1. **Right-Click Method:**
|
||||||
- Right-click on the start menu.
|
- Right-click on the start menu.
|
||||||
- Choose "PowerShell As Admin" (for Windows 10) or "Windows Terminal As Admin" (for Windows 11).
|
- Choose "Windows PowerShell (Admin)" (for Windows 10) or "Terminal (Admin)" (for Windows 11).
|
||||||
|
|
||||||
2. **Search and Launch Method:**
|
2. **Search and Launch Method:**
|
||||||
- Press the Windows key.
|
- Press the Windows key.
|
||||||
@ -20,124 +24,43 @@ Winutil must be run in Admin mode because it performs system-wide tweaks. To ach
|
|||||||
|
|
||||||
### Launch Command
|
### Launch Command
|
||||||
|
|
||||||
#### Simple way
|
#### Stable Branch
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
irm "https://christitus.com/win" | iex
|
||||||
```
|
```
|
||||||
iwr -useb https://christitus.com/win | iex
|
#### Dev Branch
|
||||||
```
|
|
||||||
or by executing:
|
|
||||||
```
|
|
||||||
irm https://christitus.com/win | iex
|
|
||||||
```
|
|
||||||
Courtesy of the issue raised at: [#144](/../../issues/144)
|
|
||||||
|
|
||||||
if for some reason this site is not reachable from your country please try running it directly from github
|
```ps1
|
||||||
|
irm "https://christitus.com/windev" | iex
|
||||||
```
|
|
||||||
irm https://raw.githubusercontent.com/ChrisTitusTech/winutil/main/winutil.ps1 | iex
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Automation
|
If you have Issues, refer to [Known Issues](https://christitustech.github.io/winutil/KnownIssues/)
|
||||||
|
|
||||||
Some features are avaliable through automation. This allows you to save your config file pass it to Winutil walk away and come back to a finished system. Here is how you can set it up currently with Winutil >24.01.15
|
## 🎓 Documentation
|
||||||
|
|
||||||
1. On the Install Tab, click "Get Installed", this will get all installed apps **supported by Winutil** on the system
|
### [WinUtil Official Documentation](https://christitustech.github.io/winutil/)
|
||||||

|
|
||||||
2. Click on the Settings cog in the upper right corner and chose Export, chose file file and location, this will export the setting file.
|
### [YouTube Tutorial](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
|
||||||

|
|
||||||
3. Copy this file to a USB or somewhere you can use after Windows installation.
|
### [ChrisTitus.com Article](https://christitus.com/windows-tool/)
|
||||||
4. Use Microwin tab to create a custom Windows image.
|
|
||||||
5. Install the Windows image.
|
|
||||||
6. In the new Windows, Open PowerShell in the admin mode and run command to automatically apply tweaks and install apps from the config file.
|
|
||||||
```
|
|
||||||
irm https://christitus.com/win -Config [path-to-your-config] -Run | iex
|
|
||||||
```
|
|
||||||
7. Have a cup of coffee! Come back when it's done.
|
|
||||||
|
|
||||||
|
|
||||||
## Issues:
|
## 💖 Support
|
||||||
|
|
||||||
- If you are unable to resolve christitus.com/win and are getting errors launching the tool, it might be due to India blocking GitHub's content domain and preventing downloads. You may use a VPN or change your DNS provider to Google/Cloudflare/etc.
|
|
||||||
|
|
||||||
Source: <https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms>
|
|
||||||
|
|
||||||
- Windows Security (formerly Defender) and other anti-virus software are known to block the script. The script gets flagged due to the fact that it requires administrator privileges & makes drastic system changes.
|
|
||||||
|
|
||||||
- If you are having TLS 1.2 issues, or are having trouble resolving `christitus.com/win` then run with the following command:
|
|
||||||
|
|
||||||
```
|
|
||||||
[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;iex(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/ChrisTitusTech/winutil/main/winutil.ps1')
|
|
||||||
```
|
|
||||||
|
|
||||||
If you are still having issues try changing your DNS provider to 1.1.1.1 || 1.0.0.1 or 8.8.8.8 || 8.8.4.4
|
|
||||||
|
|
||||||
## Support
|
|
||||||
- To morally and mentally support the project, make sure to leave a ⭐️!
|
- To morally and mentally support the project, make sure to leave a ⭐️!
|
||||||
- EXE Wrapper for $10 @ https://www.cttstore.com/windows-toolbox
|
- EXE Wrapper for $10 @ https://www.cttstore.com/windows-toolbox
|
||||||
|
|
||||||
## Tutorial
|
## 💖 Sponsors
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
|
These are the sponsors that help keep this project alive with monthly contributions.
|
||||||
|
|
||||||
## Overview
|
<!-- sponsors --><a href="https://github.com/GregoryNavasarkian"><img src="https://github.com/GregoryNavasarkian.png" width="60px" alt="Gregory Navasarkian" /></a><a href="https://github.com/ysaito8015"><img src="https://github.com/ysaito8015.png" width="60px" alt="Yusuke Saito" /></a><a href="https://github.com/TriHydera"><img src="https://github.com/TriHydera.png" width="60px" alt="TriHydera" /></a><a href="https://github.com/jozozovko"><img src="https://github.com/jozozovko.png" width="60px" alt="" /></a><a href="https://github.com/DelDongo"><img src="https://github.com/DelDongo.png" width="60px" alt="" /></a><a href="https://github.com/markamos"><img src="https://github.com/markamos.png" width="60px" alt="Mark Amos" /></a><a href="https://github.com/dwelfusius"><img src="https://github.com/dwelfusius.png" width="60px" alt="" /></a><a href="https://github.com/mews-se"><img src="https://github.com/mews-se.png" width="60px" alt="" /></a><a href="https://github.com/jdiegmueller"><img src="https://github.com/jdiegmueller.png" width="60px" alt="Jason A. Diegmueller" /></a><a href="https://github.com/AlanTristar"><img src="https://github.com/AlanTristar.png" width="60px" alt="" /></a><a href="https://github.com/JennJones89"><img src="https://github.com/JennJones89.png" width="60px" alt="" /></a><a href="https://github.com/zepled112"><img src="https://github.com/zepled112.png" width="60px" alt="wyatt" /></a><a href="https://github.com/Cube707"><img src="https://github.com/Cube707.png" width="60px" alt="Jan Wille" /></a><a href="https://github.com/Owen-3456"><img src="https://github.com/Owen-3456.png" width="60px" alt="Owen" /></a><a href="https://github.com/altugtekiner"><img src="https://github.com/altugtekiner.png" width="60px" alt="" /></a><a href="https://github.com/getsmor"><img src="https://github.com/getsmor.png" width="60px" alt="" /></a><a href="https://github.com/robertsandrock"><img src="https://github.com/robertsandrock.png" width="60px" alt="" /></a><a href="https://github.com/jeffnesbit"><img src="https://github.com/jeffnesbit.png" width="60px" alt="" /></a><a href="https://github.com/mmomega"><img src="https://github.com/mmomega.png" width="60px" alt="" /></a><a href="https://github.com/KenichiQaz"><img src="https://github.com/KenichiQaz.png" width="60px" alt="Stefan" /></a><a href="https://github.com/thaddl"><img src="https://github.com/thaddl.png" width="60px" alt="thaddl" /></a><a href="https://github.com/paulsheets"><img src="https://github.com/paulsheets.png" width="60px" alt="" /></a><a href="https://github.com/djones369"><img src="https://github.com/djones369.png" width="60px" alt="Dave Jones" /></a><!-- sponsors -->
|
||||||
|
|
||||||
- Install
|
## 🏅 Thanks to all Contributors
|
||||||
- Install Selection: Organize programs by category and facilitate installation by enabling users to select programs and initiate the installation process with a single click.
|
|
||||||
|
|
||||||
- Upgrade All: Upgrade all existing programs to their latest versions, ensuring users have the most up-to-date and feature-rich software.
|
|
||||||
|
|
||||||
- Uninstall Selection: Effortlessly uninstall selected programs, providing users with a streamlined way to remove unwanted software from their system.
|
|
||||||
|
|
||||||
- Get Installed: Retrieve a comprehensive list of installed programs on the system, offering users visibility into the software currently installed on their computer.
|
|
||||||
|
|
||||||
- Import / Export: Enable users to import or export the selection list of programs, allowing them to save their preferred program configurations or share them with others. This feature promotes convenience and flexibility in managing program selections across different systems.
|
|
||||||
|
|
||||||
- Tweaks
|
|
||||||
- Recommended Selection: Provides pre-defined templates tailored for desktop, laptop, and minimal configurations, allowing users to select recommended settings and optimizations specific to their system type.
|
|
||||||
|
|
||||||
- Essential Tweaks: Offers a collection of essential tweaks aimed at improving system performance, privacy, and resource utilization. These tweaks include creating a system restore point, disabling telemetry, Wi-Fi Sense, setting services to manual, disabling location tracking, and HomeGroup, among others.
|
|
||||||
|
|
||||||
- Misc. Tweaks: Encompasses a range of various tweaks to further optimize the system. These tweaks include enabling/disabling power throttling, enabling num lock on startup, removing Cortana and Edge, disabling User Account Control (UAC), notification panel, and configuring TPM during updates, among others.
|
|
||||||
|
|
||||||
- Additional Tweaks: Introduces various other tweaks such as enabling dark mode, changing DNS settings, adding an Ultimate Performance mode, and creating shortcuts for WinUtil tools. These tweaks provide users with additional customization options to tailor their system to their preferences.
|
|
||||||
|
|
||||||
- Config
|
|
||||||
- Features: Allows users to easily install various essential components and features to enhance their Windows experience. These features include installing .NET Frameworks, enabling Hyper-V virtualization, enabling legacy media support for Windows Media Player and DirectPlay, enabling NFS (Network File System) for network file sharing, and enabling Windows Subsystem for Linux (WSL) for running Linux applications on Windows.
|
|
||||||
|
|
||||||
- Fixes: Provides a range of helpful fixes to address common issues and improve system stability. This includes setting up autologon for seamless login experiences, resetting Windows updates to resolve update-related problems, performing a system corruption scan to detect and repair corrupted files, and resetting network settings to troubleshoot network connectivity issues.
|
|
||||||
|
|
||||||
- Legacy Windows Panels: Includes access to legacy Windows panels from Windows 7, allowing users to access familiar and powerful tools. These panels include Control Panel for managing system settings, Network Connections for configuring network adapters and connections, Power Panel for adjusting power and sleep settings, Sound Settings for managing audio devices and settings, System Properties for viewing and modifying system information, and User Accounts for managing user profiles and account settings.
|
|
||||||
|
|
||||||
|
|
||||||
- Updates:
|
|
||||||
- Default (Out of Box) Settings: Provides the default settings that come with Windows for updates.
|
|
||||||
|
|
||||||
- Security (Recommended) Settings: Offers recommended settings, including a slight delay of feature updates by 2 years and installation of security updates 4 days after release.
|
|
||||||
|
|
||||||
- Disable All Updates (Not Recommended!): Allows users to disable all Windows updates, but it's not recommended due to potential security risks.
|
|
||||||
|
|
||||||
|
|
||||||
Video and Written Article walkthrough @ <https://christitus.com/windows-tool/>
|
|
||||||
|
|
||||||
## Issues
|
|
||||||
|
|
||||||
If you encounter any challenges or problems with the script, I kindly request that you submit them via the "Issues" tab on the GitHub repository. By filling out the provided template, you can provide specific details about the issue, allowing me to promptly address any bugs or consider feature requests.
|
|
||||||
|
|
||||||
## Contribute Code
|
|
||||||
|
|
||||||
To contribute new code, please ensure that it is submitted to the **TEST BRANCH**. Please note that merges will not be performed directly on the MAIN branch.
|
|
||||||
|
|
||||||
When creating pull requests, it is essential to thoroughly document all changes made. This includes documenting any additions made to the tweaks section and ensuring that corresponding undo measures are in place to remove the newly added tweaks if necessary. Failure to adhere to this format may result in denial of the pull request. Additionally, comprehensive documentation is required for all code changes. Any code lacking sufficient documentation may also be denied.
|
|
||||||
|
|
||||||
By following these guidelines, we can maintain a high standard of quality and ensure that the codebase remains organized and well-documented.
|
|
||||||
|
|
||||||
NOTE: When creating a function please include "WPF" or "WinUtil" in the name so that it can be loaded into the runspace.
|
|
||||||
|
|
||||||
## 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 🍻.
|
||||||
|
|
||||||
[](https://github.com/ChrisTitusTech/winutil/graphs/contributors)
|
[](https://github.com/ChrisTitusTech/winutil/graphs/contributors)
|
||||||
|
|
||||||
## GitHub Stats
|
## 📊 GitHub Stats
|
||||||
|
|
||||||

|

|
||||||
|
1580
config/applications.json
Executable file → Normal file
@ -1,30 +1,50 @@
|
|||||||
{
|
{
|
||||||
"Google":{
|
"Google":{
|
||||||
"Primary": "8.8.8.8",
|
"Primary": "8.8.8.8",
|
||||||
"Secondary": "8.8.4.4"
|
"Secondary": "8.8.4.4",
|
||||||
|
"Primary6": "2001:4860:4860::8888",
|
||||||
|
"Secondary6": "2001:4860:4860::8844"
|
||||||
},
|
},
|
||||||
"Cloudflare":{
|
"Cloudflare":{
|
||||||
"Primary": "1.1.1.1",
|
"Primary": "1.1.1.1",
|
||||||
"Secondary": "1.0.0.1"
|
"Secondary": "1.0.0.1",
|
||||||
|
"Primary6": "2606:4700:4700::1111",
|
||||||
|
"Secondary6": "2606:4700:4700::1001"
|
||||||
},
|
},
|
||||||
"Cloudflare_Malware":{
|
"Cloudflare_Malware":{
|
||||||
"Primary": "1.1.1.2",
|
"Primary": "1.1.1.2",
|
||||||
"Secondary": "1.0.0.2"
|
"Secondary": "1.0.0.2",
|
||||||
|
"Primary6": "2606:4700:4700::1112",
|
||||||
|
"Secondary6": "2606:4700:4700::1002"
|
||||||
},
|
},
|
||||||
"Cloudflare_Malware_Adult":{
|
"Cloudflare_Malware_Adult":{
|
||||||
"Primary": "1.1.1.3",
|
"Primary": "1.1.1.3",
|
||||||
"Secondary": "1.0.0.3"
|
"Secondary": "1.0.0.3",
|
||||||
},
|
"Primary6": "2606:4700:4700::1113",
|
||||||
"Level3":{
|
"Secondary6": "2606:4700:4700::1003"
|
||||||
"Primary": "4.2.2.2",
|
|
||||||
"Secondary": "4.2.2.1"
|
|
||||||
},
|
},
|
||||||
"Open_DNS":{
|
"Open_DNS":{
|
||||||
"Primary": "208.67.222.222",
|
"Primary": "208.67.222.222",
|
||||||
"Secondary": "208.67.220.220"
|
"Secondary": "208.67.220.220",
|
||||||
|
"Primary6": "2620:119:35::35",
|
||||||
|
"Secondary6": "2620:119:53::53"
|
||||||
},
|
},
|
||||||
"Quad9":{
|
"Quad9":{
|
||||||
"Primary": "9.9.9.9",
|
"Primary": "9.9.9.9",
|
||||||
"Secondary": "149.112.112.112"
|
"Secondary": "149.112.112.112",
|
||||||
|
"Primary6": "2620:fe::fe",
|
||||||
|
"Secondary6": "2620:fe::9"
|
||||||
|
},
|
||||||
|
"AdGuard_Ads_Trackers":{
|
||||||
|
"Primary": "94.140.14.14",
|
||||||
|
"Secondary": "94.140.15.15",
|
||||||
|
"Primary6": "2a10:50c0::ad1:ff",
|
||||||
|
"Secondary6": "2a10:50c0::ad2:ff"
|
||||||
|
},
|
||||||
|
"AdGuard_Ads_Trackers_Malware_Adult":{
|
||||||
|
"Primary": "94.140.14.15",
|
||||||
|
"Secondary": "94.140.15.16",
|
||||||
|
"Primary6": "2a10:50c0::bad1:ff",
|
||||||
|
"Secondary6": "2a10:50c0::bad2:ff"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -184,90 +184,104 @@
|
|||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a060_",
|
"Order": "a060_",
|
||||||
"Type": "150"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelAutologin": {
|
"WPFPanelAutologin": {
|
||||||
"Content": "Set Up Autologin",
|
"Content": "Set Up Autologin",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"Order": "a040_",
|
"Order": "a040_",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "300"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFFixesUpdate": {
|
"WPFFixesUpdate": {
|
||||||
"Content": "Reset Windows Update",
|
"Content": "Reset Windows Update",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a041_",
|
"Order": "a041_",
|
||||||
"Type": "300"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFFixesNetwork": {
|
"WPFFixesNetwork": {
|
||||||
"Content": "Reset Network",
|
"Content": "Reset Network",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"Order": "a042_",
|
"Order": "a042_",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "300"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelDISM": {
|
"WPFPanelDISM": {
|
||||||
"Content": "System Corruption Scan",
|
"Content": "System Corruption Scan",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a043_",
|
"Order": "a043_",
|
||||||
"Type": "300"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFFixesWinget": {
|
"WPFFixesWinget": {
|
||||||
"Content": "WinGet Reinstall",
|
"Content": "WinGet Reinstall",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a044_",
|
"Order": "a044_",
|
||||||
"Type": "300"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFRunAdobeCCCleanerTool": {
|
"WPFRunAdobeCCCleanerTool": {
|
||||||
"Content": "Remove Adobe Creative Cloud",
|
"Content": "Remove Adobe Creative Cloud",
|
||||||
"category": "Fixes",
|
"category": "Fixes",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a045_",
|
"Order": "a045_",
|
||||||
"Type": "300"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelnetwork": {
|
"WPFPanelnetwork": {
|
||||||
"Content": "Network Connections",
|
"Content": "Network Connections",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelcontrol": {
|
"WPFPanelcontrol": {
|
||||||
"Content": "Control Panel",
|
"Content": "Control Panel",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelpower": {
|
"WPFPanelpower": {
|
||||||
"Content": "Power Panel",
|
"Content": "Power Panel",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelregion": {
|
"WPFPanelregion": {
|
||||||
"Content": "Region",
|
"Content": "Region",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelsound": {
|
"WPFPanelsound": {
|
||||||
"Content": "Sound Settings",
|
"Content": "Sound Settings",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPanelsystem": {
|
"WPFPanelsystem": {
|
||||||
"Content": "System Properties",
|
"Content": "System Properties",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
},
|
},
|
||||||
"WPFPaneluser": {
|
"WPFPaneluser": {
|
||||||
"Content": "User Accounts",
|
"Content": "User Accounts",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "200"
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,399 +0,0 @@
|
|||||||
# This file is meant to assist in building out the json files inside this folder.
|
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# applications.json
|
|
||||||
#===========================================================================
|
|
||||||
|
|
||||||
<#
|
|
||||||
Applications.json
|
|
||||||
-----------------
|
|
||||||
This file holds all the install commands to install the applications.
|
|
||||||
This file has the ability to expect multiple frameworks per checkbox.
|
|
||||||
You can also add multiple install commands by separating them with ;
|
|
||||||
|
|
||||||
The structure of the json is as follows
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name of Button": {
|
|
||||||
"winget": "Winget command"
|
|
||||||
"choco": "Chocolatey command"
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
{
|
|
||||||
"WPFInstalladobe": {
|
|
||||||
"winget": "Adobe.Acrobat.Reader.64-bit"
|
|
||||||
"choco": "adobereader"
|
|
||||||
},
|
|
||||||
"WPFInstalladvancedip": {
|
|
||||||
"winget": "Famatech.AdvancedIPScanner"
|
|
||||||
"choco": "advanced-ip-scanner"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#>
|
|
||||||
|
|
||||||
# Modify the variables and run his code. It will import the current file and add your addition. From there you can create a pull request.
|
|
||||||
#------Do not delete WPF------
|
|
||||||
|
|
||||||
$NameofButton = "WPF" + ""
|
|
||||||
$WingetCommand = ""
|
|
||||||
$ChocoCommand = ""
|
|
||||||
|
|
||||||
$ButtonToAdd = New-Object psobject
|
|
||||||
$jsonfile = Get-Content ./config/applications.json | ConvertFrom-Json
|
|
||||||
|
|
||||||
# Remove if already exists
|
|
||||||
if($jsonfile.$NameofButton){
|
|
||||||
$jsonfile.psobject.Properties.remove($NameofButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "Winget" -Value $WingetCommand
|
|
||||||
Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "choco" -Value $ChocoCommand
|
|
||||||
Add-Member -InputObject $jsonfile.install -MemberType NoteProperty -Name $NameofButton -Value $ButtonToAdd
|
|
||||||
|
|
||||||
$jsonfile | ConvertTo-Json | Out-File ./config/applications.json
|
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# feature.json
|
|
||||||
#===========================================================================
|
|
||||||
|
|
||||||
<#
|
|
||||||
feature.json
|
|
||||||
-----------------
|
|
||||||
This file holds all the windows commands to install specific features (IE Hyper-v)
|
|
||||||
|
|
||||||
The structure of the json is as follows
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name of Button": [
|
|
||||||
"Array of",
|
|
||||||
"commands"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Example:
|
|
||||||
{
|
|
||||||
"Featurewsl": [
|
|
||||||
"VirtualMachinePlatform",
|
|
||||||
"Microsoft-Windows-Subsystem-Linux"
|
|
||||||
],
|
|
||||||
"Featurenfs": [
|
|
||||||
"ServicesForNFS-ClientOnly",
|
|
||||||
"ClientForNFS-Infrastructure",
|
|
||||||
"NFS-Administration"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
#>
|
|
||||||
|
|
||||||
# Modify the variables and run his code. It will import the current file and add your addition. From there you can create a pull request.
|
|
||||||
|
|
||||||
$NameofButton = ""
|
|
||||||
$commands = @(
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
$jsonfile = Get-Content ./config/feature.json | ConvertFrom-Json
|
|
||||||
|
|
||||||
# Remove if already exists
|
|
||||||
if($jsonfile.$NameofButton){
|
|
||||||
$jsonfile.psobject.Properties.remove($NameofButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
Add-Member -InputObject $jsonfile -MemberType NoteProperty -Name $NameofButton -Value $commands
|
|
||||||
|
|
||||||
$jsonfile | ConvertTo-Json | Out-File ./config/feature.json
|
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# preset.json
|
|
||||||
#===========================================================================
|
|
||||||
|
|
||||||
<#
|
|
||||||
preset.json
|
|
||||||
-----------------
|
|
||||||
This file holds all check boxes you wish to check when clicking a preset button in the tweaks section.
|
|
||||||
|
|
||||||
The structure of the json is as follows
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name of Button": [
|
|
||||||
"Array of",
|
|
||||||
"checkboxes to check"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Example:
|
|
||||||
{
|
|
||||||
"laptop": [
|
|
||||||
"EssTweaksAH",
|
|
||||||
"EssTweaksDVR",
|
|
||||||
"EssTweaksHome",
|
|
||||||
"EssTweaksLoc",
|
|
||||||
"EssTweaksOO",
|
|
||||||
"EssTweaksRP",
|
|
||||||
"EssTweaksServices",
|
|
||||||
"EssTweaksStorage",
|
|
||||||
"EssTweaksTele",
|
|
||||||
"EssTweaksWifi",
|
|
||||||
"MiscTweaksLapPower",
|
|
||||||
"MiscTweaksLapNum"
|
|
||||||
],
|
|
||||||
"minimal": [
|
|
||||||
"EssTweaksHome",
|
|
||||||
"EssTweaksOO",
|
|
||||||
"EssTweaksRP",
|
|
||||||
"EssTweaksServices",
|
|
||||||
"EssTweaksTele"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
#>
|
|
||||||
|
|
||||||
# Modify the variables and run his code. It will import the current file and add your addition. From there you can create a pull request.
|
|
||||||
|
|
||||||
$NameofButton = "WPF" + ""
|
|
||||||
$commands = @(
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
$jsonfile = Get-Content ./config/preset.json | ConvertFrom-Json
|
|
||||||
|
|
||||||
# Remove if already exists
|
|
||||||
if($jsonfile.$NameofButton){
|
|
||||||
$jsonfile.psobject.Properties.remove($NameofButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
Add-Member -InputObject $jsonfile -MemberType NoteProperty -Name $NameofButton -Value $commands
|
|
||||||
|
|
||||||
$jsonfile | ConvertTo-Json | Out-File ./config/preset.json
|
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# tweaks.json
|
|
||||||
#===========================================================================
|
|
||||||
|
|
||||||
<#
|
|
||||||
tweaks.json
|
|
||||||
-----------------
|
|
||||||
This file holds all the tweaks needed to make modifications to windows. This file is the most complicated so modify with care.
|
|
||||||
|
|
||||||
The structure of the json is as follows
|
|
||||||
|
|
||||||
{
|
|
||||||
"Name of button": {
|
|
||||||
"registry" : [
|
|
||||||
{
|
|
||||||
"Path": "Path in registry",
|
|
||||||
"Name": "Name of Registry key",
|
|
||||||
"Type": "Item type",
|
|
||||||
"Value": "Value to modify",
|
|
||||||
"OriginalValue": "value to reset"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"service" : [
|
|
||||||
{
|
|
||||||
"Name": "Name of service",
|
|
||||||
"StartupType": "Startup type to set",
|
|
||||||
"OriginalType": "Startup type to reset"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"ScheduledTask" : [
|
|
||||||
{
|
|
||||||
"Name": "Path to scheduled task",
|
|
||||||
"State": "State to set",
|
|
||||||
"OriginalState": "State to reset"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"appx": [
|
|
||||||
List of appx,
|
|
||||||
files to uninstall
|
|
||||||
],
|
|
||||||
"InvokeScript": [
|
|
||||||
"Script to make modifications not possible with the above types
|
|
||||||
Special care needs to be taken here as converting from json to a scriptblock
|
|
||||||
can cause weird issues. Please look at the example below to get an idea of how things should work"
|
|
||||||
],
|
|
||||||
"UndoScript": [
|
|
||||||
"Same as above however is meant to undo what you did above"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
{
|
|
||||||
EssTweaksAH": {
|
|
||||||
"registry" : [
|
|
||||||
{
|
|
||||||
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System",
|
|
||||||
"Name": "EnableActivityFeed",
|
|
||||||
"Type": "DWord",
|
|
||||||
"Value": "0",
|
|
||||||
"OriginalValue": "1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System",
|
|
||||||
"Name": "PublishUserActivities",
|
|
||||||
"Type": "DWord",
|
|
||||||
"Value": "0",
|
|
||||||
"OriginalValue": "1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"EssTweaksHome": {
|
|
||||||
"service" : [
|
|
||||||
{
|
|
||||||
"Name": "HomeGroupListener",
|
|
||||||
"StartupType": "Manual",
|
|
||||||
"OriginalType": "Automatic"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "HomeGroupProvider",
|
|
||||||
"StartupType": "Manual",
|
|
||||||
"OriginalType": "Automatic"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"EssTweaksTele": {
|
|
||||||
"ScheduledTask" : [
|
|
||||||
{
|
|
||||||
"Name": "Microsoft\\Windows\\Application Experience\\Microsoft Compatibility Appraiser",
|
|
||||||
"State": "Disabled",
|
|
||||||
"OriginalState": "Enabled"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Name": "Microsoft\\Windows\\Application Experience\\ProgramDataUpdater",
|
|
||||||
"State": "Disabled",
|
|
||||||
"OriginalState": "Enabled"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"EssTweaksDeBloat": {
|
|
||||||
"appx": [
|
|
||||||
"Microsoft.Microsoft3DViewer",
|
|
||||||
"Microsoft.AppConnector"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"EssTweaksOO": {
|
|
||||||
"InvokeScript": [
|
|
||||||
"Import-Module BitsTransfer
|
|
||||||
Start-BitsTransfer -Source \"https://raw.githubusercontent.com/ChrisTitusTech/win10script/master/ooshutup10.cfg\" -Destination C:\\Windows\\Temp\\ooshutup10.cfg
|
|
||||||
Start-BitsTransfer -Source \"https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe\" -Destination C:\\Windows\\Temp\\OOSU10.exe
|
|
||||||
C:\\Windows\\Temp\\OOSU10.exe C:\\Windows\\Temp\\ooshutup10.cfg /quiet"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#>
|
|
||||||
|
|
||||||
# Modify the variables and run his code. It will import the current file and add your addition. From there you can create a pull request.
|
|
||||||
# Make sure to uncomment the sections you which to add.
|
|
||||||
|
|
||||||
#$Registry = @(
|
|
||||||
# # To add more repeat this separated by a comma
|
|
||||||
# @{
|
|
||||||
# Path = ""
|
|
||||||
# Name = ""
|
|
||||||
# Type = ""
|
|
||||||
# Value = ""
|
|
||||||
# OriginalValue = ""
|
|
||||||
# }
|
|
||||||
#)
|
|
||||||
|
|
||||||
#$Service = @(
|
|
||||||
# # To add more repeat this separated by a comma
|
|
||||||
# @{
|
|
||||||
# Name = ""
|
|
||||||
# StartupType = ""
|
|
||||||
# OriginalType = ""
|
|
||||||
# }
|
|
||||||
#)
|
|
||||||
|
|
||||||
#$ScheduledTask = @(
|
|
||||||
# # To add more repeat this separated by a comma
|
|
||||||
# @{
|
|
||||||
# Name = ""
|
|
||||||
# State = ""
|
|
||||||
# OriginalState = ""
|
|
||||||
# }
|
|
||||||
#)
|
|
||||||
|
|
||||||
#$Appx = @(
|
|
||||||
# ""
|
|
||||||
#)
|
|
||||||
|
|
||||||
#$InvokeScript = @(
|
|
||||||
# ""
|
|
||||||
#)
|
|
||||||
|
|
||||||
#$UndoScript = @(
|
|
||||||
# ""
|
|
||||||
#)
|
|
||||||
|
|
||||||
$NameofButton = "WPF" + ""
|
|
||||||
|
|
||||||
$ButtonToAdd = New-Object psobject
|
|
||||||
$jsonfile = Get-Content ./config/tweaks.json | ConvertFrom-Json
|
|
||||||
|
|
||||||
# Remove if already exists
|
|
||||||
if($jsonfile.$NameofButton){
|
|
||||||
$jsonfile.psobject.Properties.remove($NameofButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
if($Registry){Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "registry" -Value $Registry}
|
|
||||||
if($Service){Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "service" -Value $Service}
|
|
||||||
if($ScheduledTask){Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "ScheduledTask" -Value $ScheduledTask}
|
|
||||||
if($Appx){Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "Appx" -Value $Appx}
|
|
||||||
if($InvokeScript){Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "InvokeScript" -Value $InvokeScript}
|
|
||||||
if($UndoScript){Add-Member -InputObject $ButtonToAdd -MemberType NoteProperty -Name "UndoScript" -Value $UndoScript}
|
|
||||||
|
|
||||||
Add-Member -InputObject $jsonfile -MemberType NoteProperty -Name $NameofButton -Value $ButtonToAdd
|
|
||||||
|
|
||||||
($jsonfile | ConvertTo-Json -Depth 5).replace('\r\n',"`r`n") | Out-File ./config/tweaks.json
|
|
||||||
|
|
||||||
#===========================================================================
|
|
||||||
# dns.json
|
|
||||||
#===========================================================================
|
|
||||||
|
|
||||||
<#
|
|
||||||
dns.json
|
|
||||||
-----------------
|
|
||||||
This file holds all the DNS entries.
|
|
||||||
|
|
||||||
The structure of the json is as follows
|
|
||||||
|
|
||||||
{
|
|
||||||
"DNS Provider": [
|
|
||||||
"Primary": "IP address",
|
|
||||||
"Secondary": "IP address"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Example:
|
|
||||||
{
|
|
||||||
"Cloudflare":{
|
|
||||||
"Primary": "1.1.1.1",
|
|
||||||
"Secondary": "1.0.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#>
|
|
||||||
|
|
||||||
# Modify the variables and run his code. It will import the current file and add your addition. From there you can create a pull request.
|
|
||||||
|
|
||||||
$NameofProvider = "" -replace " ","_"
|
|
||||||
$IPAddress = @{
|
|
||||||
"Primary" = "0.0.0.0"
|
|
||||||
"Secondary" = "0.0.0.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
$ButtonToAdd = New-Object psobject
|
|
||||||
$jsonfile = Get-Content ./config/dns.json | ConvertFrom-Json
|
|
||||||
|
|
||||||
# Remove if already exists
|
|
||||||
if($jsonfile.$NameofProvider){
|
|
||||||
$jsonfile.psobject.Properties.remove($NameofProvider)
|
|
||||||
}
|
|
||||||
|
|
||||||
Add-Member -InputObject $jsonfile -MemberType NoteProperty -Name $NameofProvider -Value $IPAddress
|
|
||||||
|
|
||||||
($jsonfile | ConvertTo-Json -Depth 5).replace('\r\n',"`r`n") | Out-File ./config/dns.json
|
|
@ -1,32 +1,25 @@
|
|||||||
{
|
{
|
||||||
"desktop": [
|
"Standard": [
|
||||||
"WPFTweaksAH",
|
"WPFTweaksAH",
|
||||||
|
"WPFTweaksConsumerFeatures",
|
||||||
"WPFTweaksDVR",
|
"WPFTweaksDVR",
|
||||||
"WPFTweaksHiber",
|
"WPFTweaksHiber",
|
||||||
"WPFTweaksHome",
|
"WPFTweaksHome",
|
||||||
"WPFTweaksLoc",
|
"WPFTweaksLoc",
|
||||||
"WPFTweaksOO",
|
|
||||||
"WPFTweaksServices",
|
"WPFTweaksServices",
|
||||||
"WPFTweaksStorage",
|
"WPFTweaksStorage",
|
||||||
"WPFTweaksTele",
|
"WPFTweaksTele",
|
||||||
"WPFTweaksWifi",
|
"WPFTweaksWifi",
|
||||||
"WPFMiscTweaksPower"
|
"WPFTweaksDiskCleanup",
|
||||||
|
"WPFTweaksDeleteTempFiles",
|
||||||
|
"WPFTweaksEndTaskOnTaskbar",
|
||||||
|
"WPFTweaksRestorePoint",
|
||||||
|
"WPFTweaksTeredo",
|
||||||
|
"WPFTweaksPowershell7Tele"
|
||||||
],
|
],
|
||||||
"laptop": [
|
"Minimal": [
|
||||||
"WPFTweaksAH",
|
"WPFTweaksConsumerFeatures",
|
||||||
"WPFTweaksDVR",
|
|
||||||
"WPFTweaksHome",
|
"WPFTweaksHome",
|
||||||
"WPFTweaksLoc",
|
|
||||||
"WPFTweaksOO",
|
|
||||||
"WPFTweaksServices",
|
|
||||||
"WPFTweaksStorage",
|
|
||||||
"WPFTweaksTele",
|
|
||||||
"WPFTweaksWifi",
|
|
||||||
"WPFMiscTweaksLapPower"
|
|
||||||
],
|
|
||||||
"minimal": [
|
|
||||||
"WPFTweaksHome",
|
|
||||||
"WPFTweaksOO",
|
|
||||||
"WPFTweaksServices",
|
"WPFTweaksServices",
|
||||||
"WPFTweaksTele"
|
"WPFTweaksTele"
|
||||||
]
|
]
|
||||||
|
@ -1,14 +1,51 @@
|
|||||||
{
|
{
|
||||||
"Classic": {
|
"Classic": {
|
||||||
|
"CustomDialogFontSize": "12",
|
||||||
|
"CustomDialogFontSizeHeader": "14",
|
||||||
|
"CustomDialogIconSize": "25",
|
||||||
|
"CustomDialogWidth": "400",
|
||||||
|
"CustomDialogHeight": "200",
|
||||||
|
|
||||||
|
"FontSize": "12",
|
||||||
|
"FontFamily": "Arial",
|
||||||
|
"FontSizeHeading": "14",
|
||||||
|
"HeaderFontFamily": "Consolas, Monaco",
|
||||||
|
|
||||||
|
"CheckBoxBulletDecoratorFontSize": "14",
|
||||||
|
"CheckBoxMargin": "15,0,0,2",
|
||||||
|
|
||||||
|
"TabButtonFontSize": "14",
|
||||||
|
"TabButtonWidth": "100",
|
||||||
|
"TabButtonHeight": "25",
|
||||||
|
"TabRowHeightInPixels": "50",
|
||||||
|
"IconFontSize": "14",
|
||||||
|
"IconButtonSize": "35",
|
||||||
|
"WinUtilIconSize": "Auto",
|
||||||
|
"SettingsIconFontSize": "18",
|
||||||
|
|
||||||
|
"MicroWinLogoSize": "10",
|
||||||
|
|
||||||
"ComboBoxBackgroundColor": "#FFFFFF",
|
"ComboBoxBackgroundColor": "#FFFFFF",
|
||||||
"LabelboxForegroundColor": "#000000",
|
"LabelboxForegroundColor": "#000000",
|
||||||
"MainForegroundColor": "#000000",
|
"MainForegroundColor": "#000000",
|
||||||
"MainBackgroundColor": "#FFFFFF",
|
"MainBackgroundColor": "#FFFFFF",
|
||||||
"LabelBackgroundColor": "#FAFAFA",
|
"LabelBackgroundColor": "#FAFAFA",
|
||||||
"LinkForegroundColor": "#000000",
|
"LinkForegroundColor": "#000000",
|
||||||
"LinkHoverForegroundColor": "#000000",
|
"LinkHoverForegroundColor": "#000000",
|
||||||
"GroupBorderBackgroundColor": "#000000",
|
"GroupBorderBackgroundColor": "#000000",
|
||||||
"ComboBoxForegroundColor": "#000000",
|
"ComboBoxForegroundColor": "#000000",
|
||||||
|
|
||||||
|
"ButtonFontSize": "12",
|
||||||
|
"ButtonFontFamily": "Arial",
|
||||||
|
"ButtonWidth": "200",
|
||||||
|
"ButtonHeight": "25",
|
||||||
|
"ConfigTabButtonFontSize": "16",
|
||||||
|
|
||||||
|
"SearchBarWidth": "200",
|
||||||
|
"SearchBarHeight": "25",
|
||||||
|
"SearchBarTextBoxFontSize": "16",
|
||||||
|
"SearchBarClearButtonFontSize": "14",
|
||||||
|
|
||||||
"ButtonInstallBackgroundColor": "#FFFFFF",
|
"ButtonInstallBackgroundColor": "#FFFFFF",
|
||||||
"ButtonTweaksBackgroundColor": "#FFFFFF",
|
"ButtonTweaksBackgroundColor": "#FFFFFF",
|
||||||
"ButtonConfigBackgroundColor": "#FFFFFF",
|
"ButtonConfigBackgroundColor": "#FFFFFF",
|
||||||
@ -23,42 +60,149 @@
|
|||||||
"ButtonBackgroundMouseoverColor": "#C2C2C2",
|
"ButtonBackgroundMouseoverColor": "#C2C2C2",
|
||||||
"ButtonBackgroundSelectedColor": "#F0F0F0",
|
"ButtonBackgroundSelectedColor": "#F0F0F0",
|
||||||
"ButtonForegroundColor": "#000000",
|
"ButtonForegroundColor": "#000000",
|
||||||
|
"ToggleButtonOnColor": "#2e77ff",
|
||||||
|
|
||||||
"ButtonBorderThickness": "1",
|
"ButtonBorderThickness": "1",
|
||||||
"ButtonMargin": "1",
|
"ButtonMargin": "1",
|
||||||
"ButtonCornerRadius": "2",
|
"ButtonCornerRadius": "2",
|
||||||
"ToggleButtonHeight": "25",
|
|
||||||
"BorderColor": "#000000",
|
"BorderColor": "#000000",
|
||||||
"BorderOpacity": "0.2",
|
"BorderOpacity": "0.2",
|
||||||
"ShadowPulse": "Forever"
|
"ShadowPulse": "Forever"
|
||||||
},
|
},
|
||||||
"Matrix": {
|
"Matrix": {
|
||||||
"ComboBoxBackgroundColor": "#000000",
|
"CustomDialogFontSize": "12",
|
||||||
"LabelboxForegroundColor": "#FFEE58",
|
"CustomDialogFontSizeHeader": "14",
|
||||||
"MainForegroundColor": "#9CCC65",
|
"CustomDialogIconSize": "25",
|
||||||
"MainBackgroundColor": "#000000",
|
"CustomDialogWidth": "400",
|
||||||
"LabelBackgroundColor": "#000000",
|
"CustomDialogHeight": "200",
|
||||||
"LinkForegroundColor": "#add8e6",
|
|
||||||
"LinkHoverForegroundColor": "#FFFFFF",
|
"FontSize": "12",
|
||||||
"ComboBoxForegroundColor": "#FFEE58",
|
"FontFamily": "Arial",
|
||||||
"ButtonInstallBackgroundColor": "#222222",
|
"FontSizeHeading": "14",
|
||||||
"ButtonTweaksBackgroundColor": "#333333",
|
"HeaderFontFamily": "Consolas, Monaco",
|
||||||
"ButtonConfigBackgroundColor": "#444444",
|
|
||||||
"ButtonUpdatesBackgroundColor": "#555555",
|
"CheckBoxBulletDecoratorFontSize": "14",
|
||||||
"ButtonInstallForegroundColor": "#FFFFFF",
|
"CheckBoxMargin": "15,0,0,2",
|
||||||
"ButtonTweaksForegroundColor": "#FFFFFF",
|
|
||||||
"ButtonConfigForegroundColor": "#FFFFFF",
|
"TabButtonFontSize": "14",
|
||||||
"ButtonUpdatesForegroundColor": "#FFFFFF",
|
"TabButtonWidth": "100",
|
||||||
"ButtonBackgroundColor": "#000019",
|
"TabButtonHeight": "25",
|
||||||
"ButtonBackgroundPressedColor": "#FFFFFF",
|
"TabRowHeightInPixels": "50",
|
||||||
"ButtonBackgroundMouseoverColor": "#A55A64",
|
"IconFontSize": "14",
|
||||||
"ButtonBackgroundSelectedColor": "#FF5733",
|
"IconButtonSize": "35",
|
||||||
"ButtonForegroundColor": "#9CCC65",
|
"WinUtilIconSize": "Auto",
|
||||||
"ButtonBorderThickness": "1",
|
"SettingsIconFontSize": "18",
|
||||||
"ButtonMargin": "1",
|
|
||||||
"ButtonCornerRadius": "2",
|
"MicroWinLogoSize": "10",
|
||||||
"ToggleButtonHeight": "25",
|
|
||||||
"BorderColor": "#FFAC1C",
|
"ComboBoxBackgroundColor": "#000000",
|
||||||
"BorderOpacity": "0.8",
|
"LabelboxForegroundColor": "#FFEE58",
|
||||||
"ShadowPulse": "0:0:3"
|
"MainForegroundColor": "#9CCC65",
|
||||||
|
"MainBackgroundColor": "#000000",
|
||||||
|
"LabelBackgroundColor": "#000000",
|
||||||
|
"LinkForegroundColor": "#add8e6",
|
||||||
|
"LinkHoverForegroundColor": "#FFFFFF",
|
||||||
|
"ComboBoxForegroundColor": "#FFEE58",
|
||||||
|
|
||||||
|
"ButtonFontSize": "12",
|
||||||
|
"ButtonFontFamily": "Arial",
|
||||||
|
"ButtonWidth": "200",
|
||||||
|
"ButtonHeight": "25",
|
||||||
|
"ConfigTabButtonFontSize": "16",
|
||||||
|
|
||||||
|
"SearchBarWidth": "200",
|
||||||
|
"SearchBarHeight": "25",
|
||||||
|
"SearchBarTextBoxFontSize": "16",
|
||||||
|
"SearchBarClearButtonFontSize": "14",
|
||||||
|
|
||||||
|
"ButtonInstallBackgroundColor": "#222222",
|
||||||
|
"ButtonTweaksBackgroundColor": "#333333",
|
||||||
|
"ButtonConfigBackgroundColor": "#444444",
|
||||||
|
"ButtonUpdatesBackgroundColor": "#555555",
|
||||||
|
"ButtonInstallForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonTweaksForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonConfigForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonUpdatesForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonBackgroundColor": "#000019",
|
||||||
|
"ButtonBackgroundPressedColor": "#FFFFFF",
|
||||||
|
"ButtonBackgroundMouseoverColor": "#A55A64",
|
||||||
|
"ButtonBackgroundSelectedColor": "#FF5733",
|
||||||
|
"ButtonForegroundColor": "#9CCC65",
|
||||||
|
"ToggleButtonOnColor": "#2e77ff",
|
||||||
|
|
||||||
|
"ButtonBorderThickness": "1",
|
||||||
|
"ButtonMargin": "1",
|
||||||
|
"ButtonCornerRadius": "2",
|
||||||
|
"BorderColor": "#FFAC1C",
|
||||||
|
"BorderOpacity": "0.8",
|
||||||
|
"ShadowPulse": "0:0:3"
|
||||||
|
},
|
||||||
|
"Dark": {
|
||||||
|
"CustomDialogFontSize": "12",
|
||||||
|
"CustomDialogFontSizeHeader": "14",
|
||||||
|
"CustomDialogIconSize": "25",
|
||||||
|
"CustomDialogWidth": "400",
|
||||||
|
"CustomDialogHeight": "200",
|
||||||
|
|
||||||
|
"FontSize": "12",
|
||||||
|
"FontFamily": "Arial",
|
||||||
|
"FontSizeHeading": "14",
|
||||||
|
"HeaderFontFamily": "Consolas, Monaco",
|
||||||
|
|
||||||
|
"CheckBoxBulletDecoratorFontSize": "14",
|
||||||
|
"CheckBoxMargin": "15,0,0,2",
|
||||||
|
|
||||||
|
"TabButtonFontSize": "14",
|
||||||
|
"TabButtonWidth": "100",
|
||||||
|
"TabButtonHeight": "25",
|
||||||
|
"TabRowHeightInPixels": "50",
|
||||||
|
"IconFontSize": "14",
|
||||||
|
"IconButtonSize": "35",
|
||||||
|
"WinUtilIconSize": "Auto",
|
||||||
|
"SettingsIconFontSize": "18",
|
||||||
|
|
||||||
|
"MicroWinLogoSize": "10",
|
||||||
|
|
||||||
|
"ComboBoxBackgroundColor": "#000000",
|
||||||
|
"LabelboxForegroundColor": "#FFEE58",
|
||||||
|
"MainForegroundColor": "#9CCC65",
|
||||||
|
"MainBackgroundColor": "#000000",
|
||||||
|
"LabelBackgroundColor": "#000000",
|
||||||
|
"LinkForegroundColor": "#add8e6",
|
||||||
|
"LinkHoverForegroundColor": "#FFFFFF",
|
||||||
|
"ComboBoxForegroundColor": "#FFEE58",
|
||||||
|
|
||||||
|
"ButtonFontSize": "12",
|
||||||
|
"ButtonFontFamily": "Arial",
|
||||||
|
"ButtonWidth": "200",
|
||||||
|
"ButtonHeight": "25",
|
||||||
|
"ConfigTabButtonFontSize": "16",
|
||||||
|
|
||||||
|
"SearchBarWidth": "200",
|
||||||
|
"SearchBarHeight": "25",
|
||||||
|
"SearchBarTextBoxFontSize": "16",
|
||||||
|
"SearchBarClearButtonFontSize": "14",
|
||||||
|
|
||||||
|
"ButtonInstallBackgroundColor": "#222222",
|
||||||
|
"ButtonTweaksBackgroundColor": "#333333",
|
||||||
|
"ButtonConfigBackgroundColor": "#444444",
|
||||||
|
"ButtonUpdatesBackgroundColor": "#555555",
|
||||||
|
"ButtonInstallForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonTweaksForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonConfigForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonUpdatesForegroundColor": "#FFFFFF",
|
||||||
|
"ButtonBackgroundColor": "#000019",
|
||||||
|
"ButtonBackgroundPressedColor": "#9CCC65",
|
||||||
|
"ButtonBackgroundMouseoverColor": "#FF5733",
|
||||||
|
"ButtonBackgroundSelectedColor": "#FF5733",
|
||||||
|
"ButtonForegroundColor": "#9CCC65",
|
||||||
|
"ToggleButtonOnColor": "#2e77ff",
|
||||||
|
|
||||||
|
"ButtonBorderThickness": "1",
|
||||||
|
"ButtonMargin": "1",
|
||||||
|
"ButtonCornerRadius": "2",
|
||||||
|
"BorderColor": "#FFAC1C",
|
||||||
|
"BorderOpacity": "0.2",
|
||||||
|
"ShadowPulse": "Forever"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
179
docs/KnownIssues.md
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
### Launch Issues:
|
||||||
|
|
||||||
|
- Windows Security (formerly Defender) and other anti-virus software are known to block the script. The script gets flagged due to the fact that it requires administrator privileges & makes drastic system changes.
|
||||||
|
- If possible: Allow script in Anti-Virus software settings.
|
||||||
|
|
||||||
|
- If you are having TLS 1.2 issues, or are having trouble resolving `christitus.com/win` then run with the following command:
|
||||||
|
|
||||||
|
```ps1
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;iex(New-Object Net.WebClient).DownloadString('https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1')
|
||||||
|
```
|
||||||
|
|
||||||
|
- If you are unable to resolve `christitus.com/win` and are getting errors launching the tool, it might be due to India blocking GitHub's content domain and preventing downloads.
|
||||||
|
- Source: <https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms>
|
||||||
|
|
||||||
|
If you are still having issues try using a **VPN**, or changing your **DNS provider** to one of following two providers:
|
||||||
|
|
||||||
|
| Provider | Primary DNS | Secondary DNS |
|
||||||
|
|:------------:|:------------:|:-------------:|
|
||||||
|
| Cloudflare | `1.1.1.1` | `1.0.0.1` |
|
||||||
|
| Google | `8.8.8.8` | `8.8.4.4` |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- Script doesn't run/PowerShell crashes:
|
||||||
|
1. Press Windows Key+X and select 'PowerShell (Admin)' (Windows 10) or 'Windows Terminal (Admin)' (Windows 11)
|
||||||
|
2. Run:
|
||||||
|
```ps1
|
||||||
|
Set-ExecutionPolicy Unrestricted -Scope Process -Force
|
||||||
|
```
|
||||||
|
3. Run:
|
||||||
|
```ps1
|
||||||
|
irm christitus.com/win | iex
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other Issues:
|
||||||
|
|
||||||
|
- Windows taking longer to shut down:
|
||||||
|
- [#69](https://github.com/ChrisTitusTech/winutil/issues/69) Turn on fast startup: Press Windows key + R, then type:
|
||||||
|
```
|
||||||
|
control /name Microsoft.PowerOptions /page pageGlobalSettings
|
||||||
|
```
|
||||||
|
- If that doesn't work, Disable Hibernation: Press Windows Key+X and select 'PowerShell (Admin)' (Windows 10) or 'Windows Terminal (Admin)' (Windows 11) and enter:
|
||||||
|
```ps1
|
||||||
|
powercfg /H off
|
||||||
|
```
|
||||||
|
- [#69](https://github.com/ChrisTitusTech/winutil/issues/69) [95](https://github.com/ChrisTitusTech/winutil/issues/95) [#232](https://github.com/ChrisTitusTech/winutil/issues/232) Windows Search does not work: Enable Background Apps
|
||||||
|
- [#198](https://github.com/ChrisTitusTech/winutil/issues/198) Xbox Game Bar Activation Broken: Set the Xbox Accessory Management Service to Automatic
|
||||||
|
```ps1
|
||||||
|
Get-Service -Name "XboxGipSvc" | Set-Service -StartupType Automatic
|
||||||
|
```
|
||||||
|
|
||||||
|
- Winget requires interaction on first run: Manually type 'y' and 'enter' into the PowerShell console to continue
|
||||||
|
- (Windows 11) Quick Settings no longer works: Launch the Script and click 'Enable Action Center'
|
||||||
|
|
||||||
|
- Explorer no longer launches: Go to Control Panel, File Explorer Options, Change the 'Open File Explorer to' option to 'This PC'.
|
||||||
|
|
||||||
|
### Battery drains too fast.
|
||||||
|
* When your battery on the laptop drains too fast, please perform these steps and report the results back to the Winutil community.
|
||||||
|
|
||||||
|
1. **Check Battery Health:**
|
||||||
|
- Open a Command Prompt as an administrator.
|
||||||
|
- Run the following command to generate a battery report:
|
||||||
|
```powershell
|
||||||
|
powercfg /batteryreport /output "C:\battery_report.html"
|
||||||
|
```
|
||||||
|
- Open the generated HTML report to review information about battery health and usage.
|
||||||
|
|
||||||
|
2. **Review Power Settings:**
|
||||||
|
- Go to "Settings" > "System" > "Power & sleep."
|
||||||
|
- Adjust power plan settings based on your preferences and usage patterns.
|
||||||
|
- Click on "Additional power settings" to access advanced power settings.
|
||||||
|
|
||||||
|
3. **Identify Power-Hungry Apps:**
|
||||||
|
- Right-click on the taskbar and select "Task Manager."
|
||||||
|
- Navigate to the "Processes" tab to identify applications with high CPU or memory usage.
|
||||||
|
- Consider closing unnecessary background applications.
|
||||||
|
|
||||||
|
4. **Update Drivers:**
|
||||||
|
- Visit your laptop manufacturer's website or use Windows Update to check for driver updates.
|
||||||
|
- Ensure graphics, chipset, and other essential drivers are up to date.
|
||||||
|
|
||||||
|
5. **Check for Windows Updates:**
|
||||||
|
- Go to "Settings" > "Update & Security" > "Windows Update."
|
||||||
|
- Check for and install any available updates for your operating system.
|
||||||
|
|
||||||
|
6. **Reduce Screen Brightness:**
|
||||||
|
- Adjust screen brightness based on your preferences and lighting conditions.
|
||||||
|
- Go to "Settings" > "System" > "Display" to adjust brightness.
|
||||||
|
|
||||||
|
7. **Battery Saver Mode:**
|
||||||
|
- Go to "Settings" > "System" > "Battery."
|
||||||
|
- Turn on "Battery saver" to limit background activity and conserve power.
|
||||||
|
|
||||||
|
8. **Check Power Usage in Settings:**
|
||||||
|
- Go to "Settings" > "System" > "Battery" > "Battery usage by app."
|
||||||
|
- Review the list of apps and their power usage.
|
||||||
|
|
||||||
|
9. **Check Background Apps:**
|
||||||
|
- Go to "Settings" > "Privacy" > "Background apps."
|
||||||
|
- Disable unnecessary apps running in the background.
|
||||||
|
|
||||||
|
10. **Use Powercfg for Analysis:**
|
||||||
|
- Open a Command Prompt as an administrator.
|
||||||
|
- Run the following command to analyze energy usage and generate a report:
|
||||||
|
```powershell
|
||||||
|
powercfg /energy /output "C:\energy_report.html"
|
||||||
|
```
|
||||||
|
- Open the generated HTML report to identify energy consumption patterns.
|
||||||
|
|
||||||
|
11. **Review Event Viewer:**
|
||||||
|
- Open Event Viewer by searching for it in the Start menu.
|
||||||
|
- Navigate to "Windows Logs" > "System."
|
||||||
|
- Look for events with the source "Power-Troubleshooter" to identify power-related events.
|
||||||
|
|
||||||
|
12. **Check Wake-up Sources:**
|
||||||
|
- Open a Command Prompt as an administrator.
|
||||||
|
- Use the command `powercfg /requests` to identify processes preventing sleep.
|
||||||
|
- Check Task Scheduler for tasks waking up the computer.
|
||||||
|
- Use the command `powercfg /waketimers` to view active wake timers.
|
||||||
|
|
||||||
|
13. **Resource Monitor:**
|
||||||
|
- Open Resource Monitor from the Start menu.
|
||||||
|
- Navigate to the "CPU" tab and identify processes with high CPU usage.
|
||||||
|
|
||||||
|
14. **Windows Settings - Activity History:**
|
||||||
|
- In "Settings," go to "Privacy" > "Activity history."
|
||||||
|
- Turn off "Let Windows collect my activities from this PC."
|
||||||
|
|
||||||
|
15. **Network Adapters:**
|
||||||
|
- Open Device Manager by searching for it in the Start menu.
|
||||||
|
- Locate your network adapter, right-click, and go to "Properties."
|
||||||
|
- Under the "Power Management" tab, uncheck the option that allows the device to wake the computer.
|
||||||
|
|
||||||
|
16. **Review Installed Applications:**
|
||||||
|
- Manually review installed applications by searching for "Add or remove programs" in the Start menu.
|
||||||
|
- Check settings/preferences of individual applications for power-related options.
|
||||||
|
- Uninstall unnecessary or problematic software.
|
||||||
|
|
||||||
|
* By following these detailed instructions, you should be able to thoroughly diagnose and address battery drain issues on your Windows laptop. Adjust settings as needed to optimize power management and improve battery life.
|
||||||
|
|
||||||
|
### Troubleshoot errors during Microwin usage
|
||||||
|
|
||||||
|
#### Error `0x80041031`
|
||||||
|
|
||||||
|
* This error code typically indicates an issue related to Windows Management Instrumentation (WMI). Here are a few steps you can try to resolve the issue:
|
||||||
|
|
||||||
|
1. **Reboot Your Computer:**
|
||||||
|
Sometimes, a simple reboot can resolve temporary issues. Restart your computer and try mounting the ISO again.
|
||||||
|
|
||||||
|
2. **Check for System Corruption:**
|
||||||
|
Run the System File Checker (SFC) utility to scan and repair system files that may be corrupted.
|
||||||
|
```powershell
|
||||||
|
sfc /scannow
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Update Your System:**
|
||||||
|
Make sure your operating system is up-to-date. Check for Windows updates and install any pending updates.
|
||||||
|
|
||||||
|
4. **Check WMI Service:**
|
||||||
|
Ensure that the Windows Management Instrumentation (WMI) service is running. You can do this through the Services application:
|
||||||
|
- Press `Win + R` to open the Run dialog.
|
||||||
|
- Type `services.msc` and press Enter.
|
||||||
|
- Locate "Windows Management Instrumentation" in the list.
|
||||||
|
- Make sure to set its status to "Running" and the startup type to "Automatic."
|
||||||
|
|
||||||
|
5. **Check for Security Software Interference:**
|
||||||
|
Security software can sometimes interfere with WMI operations. Temporarily disable your antivirus or security software and check if the issue persists.
|
||||||
|
|
||||||
|
6. **Event Viewer:**
|
||||||
|
Check the Event Viewer for more detailed error information. Look for entries related to the `80041031` error and check if there are any additional details that can help identify the cause.
|
||||||
|
|
||||||
|
- Press `Win + X` and select "Event Viewer."
|
||||||
|
- Navigate to "Windows Logs" -> "Application" or "System."
|
||||||
|
- Look for entries with the source related to WMI or the application use to mount the ISO.
|
||||||
|
|
||||||
|
7. **ISO File Integrity:**
|
||||||
|
Ensure that the ISO file you are trying to mount is uncorrupted. Try mounting a different ISO file to see if the issue persists.
|
||||||
|
|
||||||
|
* If the problem persists after trying these steps, additional troubleshooting is required. Consider seeking assistance from Microsoft support or community forums for more specific guidance based on your system configuration and the software you use to mount the ISO.
|
BIN
docs/assets/Commit-GHD.png
Normal file
After Width: | Height: | Size: 194 KiB |
BIN
docs/assets/Compile.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
docs/assets/Create-Branch.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
docs/assets/Discard-GHD.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
docs/assets/Fork-Button-Dark.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/assets/Fork-Button-Light.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
docs/assets/Get-Installed-Dark.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
docs/assets/Get-Installed-Light.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
docs/assets/Install-Tab-Dark.png
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
docs/assets/Install-Tab-Light.png
Normal file
After Width: | Height: | Size: 137 KiB |
BIN
docs/assets/MicroWinScreen.png
Normal file
After Width: | Height: | Size: 102 KiB |
BIN
docs/assets/Microwin-Dark.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
docs/assets/Microwin-Light.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
docs/assets/Push-Commit.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
docs/assets/Screen.png
Normal file
After Width: | Height: | Size: 264 KiB |
BIN
docs/assets/Settings-Export-Dark.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
docs/assets/Settings-Export-Light.png
Normal file
After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 339 KiB After Width: | Height: | Size: 339 KiB |
BIN
docs/assets/Tweaks-Tab-Dark.png
Normal file
After Width: | Height: | Size: 150 KiB |
BIN
docs/assets/Tweaks-Tab-Light.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
docs/assets/favicon.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
175
docs/changelog.md
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
WinUtil change log received from GitHub Releases, it's autogenerated using GitHub Actions.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> This file **SHOULD NOT** be edited directly, any PRs that tries changing it directly will either be requested on not changing it, or it'll get rejected.
|
||||||
|
|
||||||
|
# Release 24.07.17
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
* Pump up the value of 'operations-per-run' Field for 'Close Old Issues' Workflow by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2219
|
||||||
|
* Improvements/Fixes for the Release Actions by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2221
|
||||||
|
* Move Launch Issues from ReadMe to Known Issues by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2222
|
||||||
|
* [01] Refactoring UI code by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2274
|
||||||
|
* Delete Un-used 'helperscript.ps1' File by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2223
|
||||||
|
* Known Issues: Removed redundancy caused by resolving the merge conflict. by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2224
|
||||||
|
* Redirect dev to latest Full Release if can't find prerelease by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2225
|
||||||
|
* Add 'CONTRIBUTING.md' File by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2227
|
||||||
|
* Update main.ps1 by @eltociear in https://github.com/ChrisTitusTech/winutil/pull/2229
|
||||||
|
* Added get installed check for classic right click menu tweak by @btstromberg in https://github.com/ChrisTitusTech/winutil/pull/2231
|
||||||
|
* fix syntax highlighting in .MDs by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2235
|
||||||
|
* Add "Shotcut" in applications by @ksb2311 in https://github.com/ChrisTitusTech/winutil/pull/2238
|
||||||
|
* Fix Icon Support for Shortcut Creation by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2242
|
||||||
|
* Allow for tasks to be distinguished by @CodingWonders in https://github.com/ChrisTitusTech/winutil/pull/2251
|
||||||
|
* Fix & Rename Nilesoft Shell by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2261
|
||||||
|
* Fix: Ultimate Performance Plan by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2267
|
||||||
|
* Change Main loop from 'ForEach' to 'For' inside 'Install-WinUtilProgramWinget' Private Function by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2271
|
||||||
|
* Fix 'Close Old Issues' Workflow by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2272
|
||||||
|
* Add new 'Disable Powershell 7 Telemetry' Tweak by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2273
|
||||||
|
* Fix Typo in 'Invoke-WinUtilTaskbarSearch' Private Function by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2275
|
||||||
|
* Update applications.json by @dhruvmistry2000 in https://github.com/ChrisTitusTech/winutil/pull/2290
|
||||||
|
* Add app: Modern Flyouts by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2293
|
||||||
|
* Adds PR template by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2299
|
||||||
|
* Add download counter by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2300
|
||||||
|
* Change Kicad category by @Joanty24 in https://github.com/ChrisTitusTech/winutil/pull/2302
|
||||||
|
* Fix: PR Template file extension by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2304
|
||||||
|
* Rework JDK packages with Corretto LTS ones by @meenbeese in https://github.com/ChrisTitusTech/winutil/pull/2305
|
||||||
|
* Added IPv6 DNS by @Joanty24 in https://github.com/ChrisTitusTech/winutil/pull/2303
|
||||||
|
* Create createchangelog.yml for docs page by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2346
|
||||||
|
* Adds all files for winutil docs by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2342
|
||||||
|
* Adds Community Discord to ReadMe file by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2343
|
||||||
|
* Discussions close on PR merge by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2336
|
||||||
|
* Documentation & ReadMe Cleanup by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2310
|
||||||
|
* Added MicroWin documentation by @CodingWonders in https://github.com/ChrisTitusTech/winutil/pull/2349
|
||||||
|
* Update Install-WinUtilProgramChoco.ps1 by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2307
|
||||||
|
* Addition of Fork by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2313
|
||||||
|
* Hidden File Tweaks by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2320
|
||||||
|
* Optimized: Shortcut Creation and PS7 Tweak by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2314
|
||||||
|
* Addition of multiple applications by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2316
|
||||||
|
* Add Application: ZoomIt by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2319
|
||||||
|
* Fix Compile Errors on PowerShell 5 by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2322
|
||||||
|
* Add application: Lenovo Legion Toolkit by @Klusio19 in https://github.com/ChrisTitusTech/winutil/pull/2324
|
||||||
|
* Remove Edge leftovers from WOW6432Node by @CodingWonders in https://github.com/ChrisTitusTech/winutil/pull/2328
|
||||||
|
* Fix: End Task with right click by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2331
|
||||||
|
* Adds Palemoon and closes old issues if not needed by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2332
|
||||||
|
* Change the titles for each section from Bold Text to Header 2 in Bug Report Issue Template by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2339
|
||||||
|
* Optimize badges by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2356
|
||||||
|
* Add New Windows 11 Specific Toggle - The 'Taskbar Alignment' Toggle by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2347
|
||||||
|
* Make the 'Youtube Tutorial' Header be the link instead of the Youtube Thumbnail for it, Making the 'README.md' even shorter by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2359
|
||||||
|
* Fix WinUtil Crashing on Startup - Xaml Error from Generated Applications List by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2361
|
||||||
|
* [Wiki] Automatically enabling Dark/Light mode set by user's browser Preference by @Angxddeep in https://github.com/ChrisTitusTech/winutil/pull/2366
|
||||||
|
* Fixes an issue with create changelog not working by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2375
|
||||||
|
* Updates PR template so disscussion and issue is on the same line. by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2363
|
||||||
|
* Update close-discussion.yml so it detects based on new previous PR by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2364
|
||||||
|
* Repo Cleanup by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2367
|
||||||
|
* Add /close command for the active contributors to close issues by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2380
|
||||||
|
* Update workflows to remove `::set-output` by @wojsmol in https://github.com/ChrisTitusTech/winutil/pull/2384
|
||||||
|
* Fixes release log by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2377
|
||||||
|
* Bump actions/checkout from 2 to 4 by @dependabot in https://github.com/ChrisTitusTech/winutil/pull/2389
|
||||||
|
* Bump actions/cache from 2 to 4 by @dependabot in https://github.com/ChrisTitusTech/winutil/pull/2390
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
* @btstromberg made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2231
|
||||||
|
* @ksb2311 made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2238
|
||||||
|
* @dhruvmistry2000 made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2290
|
||||||
|
* @Klusio19 made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2324
|
||||||
|
* @Angxddeep made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2366
|
||||||
|
* @wojsmol made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2384
|
||||||
|
* @dependabot made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2389
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/ChrisTitusTech/winutil/compare/24.06.29...24.07.17
|
||||||
|
|
||||||
|
# Release 24.06.28
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
* Rename Application: ForceAutoHDR by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2081
|
||||||
|
* Remove force install of Winget + Small improvements by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2083
|
||||||
|
* Remove WwanSvc Service From Manual Services Tweak by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2086
|
||||||
|
* Added Plex Desktop along side Plex Media Server by @PedroBuffon in https://github.com/ChrisTitusTech/winutil/pull/2091
|
||||||
|
* Remove java 20 by @brrock in https://github.com/ChrisTitusTech/winutil/pull/2095
|
||||||
|
* Remove oosu essential tweak by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2099
|
||||||
|
* Removed Free File Sync because of Malware warning on choco repo by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2101
|
||||||
|
* Remove unused Functions by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2102
|
||||||
|
* Remove Extra Tabs in 'applications.json' File by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2113
|
||||||
|
* Fix Compile -Run always starting as PS5 by @Marterich in https://github.com/ChrisTitusTech/winutil/pull/2165
|
||||||
|
* Fix White space (bottom right of Application Tab) by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2120
|
||||||
|
* Delete Un-used 'logs' Folder by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2135
|
||||||
|
* Fixes Edge Removal by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2136
|
||||||
|
* Added kicad by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2138
|
||||||
|
* Addition of Dropbox by @Real-MullaC in https://github.com/ChrisTitusTech/winutil/pull/2200
|
||||||
|
* Spelling Fix: uninstall button by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2197
|
||||||
|
* Add Overlay to Taskbaritem by @MyDrift-user in https://github.com/ChrisTitusTech/winutil/pull/2196
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
* @PedroBuffon made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2091
|
||||||
|
* @brrock made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2095
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/ChrisTitusTech/winutil/compare/24.06.25...24.06.28
|
||||||
|
|
||||||
|
# Release 24.06.18
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
* Update Invoke-WinUtilNumLock.ps1 by @ChrisTitusTech in https://github.com/ChrisTitusTech/winutil/pull/2104
|
||||||
|
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/ChrisTitusTech/winutil/compare/24.06.11...24.06.18
|
||||||
|
|
||||||
|
# Release 24.06.11
|
||||||
|
|
||||||
|
This release is an auto generated release.
|
||||||
|
|
||||||
|
From now on any pull request on the main branch generates a release like this, which ensures you can rewind in time to ANY version of winutil. Also this makes it easy to launch winutil from github.com instead of using raw GitHub which is blocked in some countries. Big shoutout to KonTy for the auto release idea!
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
* Fix Numlock toggle by @ChrisTitusTech in https://github.com/ChrisTitusTech/winutil/pull/2044
|
||||||
|
* fix typo by @nikolan123 in https://github.com/ChrisTitusTech/winutil/pull/2041
|
||||||
|
* Simplify 'Close Old Issues' Workflow by using 'actions/stale' GitHub Action by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2055
|
||||||
|
* Compile Cleanup and Tweak Fixes by @ChrisTitusTech in https://github.com/ChrisTitusTech/winutil/pull/2062
|
||||||
|
* Fix the URL of an Example in 'README.md' File by @og-mrk in https://github.com/ChrisTitusTech/winutil/pull/2063
|
||||||
|
|
||||||
|
## New Contributors
|
||||||
|
* @nikolan123 made their first contribution in https://github.com/ChrisTitusTech/winutil/pull/2041
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/ChrisTitusTech/winutil/compare/v2024.06.05...24.06.11
|
||||||
|
|
||||||
|
# WinUtil 2024.06.05 Bug Fixes and Feature Additions
|
||||||
|
|
||||||
|
- Applications cleanup (Few unmaintained applications culled)
|
||||||
|
- Application Additions
|
||||||
|
- Various Microwin fixes thanks to @KonTy
|
||||||
|
- Better application filtering @Marterich
|
||||||
|
- CoPilot Removal @KonTy @ModernTTY
|
||||||
|
- Import Drivers @CodingWonders
|
||||||
|
- OOSU updates @Marterich
|
||||||
|
- Fix Auto HDR @og-mrk
|
||||||
|
- Only install chocolatey if needed @Marterich
|
||||||
|
- Various winget fixes @og-mrk
|
||||||
|
- Adobe Fixes @MyDrift-user
|
||||||
|
- Disable Fullscreen Optimizations Tweak Added
|
||||||
|
- Tweaks reorder and cleanup
|
||||||
|
- Chocolatey fallback fix @ty802
|
||||||
|
|
||||||
|
This was a massive 100+ commit PR and the last of it's size. Going forward I will be making multiple branches to separate the pr's into. This will help seperate application PRs, GUI PRs, Tweaks, and others into their own branches based on features.
|
||||||
|
|
||||||
|
# WinUtil 2024.04.20 Bug Fixes and Issue Fixes
|
||||||
|
|
||||||
|
- Toggle Widgets fix @og-mrk
|
||||||
|
- Fix Special Characters causing errors in JSON files @og-mrk
|
||||||
|
- Restart explorer on classic right click tweak @og-mrk
|
||||||
|
- Fix Disable Storage Sense @og-mrk
|
||||||
|
- Robocopy fix when username has space in during OneDrive uninstall @og-mrk
|
||||||
|
- Multiple Winget Fixes made by @ruxunderscore
|
||||||
|
- Fix DISM Conversion for ESD files @CodingWonders
|
||||||
|
- Independent Edge Removal Update by @DaEpicR
|
||||||
|
- Disable SCOOBE @ICTdE
|
||||||
|
- O&O Tweaks update by @Marterich
|
||||||
|
- Bugfix for Window Restore Creation by @ChrisTitusTech
|
||||||
|
- Fix Winget Installs for Default -> User Scope -> Unelevated if one fails it trys the next method. @ChrisTitusTech
|
||||||
|
- Fix Unit Tests for Functions @ChrisTitusTech
|
||||||
|
|
106
docs/contribute.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# How to Contribute?
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
* Test the latest changes to WinUtil by running the pre-release and reporting issues you are encountering to help us continually improve WinUtil!
|
||||||
|
|
||||||
|
#### **Run the latest pre-release**
|
||||||
|
```ps1
|
||||||
|
irm christitus.com/windev | iex
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! bug "Keep in mind"
|
||||||
|
|
||||||
|
This is a pre-release and should be treated as such. It exists for developers to test the utility and report or fix bugs before they get added to the stable release. Don't use it in production!
|
||||||
|
|
||||||
|
## Issues
|
||||||
|
|
||||||
|
* If you encounter any challenges or problems with the script, I kindly request that you submit them via the "Issues" tab on the GitHub repository. By filling out the provided template, you can provide specific details about the issue, allowing me (and others in the community) to promptly address any bugs or consider feature requests.
|
||||||
|
|
||||||
|
## Contribute Code
|
||||||
|
|
||||||
|
* Pull requests are now handled directly on the **MAIN branch**. This was done since we can now select specific releases to launch via releases in GitHub.
|
||||||
|
|
||||||
|
* If you're doing code changes, then you can submit a PR to `main` branch, but I am very selective about these.
|
||||||
|
|
||||||
|
!!! warning "Important"
|
||||||
|
|
||||||
|
Do not use a code formatter, make massive amounts of line changes, or make multiple feature changes. EACH FEATURE CHANGE SHOULD BE IT'S OWN PULL REQUEST!
|
||||||
|
|
||||||
|
* When creating pull requests, it is essential to thoroughly document all changes made. This includes, but is not limited to, documenting any additions made to the `tweaks` section and corresponding `undo tweak`, so users are able to remove the newly added tweaks if necessary, and comprehensive documentation is required for all code changes. Document your changes and briefly explain why you made your changes in your Pull Request Description. Failure to adhere to this format may result in the denial of the pull request. Additionally, any code lacking sufficient documentation may also be denied.
|
||||||
|
|
||||||
|
* By following these guidelines, we can maintain a high standard of quality and ensure that the codebase remains organized and well-documented.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
|
||||||
|
When creating a function, please include "WPF" or "WinUtil" in the file name so it can be loaded into the runspace.
|
||||||
|
|
||||||
|
## Walk through
|
||||||
|
|
||||||
|
* This is a guide for beginners. If you are still having issues, look at the following official GitHub documentation:
|
||||||
|
* [Commit through WEB](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits)
|
||||||
|
* [Commit through GitHub Desktop](https://docs.github.com/en/desktop/making-changes-in-a-branch/committing-and-reviewing-changes-to-your-project-in-github-desktop#about-commits)
|
||||||
|
* [Create a Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)
|
||||||
|
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
``` mermaid
|
||||||
|
graph LR
|
||||||
|
A[Fork Project] --> B[Clone Repository];
|
||||||
|
B --> C[Create New Branch];
|
||||||
|
C --> D[Make Changes];
|
||||||
|
D --> G[Test Changes];
|
||||||
|
G --> H{Tests Passed?};
|
||||||
|
H -->|Yes| E[Commit Changes];
|
||||||
|
E --> F[Push Branch];
|
||||||
|
H -->|No| J[Fix Issues];
|
||||||
|
F --> K[Create Pull Request];
|
||||||
|
K --> L[Fill out PR template];
|
||||||
|
J --> G;
|
||||||
|
```
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
This is a diagram to guide you through the process. It may vary depending on the type of change you're making.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
### Clone the Fork
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
While you can make your changes directly through the Web, we recommend cloning the repo to your device using the application GitHub Desktop (available in WinUtil) to test your fork easily.
|
||||||
|
|
||||||
|
* Install GitHub Desktop if it is not already installed.
|
||||||
|
* Log in using the same GitHub account you used to fork WinUtil.
|
||||||
|
* Choose the fork under "Your Repositories" and press "clone {repo name}"
|
||||||
|
* Create a new branch and name it something relatable to your changes.
|
||||||
|
|
||||||
|
* Now you can modify WinUtil to your liking using your preferred text editor.
|
||||||
|
|
||||||
|
|
||||||
|
### Testing your changes
|
||||||
|
|
||||||
|
* To test to see if your changes work as intended run following commands in a powershell teminal as admin:
|
||||||
|
|
||||||
|
* Change the directory where you are running the commands to the forked project.
|
||||||
|
* `cd {path to the folder with the compile.ps1}`
|
||||||
|
* Run the following command to compile and run WinUtil:
|
||||||
|
* `.\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.
|
||||||
|
|
||||||
|
### Committing the changes
|
||||||
|
* 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.
|
||||||
|

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

|
||||||
|
|
||||||
|
### 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.
|
||||||
|
* If you do not see your feature in the main "/win" build, that is fine. All new changes go into the /windev build to make sure everything is working OK before going fully public.
|
||||||
|
* Congratulations! You just submitted your first PR. Thank you so much for contributing to WinUtil.
|
7
docs/faq.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# FAQ's
|
||||||
|
|
||||||
|
## How do I uninstall WinUtil?
|
||||||
|
* You do not have to uninstall WinUtil. As it is a script you run from Powershell it only loads into your RAM. This means as soon as you close WinUtil it will be deleted off your system.
|
||||||
|
|
||||||
|
## I applied a tweak and now something doesn't work, what do I do?
|
||||||
|
* If you applied a tweak and it breaks something, you can always revert the tweak by selecting the tweak and clicking "Undo Selected Tweaks".
|
20
docs/index.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Welcome to the WinUtil Documentation!
|
||||||
|
|
||||||
|
[](https://github.com/ChrisTitusTech/winutil/releases/latest)
|
||||||
|

|
||||||
|
|
||||||
|
[](https://discord.gg/RUbZUZyByQ)
|
||||||
|
|
||||||
|
Welcome to the official documentation for WinUtil, your go-to utility for optimizing and managing your Windows environment. Whether you’re an IT professional, power user, or regular user, WinUtil provides a comprehensive set of tools to enhance your Windows experience.
|
||||||
|
|
||||||
|
## Running the latest release of WinUtil
|
||||||
|
|
||||||
|
* You will first need to start a Powershell terminal **as Admin**.
|
||||||
|
* Now you can run the following command:
|
||||||
|
```ps1
|
||||||
|
irm christitus.com/win | iex
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
WinUtil is updated weekly as of the time of writing. Consequently, features and functionalities may evolve, and the documentation may not always reflect the most current images or information.
|
13
docs/stylesheets/extra.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* Custom styles for MkDocs Material */
|
||||||
|
body {
|
||||||
|
background-color: #c22525;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-nav__link {
|
||||||
|
color: #ff5722;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset h1 {
|
||||||
|
font-size: 2.5em;
|
||||||
|
color: #3f51b5;
|
||||||
|
}
|
260
docs/userguide.md
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
# Walkthrough
|
||||||
|
|
||||||
|
## Install
|
||||||
|
---
|
||||||
|
|
||||||
|
=== "Installation & Updates"
|
||||||
|
|
||||||
|
* Choose the programs you want to install or upgrade.
|
||||||
|
* For programs not currently installed, this action will install them.
|
||||||
|
* For programs already installed, this action will update them to the latest version.
|
||||||
|
* Click the `Install/Upgrade Selected` button to start the installation or upgrade process.
|
||||||
|
|
||||||
|
=== "Upgrade All"
|
||||||
|
|
||||||
|
* Simply press the `Upgrade All` button.
|
||||||
|
* This will upgrade all applicable programs that are installed without the need for individual selection.
|
||||||
|
|
||||||
|
=== "Uninstall"
|
||||||
|
|
||||||
|
* Select the programs you wish to uninstall.
|
||||||
|
* Click the `Uninstall Selected` button to remove the selected programs.
|
||||||
|
|
||||||
|
=== "Get Installed"
|
||||||
|
|
||||||
|
* Click the `Get Installed` button.
|
||||||
|
* This will scan for and select all installed programs in WinUtil that WinGet supports.
|
||||||
|
|
||||||
|
=== "Clear Selection"
|
||||||
|
* Click the `Clear Selection` button.
|
||||||
|
* This will unselect all checked programs.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
If you have trouble finding an application, press `ctrl + f` and search the name of it. Applications will filter depending on your input.
|
||||||
|
|
||||||
|
## Tweaks
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
### Run Tweaks
|
||||||
|
* **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application.
|
||||||
|
* **Select Tweaks**: Choose the tweaks you want to apply. You can use the presets available at the top for convenience.
|
||||||
|
* **Run Tweaks**: After selecting the desired tweaks, click the 'Run Tweaks' button at the bottom of the screen.
|
||||||
|
|
||||||
|
### Undo Tweaks
|
||||||
|
* **Open Tweaks Tab**: Go to the 'Tweaks' tab located next to 'Install'.
|
||||||
|
* **Select Tweaks to Remove**: Choose the tweaks you want to disable or remove.
|
||||||
|
* **Undo Tweaks**: Click the 'Undo Selected Tweaks' button at the bottom of the screen to apply the changes.
|
||||||
|
|
||||||
|
### Essential Tweaks
|
||||||
|
Essential Tweaks are modifications and optimizations that are generally safe for most users to implement. These tweaks are designed to enhance system performance, improve privacy, and reduce unnecessary system activities. They are considered low-risk and are recommended for users who want to ensure their system runs smoothly and efficiently without delving too deeply into complex configurations. The goal of Essential Tweaks is to provide noticeable improvements with minimal risk, making them suitable for a wide range of users, including those who may not have advanced technical knowledge.
|
||||||
|
|
||||||
|
### Advanced Tweaks - CAUTION
|
||||||
|
Advanced Tweaks are intended for experienced users who have a solid understanding of their system and the potential implications of making deep-level changes. These tweaks involve more significant alterations to the operating system and can provide substantial customization. However, they also carry a higher risk of causing system instability or unintended side effects if not implemented correctly. Users who choose to apply Advanced Tweaks should proceed with caution, ensuring they have adequate knowledge and backups in place to recover if something goes wrong. These tweaks are not recommended for novice users or those unfamiliar with the inner workings of their operating system.
|
||||||
|
|
||||||
|
### O&O Shutup
|
||||||
|
|
||||||
|
|
||||||
|
[O&O ShutUp10++](https://www.oo-software.com/en/shutup10) can be launched from WinUtil with only one button click. It is a free privacy tool for Windows that lets users easily manage their privacy settings. It disables telemetry, controls updates, and manages app permissions to enhance security and privacy. The tool offers recommended settings for optimal privacy with just a few clicks.
|
||||||
|
|
||||||
|
<iframe width="640" height="360" src="https://www.youtube.com/embed/3HvNr8eMcv0" title="O&O ShutUp10++: For Windows 10 & 11, with Dark Mode" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||||
|
|
||||||
|
|
||||||
|
### DNS
|
||||||
|
|
||||||
|
The utility provides a convenient DNS selection feature, allowing users to choose between various DNS providers for both IPv4 and IPv6. This enables users to optimize their internet connection for speed, security, and privacy according to their specific needs. Here are the available options:
|
||||||
|
|
||||||
|
* **Default**: Uses the default DNS settings configured by your ISP or network.
|
||||||
|
* **DHCP**: Automatically acquires DNS settings from the DHCP server.
|
||||||
|
* [**Google**](https://developers.google.com/speed/public-dns?hl=de): A reliable and fast DNS service provided by Google.
|
||||||
|
* [**Cloudflare**](https://developers.cloudflare.com/1.1.1.1/): Known for speed and privacy, Cloudflare DNS is a popular choice for enhancing internet performance.
|
||||||
|
* [**Cloudflare_Malware**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malicious%20content%3A): Provides additional protection by blocking malware sites.
|
||||||
|
* [**Cloudflare_Malware_Adult**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malware%20and%20adult%20content%3A): Blocks both malware and adult content, offering more comprehensive filtering.
|
||||||
|
* [**Level3**](https://www.lumen.com/): Another fast and reliable DNS service option.
|
||||||
|
* [**Open_DNS**](https://www.opendns.com/setupguide/#familyshield): Offers customizable filtering and enhanced security features.
|
||||||
|
* [**Quad9**](https://quad9.net/): Focuses on security by blocking known malicious domains.
|
||||||
|
|
||||||
|
### Customize Preferences
|
||||||
|
|
||||||
|
The Customize Preferences section allows users to personalize their Windows experience by toggling various visual and functional features. These preferences are designed to enhance usability and tailor the system to the user’s specific needs and preferences.
|
||||||
|
|
||||||
|
### Performance Plans
|
||||||
|
|
||||||
|
The Performance Plans section allows users to manage the Ultimate Performance Profile on their system. This feature is designed to optimize the system for maximum performance.
|
||||||
|
|
||||||
|
#### Add and activate the Ultimate Performance Profile:
|
||||||
|
* Enables and activates the Ultimate Performance Profile to enhance system performance by minimizing latency and increasing efficiency.
|
||||||
|
#### Remove Ultimate Performance Profile:
|
||||||
|
* Deactivates the Ultimate Performance Profile, changing the system to the Balanced Profile.
|
||||||
|
|
||||||
|
### Shortcuts
|
||||||
|
|
||||||
|
The utility includes a feature to easily create a desktop shortcut, providing quick access to the script.
|
||||||
|
|
||||||
|
## Config
|
||||||
|
---
|
||||||
|
|
||||||
|
### Features
|
||||||
|
* Install the most used **Windows Features** by checking the checkbox and clicking "Install Features" to install them.
|
||||||
|
|
||||||
|
* All .Net Frameworks (2, 3, 4)
|
||||||
|
* HyperV Virtualization
|
||||||
|
* Legacy Media (WMP, DirectPlay)
|
||||||
|
* NFS - Network File System
|
||||||
|
* Enable Search Box Web Suggestions in Registry (explorer restart)
|
||||||
|
* Disables Search Box Web Suggestions in Registry (explorer restart)
|
||||||
|
* Enable Daily Registry Backup Task 12:30am
|
||||||
|
* Enable Legacy F8 Boot Recovery
|
||||||
|
* Disable Legacy F8 Boot Recovery
|
||||||
|
* Windows Subsystem for Linux
|
||||||
|
* Windows Sandbox
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Quick fixes for your system if you are having issues.
|
||||||
|
|
||||||
|
* Set Up Autologin
|
||||||
|
* Reset Windows Update
|
||||||
|
* Reset Network
|
||||||
|
* System Corruption Scan
|
||||||
|
* WinGet Reinstall
|
||||||
|
* Remove Adobe Creative Cloud
|
||||||
|
|
||||||
|
### Legacy Windows Panels
|
||||||
|
|
||||||
|
Open old-school Windows panels directly from WinUtil. Following Panels are available:
|
||||||
|
|
||||||
|
* Control Panel
|
||||||
|
* Network Connections
|
||||||
|
* Power Panel
|
||||||
|
* Region
|
||||||
|
* Sound Settings
|
||||||
|
* System Properties
|
||||||
|
* User Accounts
|
||||||
|
|
||||||
|
## Updates
|
||||||
|
---
|
||||||
|
|
||||||
|
The utility provides three distinct settings for managing Windows updates: Default (Out of Box) Settings, Security (Recommended) Settings, and Disable ALL Updates (NOT RECOMMENDED!). Each setting offers a different approach to handling updates, catering to various user needs and preferences.
|
||||||
|
|
||||||
|
### Default (Out of Box) Settings
|
||||||
|
- **Description**: This setting retains the default configurations that come with Windows, ensuring no modifications are made.
|
||||||
|
- **Functionality**: It will remove any custom Windows update settings previously applied.
|
||||||
|
- **Note**: If update errors persist, reset all updates in the configuration tab to restore all Microsoft Update Services to their default settings, reinstalling them from their servers.
|
||||||
|
|
||||||
|
### Security (Recommended) Settings
|
||||||
|
- **Description**: This is the recommended setting for all computers.
|
||||||
|
- **Update Schedule**:
|
||||||
|
- **Feature Updates**: Delays feature updates by 2 years to avoid potential bugs and instability.
|
||||||
|
- **Security Updates**: Installs security updates 4 days after their release to ensure system protection against pressing security flaws.
|
||||||
|
- **Rationale**:
|
||||||
|
- **Feature Updates**: Often introduce new features and bugs; delaying these updates minimizes the risk of system disruptions.
|
||||||
|
- **Security Updates**: Essential for patching critical security vulnerabilities. Delaying them by a few days allows for verification of stability and compatibility without leaving the system exposed for extended periods.
|
||||||
|
|
||||||
|
### Disable ALL Updates (NOT RECOMMENDED!)
|
||||||
|
- **Description**: This setting completely disables all Windows updates.
|
||||||
|
- **Suitability**: May be appropriate for systems used for specific purposes that do not require active internet browsing.
|
||||||
|
- **Warning**: Disabling updates significantly increases the risk of the system being hacked or infected due to the lack of security patches.
|
||||||
|
- **Note**: It is strongly advised against using this setting due to the heightened security risks.
|
||||||
|
|
||||||
|
!!! bug
|
||||||
|
|
||||||
|
The Updates tab is currently non-functional. We are actively working on a resolution to restore its functionality.
|
||||||
|
|
||||||
|
## MicroWin
|
||||||
|
---
|
||||||
|
|
||||||
|
* **MicroWin** lets you customize your Windows 10 and 11 installation images by debloating them however you want.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
#### Basic usage
|
||||||
|
|
||||||
|
1. Specify the source Windows ISO to customize.
|
||||||
|
|
||||||
|
* If you don't have a Windows ISO file prepared, you can download it using the Media Creation Tool for the respective Windows version. [Here](https://go.microsoft.com/fwlink/?linkid=2156295) is the Windows 11 version, and [here](https://go.microsoft.com/fwlink/?LinkId=2265055) is the Windows 10 version
|
||||||
|
|
||||||
|
2. Configure the debloat process.
|
||||||
|
3. Specify the target location for the new ISO file.
|
||||||
|
4. Let the magic happen!
|
||||||
|
|
||||||
|
!!! warning "Heads-up"
|
||||||
|
|
||||||
|
This feature is still in development, and you may encounter some issues with the generated images. If that happens, don't hesitate to report an issue!
|
||||||
|
|
||||||
|
#### Options
|
||||||
|
|
||||||
|
* **Download oscdimg.exe from the CTT GitHub repo** will grab an OSCDIMG executable from the GitHub repository instead of a Chocolatey package.
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
OSCDIMG is the tool that lets the program create ISO images. Typically, you would find this in the [Windows Assessment and Deployment Kit](https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install)
|
||||||
|
|
||||||
|
* Selecting a scratch directory will copy the contents of the ISO file to the directory you specify instead of an automatically generated folder in the `%TEMP%` directory.
|
||||||
|
* You can select an edition of Windows to debloat (**SKU**) using the convenient drop-down menu.
|
||||||
|
|
||||||
|
By default, MicroWin will debloat the Pro edition, but you can choose any edition you want.
|
||||||
|
|
||||||
|
|
||||||
|
##### Customization options
|
||||||
|
|
||||||
|
* **Keep Provisioned Packages**: leaving this option unticked (default) will try to remove every operating system package.
|
||||||
|
|
||||||
|
Some packages may remain after processing. This can happen if the packages in question are permanent or have been superseded by newer versions.
|
||||||
|
|
||||||
|
* **Keep Appx Packages**: leaving this option unticked (default) will try to remove every Microsoft Store app from the Windows image.
|
||||||
|
|
||||||
|
This option will exclude some applications that are essential in the event that you want or need to add a Store app later on.
|
||||||
|
|
||||||
|
* **Keep Defender**: leaving this option unticked will try to remove every part of Windows Defender, including the Windows Security app.
|
||||||
|
|
||||||
|
Leaving this option unticked is **NOT recommended** unless you plan to use a third-party antivirus solution on your MicroWin installation. In that regard, don't install AVs with bad reputations or rogueware.
|
||||||
|
|
||||||
|
* **Keep Edge**: leaving this option unticked will try to remove every part of the Microsoft Edge browser using the best methods available.
|
||||||
|
|
||||||
|
Leaving this option unticked is not recommended because it might break some applications that might depend on the `Edge WebView2` runtime. However, if that happens, you can easily [reinstall it](https://developer.microsoft.com/en-us/microsoft-edge/webview2)
|
||||||
|
|
||||||
|
|
||||||
|
##### Driver integration options
|
||||||
|
|
||||||
|
* **Inject drivers** will add the drivers in the folder that you specify to the target Windows image.
|
||||||
|
* **Import drivers from the current system** will add every third-party driver that is present in your active installation.
|
||||||
|
|
||||||
|
This makes the target image have the same hardware compatibility as the active installation. However, this means that you will only be able to install the target Windows image and take full advantage of it on computers with **the same hardware**. To avoid this, you'll need to customize the `install.wim` file of the target ISO in the 'sources` folder.
|
||||||
|
|
||||||
|
|
||||||
|
##### Ventoy options
|
||||||
|
|
||||||
|
* **Copy to Ventoy** will copy the target ISO file to any USB drive with [Ventoy](https://ventoy.net/en/index.html) installed
|
||||||
|
!!! info
|
||||||
|
|
||||||
|
Ventoy is a solution that lets you boot to any ISO file stored on a drive. Think of it as having multiple bootable USBs in one. Do note, though, that your drive needs to have enough free space for the target ISO file.
|
||||||
|
|
||||||
|
## Automation
|
||||||
|
|
||||||
|
* Some features are available through automation. This allows you to save your config file, pass it to WinUtil, walk away and come back to a finished system. Here is how you can set it up currently with Winutil >24.01.15
|
||||||
|
|
||||||
|
* On the Install Tab, click "Get Installed", this will get all installed apps **supported by Winutil** on the system.
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
* Click on the Settings cog in the upper right corner and choose Export. Choose file file and location; this will export the setting file.
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
* Copy this file to a USB or somewhere you can use it after Windows installation.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
Use the Microwin tab to create a custom Windows image & install the Windows image.
|
||||||
|
|
||||||
|
* On any supported Windows machine, open PowerShell **as Admin** and run the following command to automatically apply tweaks and install apps from the config file.
|
||||||
|
```ps1
|
||||||
|
iex "& { $(irm christitus.com/win) } -Config [path-to-your-config] -Run"
|
||||||
|
```
|
||||||
|
* Have a cup of coffee! Come back when it's done.
|
@ -37,7 +37,7 @@ function global:prepare_edge {
|
|||||||
ri 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\microsoft-edge' -recurse -force -ea 0
|
ri 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\microsoft-edge' -recurse -force -ea 0
|
||||||
ri 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\MSEdgeHTM' -recurse -force -ea 0
|
ri 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\MSEdgeHTM' -recurse -force -ea 0
|
||||||
ni "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -force -ea 0 >''
|
ni "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -force -ea 0 >''
|
||||||
sp "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" '(Default)' "`"$MS`" --single-argument %%1" -force -ea 0
|
sp "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" '(Default)' "`"$MS`" --single-argument %%1" -force -ea 0
|
||||||
ni "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -force -ea 0 >''
|
ni "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -force -ea 0 >''
|
||||||
sp "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" '(Default)' "`"$MS`" --single-argument %%1" -force -ea 0
|
sp "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" '(Default)' "`"$MS`" --single-argument %%1" -force -ea 0
|
||||||
foreach ($p in 'HKLM:\SOFTWARE\Policies','HKLM:\SOFTWARE','HKLM:\SOFTWARE\WOW6432Node') {
|
foreach ($p in 'HKLM:\SOFTWARE\Policies','HKLM:\SOFTWARE','HKLM:\SOFTWARE\WOW6432Node') {
|
||||||
@ -54,7 +54,7 @@ function global:prepare_edge {
|
|||||||
}
|
}
|
||||||
## helper for webview reinstall - restore webexperience (widgets) if available
|
## helper for webview reinstall - restore webexperience (widgets) if available
|
||||||
function global:prepare_webview {
|
function global:prepare_webview {
|
||||||
$cfg = @{Register=$true; ForceApplicationShutdown=$true; ForceUpdateFromAnyVersion=$true; DisableDevelopmentMode=$true}
|
$cfg = @{Register=$true; ForceApplicationShutdown=$true; ForceUpdateFromAnyVersion=$true; DisableDevelopmentMode=$true}
|
||||||
dir "$env:ProgramFiles\WindowsApps\MicrosoftWindows.Client.WebExperience*\AppxManifest.xml" -rec -ea 0 | Add-AppxPackage @cfg
|
dir "$env:ProgramFiles\WindowsApps\MicrosoftWindows.Client.WebExperience*\AppxManifest.xml" -rec -ea 0 | Add-AppxPackage @cfg
|
||||||
dir "$env:SystemRoot\SystemApps\Microsoft.Win32WebViewHost*\AppxManifest.xml" -rec -ea 0 | Add-AppxPackage @cfg
|
dir "$env:SystemRoot\SystemApps\Microsoft.Win32WebViewHost*\AppxManifest.xml" -rec -ea 0 | Add-AppxPackage @cfg
|
||||||
kill -name explorer -ea 0; if ((get-process -name 'explorer' -ea 0) -eq $null) {start explorer}
|
kill -name explorer -ea 0; if ((get-process -name 'explorer' -ea 0) -eq $null) {start explorer}
|
||||||
@ -66,7 +66,7 @@ $D1=[uri].module.gettype('System.Diagnostics.Process')."GetM`ethods"(42) |where
|
|||||||
|
|
||||||
## 3 shut edge & webview clone stuff down and gather install paths
|
## 3 shut edge & webview clone stuff down and gather install paths
|
||||||
$shut = 'explorer','Widgets','widgetservice','msedgewebview2','MicrosoftEdge*','chredge','msedge','edge'
|
$shut = 'explorer','Widgets','widgetservice','msedgewebview2','MicrosoftEdge*','chredge','msedge','edge'
|
||||||
$shut+= 'msteams','msfamily','WebViewHost','Clipchamp'
|
$shut+= 'msteams','msfamily','WebViewHost','Clipchamp'
|
||||||
cd $env:systemdrive; taskkill /im explorer.exe /f 2>&1 >''; foreach ($p in $shut) {kill -name $p -force -ea 0}
|
cd $env:systemdrive; taskkill /im explorer.exe /f 2>&1 >''; foreach ($p in $shut) {kill -name $p -force -ea 0}
|
||||||
prepare_edge
|
prepare_edge
|
||||||
## clear win32 uninstall block
|
## clear win32 uninstall block
|
||||||
@ -93,15 +93,15 @@ $users = @('S-1-5-18'); if (test-path $store) {$users += $((dir $store -ea 0 |wh
|
|||||||
foreach ($choice in $remove_appx) { if ('' -eq $choice.Trim()) {continue}
|
foreach ($choice in $remove_appx) { if ('' -eq $choice.Trim()) {continue}
|
||||||
foreach ($appx in $($provisioned |where {$_.PackageName -like "*$choice*"})) {
|
foreach ($appx in $($provisioned |where {$_.PackageName -like "*$choice*"})) {
|
||||||
$next = !1; foreach ($no in $skip) {if ($appx.PackageName -like "*$no*") {$next = !0}} ; if ($next) {continue}
|
$next = !1; foreach ($no in $skip) {if ($appx.PackageName -like "*$no*") {$next = !0}} ; if ($next) {continue}
|
||||||
$PackageName = $appx.PackageName; $PackageFamilyName = ($appxpackage |where {$_.Name -eq $appx.DisplayName}).PackageFamilyName
|
$PackageName = $appx.PackageName; $PackageFamilyName = ($appxpackage |where {$_.Name -eq $appx.DisplayName}).PackageFamilyName
|
||||||
ni "$store\Deprovisioned\$PackageFamilyName" -force >''; $PackageFamilyName
|
ni "$store\Deprovisioned\$PackageFamilyName" -force >''; $PackageFamilyName
|
||||||
foreach ($sid in $users) {ni "$store\EndOfLife\$sid\$PackageName" -force >''} ; $eol += $PackageName
|
foreach ($sid in $users) {ni "$store\EndOfLife\$sid\$PackageName" -force >''} ; $eol += $PackageName
|
||||||
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 >''
|
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 >''
|
||||||
remove-appxprovisionedpackage -packagename $PackageName -online -allusers >''
|
remove-appxprovisionedpackage -packagename $PackageName -online -allusers >''
|
||||||
}
|
}
|
||||||
foreach ($appx in $($appxpackage |where {$_.PackageFullName -like "*$choice*"})) {
|
foreach ($appx in $($appxpackage |where {$_.PackageFullName -like "*$choice*"})) {
|
||||||
$next = !1; foreach ($no in $skip) {if ($appx.PackageFullName -like "*$no*") {$next = !0}} ; if ($next) {continue}
|
$next = !1; foreach ($no in $skip) {if ($appx.PackageFullName -like "*$no*") {$next = !0}} ; if ($next) {continue}
|
||||||
$PackageFullName = $appx.PackageFullName;
|
$PackageFullName = $appx.PackageFullName;
|
||||||
ni "$store\Deprovisioned\$appx.PackageFamilyName" -force >''; $PackageFullName
|
ni "$store\Deprovisioned\$appx.PackageFamilyName" -force >''; $PackageFullName
|
||||||
foreach ($sid in $users) {ni "$store\EndOfLife\$sid\$PackageFullName" -force >''} ; $eol += $PackageFullName
|
foreach ($sid in $users) {ni "$store\EndOfLife\$sid\$PackageFullName" -force >''} ; $eol += $PackageFullName
|
||||||
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 >''
|
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 >''
|
||||||
@ -125,16 +125,16 @@ foreach ($PF in $env:ProgramFiles,${env:ProgramFiles(x86)}) { if (test-path "$PF
|
|||||||
if ($also_remove_webview -eq 1) { foreach ($hk in 'HKCU:','HKLM:') { foreach ($wow in '','\Wow6432Node') {
|
if ($also_remove_webview -eq 1) { foreach ($hk in 'HKCU:','HKLM:') { foreach ($wow in '','\Wow6432Node') {
|
||||||
ri "$hk\SOFTWARE${wow}\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge Update" -rec -force -ea 0 }}
|
ri "$hk\SOFTWARE${wow}\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge Update" -rec -force -ea 0 }}
|
||||||
ri "$PF\Microsoft\EdgeUpdate" -rec -force -ea 0; Unregister-ScheduledTask -TaskName MicrosoftEdgeUpdate* -Confirm:$false -ea 0
|
ri "$PF\Microsoft\EdgeUpdate" -rec -force -ea 0; Unregister-ScheduledTask -TaskName MicrosoftEdgeUpdate* -Confirm:$false -ea 0
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
$appdata = $([Environment]::GetFolderPath('ApplicationData'))
|
$appdata = $([Environment]::GetFolderPath('ApplicationData'))
|
||||||
ri "$appdata\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Tombstones\Microsoft Edge.lnk" -force
|
ri "$appdata\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Tombstones\Microsoft Edge.lnk" -force
|
||||||
ri "$appdata\Microsoft\Internet Explorer\Quick Launch\Microsoft Edge.lnk" -force
|
ri "$appdata\Microsoft\Internet Explorer\Quick Launch\Microsoft Edge.lnk" -force
|
||||||
|
|
||||||
## undo eol unblock trick to prevent latest cumulative update (LCU) failing
|
## undo eol unblock trick to prevent latest cumulative update (LCU) failing
|
||||||
foreach ($sid in $users) { foreach ($PackageName in $eol) {ri "$store\EndOfLife\$sid\$PackageName" -force >''} }
|
foreach ($sid in $users) { foreach ($PackageName in $eol) {ri "$store\EndOfLife\$sid\$PackageName" -force >''} }
|
||||||
|
|
||||||
## set (almost) useless policies to prevent unsolicited reinstalls
|
## set (almost) useless policies to prevent unsolicited reinstalls
|
||||||
foreach ($p in 'HKLM:\SOFTWARE\Policies','HKLM:\SOFTWARE','HKLM:\SOFTWARE\WOW6432Node') {
|
foreach ($p in 'HKLM:\SOFTWARE\Policies','HKLM:\SOFTWARE','HKLM:\SOFTWARE\WOW6432Node') {
|
||||||
ni "$p\Microsoft\EdgeUpdate" -force >''
|
ni "$p\Microsoft\EdgeUpdate" -force >''
|
||||||
sp "$p\Microsoft\EdgeUpdate" 'InstallDefault' 0 -type Dword -force
|
sp "$p\Microsoft\EdgeUpdate" 'InstallDefault' 0 -type Dword -force
|
||||||
|
451
edgeremoval.ps1
@ -15,11 +15,6 @@ if ($also_remove_webview -eq 1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Administrative Privileges Check
|
# Administrative Privileges Check
|
||||||
|
|
||||||
# Get the 'SetPrivilege' method from System.Diagnostics.Process type
|
|
||||||
$setPrivilegeMethod = [System.Diagnostics.Process].GetMethod('SetPrivilege', [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Static)
|
|
||||||
|
|
||||||
# List of privileges to set
|
|
||||||
$privileges = @(
|
$privileges = @(
|
||||||
'SeSecurityPrivilege',
|
'SeSecurityPrivilege',
|
||||||
'SeTakeOwnershipPrivilege',
|
'SeTakeOwnershipPrivilege',
|
||||||
@ -27,44 +22,34 @@ $privileges = @(
|
|||||||
'SeRestorePrivilege'
|
'SeRestorePrivilege'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Invoke the method for each privilege
|
|
||||||
foreach ($privilege in $privileges) {
|
foreach ($privilege in $privileges) {
|
||||||
$setPrivilegeMethod.Invoke($null, @($privilege, 2))
|
[System.Diagnostics.Process]::SetPrivilege($privilege, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Edge Removal Procedures
|
# Edge Removal Procedures
|
||||||
|
|
||||||
# Define processes to shut down
|
|
||||||
$processesToShutdown = @(
|
$processesToShutdown = @(
|
||||||
'explorer', 'Widgets', 'widgetservice', 'msedgewebview2', 'MicrosoftEdge*', 'chredge',
|
'explorer', 'Widgets', 'widgetservice', 'msedgewebview2', 'MicrosoftEdge*', 'chredge',
|
||||||
'msedge', 'edge', 'msteams', 'msfamily', 'WebViewHost', 'Clipchamp'
|
'msedge', 'edge', 'msteams', 'msfamily', 'WebViewHost', 'Clipchamp'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Kill explorer process
|
|
||||||
Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue
|
Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# Kill the processes from the list
|
|
||||||
$processesToShutdown | ForEach-Object {
|
$processesToShutdown | ForEach-Object {
|
||||||
Stop-Process -Name $_ -Force -ErrorAction SilentlyContinue
|
Stop-Process -Name $_ -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set path for Edge executable
|
|
||||||
$MS = ($env:ProgramFiles, ${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem] + '\Microsoft\Edge\Application\msedge.exe'
|
$MS = ($env:ProgramFiles, ${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem] + '\Microsoft\Edge\Application\msedge.exe'
|
||||||
|
|
||||||
# Clean up certain registry entries
|
|
||||||
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe" -Recurse -ErrorAction SilentlyContinue
|
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe" -Recurse -ErrorAction SilentlyContinue
|
||||||
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ie_to_edge_stub.exe" -Recurse -ErrorAction SilentlyContinue
|
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ie_to_edge_stub.exe" -Recurse -ErrorAction SilentlyContinue
|
||||||
Remove-Item -Path 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\microsoft-edge' -Recurse -ErrorAction SilentlyContinue
|
Remove-Item -Path 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\microsoft-edge' -Recurse -ErrorAction SilentlyContinue
|
||||||
Remove-Item -Path 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\MSEdgeHTM' -Recurse -ErrorAction SilentlyContinue
|
Remove-Item -Path 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\MSEdgeHTM' -Recurse -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# Create new registry entries
|
|
||||||
New-Item -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Force -ErrorAction SilentlyContinue
|
New-Item -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Force -ErrorAction SilentlyContinue
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Name '(Default)' -Value "`"$MS`" --single-argument %%1" -Force -ErrorAction SilentlyContinue
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Name '(Default)' -Value "`"$MS`" --single-argument %%1" -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
New-Item -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Force -ErrorAction SilentlyContinue
|
New-Item -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Force -ErrorAction SilentlyContinue
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Name '(Default)' -Value "`"$MS`" --single-argument %%1" -Force -ErrorAction SilentlyContinue
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Name '(Default)' -Value "`"$MS`" --single-argument %%1" -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# Remove certain registry properties
|
|
||||||
$registryPaths = @('HKLM:\SOFTWARE\Policies', 'HKLM:\SOFTWARE', 'HKLM:\SOFTWARE\WOW6432Node')
|
$registryPaths = @('HKLM:\SOFTWARE\Policies', 'HKLM:\SOFTWARE', 'HKLM:\SOFTWARE\WOW6432Node')
|
||||||
$edgeProperties = @('InstallDefault', 'Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}', 'Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}')
|
$edgeProperties = @('InstallDefault', 'Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}', 'Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}')
|
||||||
foreach ($path in $registryPaths) {
|
foreach ($path in $registryPaths) {
|
||||||
@ -84,7 +69,6 @@ foreach ($base in $registryBases) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Clear specific registry keys
|
|
||||||
$registryPaths = @('HKCU:', 'HKLM:')
|
$registryPaths = @('HKCU:', 'HKLM:')
|
||||||
$nodes = @('', '\Wow6432Node')
|
$nodes = @('', '\Wow6432Node')
|
||||||
foreach ($regPath in $registryPaths) {
|
foreach ($regPath in $registryPaths) {
|
||||||
@ -97,7 +81,6 @@ foreach ($regPath in $registryPaths) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Locate setup.exe and ie_to_edge_stub.exe
|
|
||||||
$foldersToSearch = @('LocalApplicationData', 'ProgramFilesX86', 'ProgramFiles') | ForEach-Object {
|
$foldersToSearch = @('LocalApplicationData', 'ProgramFilesX86', 'ProgramFiles') | ForEach-Object {
|
||||||
[Environment]::GetFolderPath($_)
|
[Environment]::GetFolderPath($_)
|
||||||
}
|
}
|
||||||
@ -112,7 +95,6 @@ foreach ($folder in $foldersToSearch) {
|
|||||||
Where-Object { $_.FullName -notlike '*EdgeWebView*' }
|
Where-Object { $_.FullName -notlike '*EdgeWebView*' }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create directory and copy ie_to_edge_stub.exe to it
|
|
||||||
$destinationDir = "$env:SystemDrive\Scripts"
|
$destinationDir = "$env:SystemDrive\Scripts"
|
||||||
New-Item -Path $destinationDir -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
|
New-Item -Path $destinationDir -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
|
||||||
|
|
||||||
@ -125,342 +107,147 @@ foreach ($bhoFile in $bhoFiles) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
## Work on Appx Removals
|
## Work on Appx Removals
|
||||||
|
|
||||||
# Retrieve AppX provisioned packages and all AppX packages
|
|
||||||
$provisioned = Get-AppxProvisionedPackage -Online
|
$provisioned = Get-AppxProvisionedPackage -Online
|
||||||
$appxpackage = Get-AppxPackage -AllUsers
|
$appxpackage = Get-AppxPackage -AllUsers
|
||||||
|
|
||||||
# Initialize empty array for EndOfLife packages
|
|
||||||
$eol = @()
|
$eol = @()
|
||||||
|
|
||||||
# Define user SIDs and retrieve them from the registry
|
$store = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Store'
|
||||||
$store = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore'
|
$storeP = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Store\InstalledApplications'
|
||||||
$users = @('S-1-5-18')
|
foreach ($app in $appxpackage) {
|
||||||
if (Test-Path $store) {
|
$name = $app.Name
|
||||||
$users += (Get-ChildItem $store -ErrorAction SilentlyContinue | Where-Object { $_.PSChildName -like '*S-1-5-21*' }).PSChildName
|
if ($app.Name -eq "Microsoft.Edge") {
|
||||||
}
|
$eol += $name
|
||||||
|
} elseif ($app.Name -eq "Microsoft.EdgeBeta" -or $app.Name -eq "Microsoft.EdgeDev" -or $app.Name -eq "Microsoft.EdgeCanary" -or $app.Name -eq "Microsoft.MicrosoftEdge") {
|
||||||
# Process AppX packages for removal
|
$eol += $name
|
||||||
foreach ($choice in $remove_appx) {
|
|
||||||
if ([string]::IsNullOrWhiteSpace($choice)) { continue }
|
|
||||||
|
|
||||||
# Process provisioned packages
|
|
||||||
$provisioned | Where-Object { $_.PackageName -like "*$choice*" } | ForEach-Object {
|
|
||||||
if ($skip -Contains $_.PackageName) { return }
|
|
||||||
|
|
||||||
$PackageName = $_.PackageName
|
|
||||||
$PackageFamilyName = ($appxpackage | Where-Object { $_.Name -eq $_.DisplayName }).PackageFamilyName
|
|
||||||
|
|
||||||
# Add registry entries
|
|
||||||
New-Item -Path "$store\Deprovisioned\$PackageFamilyName" -Force -ErrorAction SilentlyContinue | Out-Null
|
|
||||||
$users | ForEach-Object {
|
|
||||||
New-Item -Path "$store\EndOfLife\$_\$PackageName" -Force -ErrorAction SilentlyContinue | Out-Null
|
|
||||||
}
|
|
||||||
$eol += $PackageName
|
|
||||||
|
|
||||||
# Modify non-removable app policy and remove package
|
|
||||||
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 | Out-Null
|
|
||||||
Remove-AppxProvisionedPackage -PackageName $PackageName -Online -AllUsers | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Process all AppX packages
|
|
||||||
$appxpackage | Where-Object { $_.PackageFullName -like "*$choice*" } | ForEach-Object {
|
|
||||||
if ($skip -Contains $_.PackageFullName) { return }
|
|
||||||
|
|
||||||
$PackageFullName = $_.PackageFullName
|
|
||||||
|
|
||||||
# Add registry entries
|
|
||||||
New-Item -Path "$store\Deprovisioned\$_.PackageFamilyName" -Force -ErrorAction SilentlyContinue | Out-Null
|
|
||||||
$users | ForEach-Object {
|
|
||||||
New-Item -Path "$store\EndOfLife\$_\$PackageFullName" -Force -ErrorAction SilentlyContinue | Out-Null
|
|
||||||
}
|
|
||||||
$eol += $PackageFullName
|
|
||||||
|
|
||||||
# Modify non-removable app policy and remove package
|
|
||||||
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 | Out-Null
|
|
||||||
Remove-AppxPackage -Package $PackageFullName -AllUsers | Out-Null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## Run Edge setup uninstaller
|
$eolApps = $provisioned | Where-Object { $eol -contains $_.DisplayName }
|
||||||
|
|
||||||
foreach ($setup in $edges) {
|
foreach ($edge in $eolApps) {
|
||||||
if (Test-Path $setup) {
|
$edgeName = $edge.DisplayName
|
||||||
$target = if ($setup -like '*EdgeWebView*') { "--msedgewebview" } else { "--msedge" }
|
if (-not ($skip -contains $edgeName)) {
|
||||||
|
|
||||||
$removalArgs = "--uninstall $target --system-level --verbose-logging --force-uninstall"
|
|
||||||
|
|
||||||
Write-Host "$setup $removalArgs"
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Start-Process -FilePath $setup -ArgumentList $removalArgs -Wait
|
Remove-AppxProvisionedPackage -Online -PackageName $edgeName -ErrorAction SilentlyContinue
|
||||||
} catch {
|
} catch { }
|
||||||
# You may want to add logging or other error handling here.
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((Get-Process -Name 'setup', 'MicrosoftEdge*' -ErrorAction SilentlyContinue).Path -like '*\Microsoft\Edge*') {
|
foreach ($edge in $appxpackage) {
|
||||||
Start-Sleep -Seconds 3
|
$edgeName = $edge.Name
|
||||||
|
if ($eol -contains $edgeName) {
|
||||||
|
if (-not ($skip -contains $edgeName)) {
|
||||||
|
try {
|
||||||
|
Remove-AppxPackage -Package $edgeName -AllUsers -ErrorAction SilentlyContinue
|
||||||
|
} catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## Cleanup
|
## Redirect shortcuts
|
||||||
|
$shortcut_path = "$env:Public\Desktop"
|
||||||
|
$shortcut_file = 'Microsoft Edge.lnk'
|
||||||
|
$full_path = Join-Path -Path $shortcut_path -ChildPath $shortcut_file
|
||||||
|
|
||||||
# Define necessary paths and variables
|
if (Test-Path $full_path) {
|
||||||
$edgePaths = $env:ProgramFiles, ${env:ProgramFiles(x86)}
|
Remove-Item -Path $full_path -Force -ErrorAction SilentlyContinue
|
||||||
$appDataPath = [Environment]::GetFolderPath('ApplicationData')
|
}
|
||||||
|
|
||||||
# Uninstall Microsoft Edge Update
|
$shortcut_path = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs"
|
||||||
foreach ($path in $edgePaths) {
|
$shortcut_file = 'Microsoft Edge.lnk'
|
||||||
$edgeUpdateExe = "$path\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe"
|
$full_path = Join-Path -Path $shortcut_path -ChildPath $shortcut_file
|
||||||
if (Test-Path $edgeUpdateExe) {
|
|
||||||
Write-Host $edgeUpdateExe /uninstall
|
if (Test-Path $full_path) {
|
||||||
Start-Process -FilePath $edgeUpdateExe -ArgumentList '/uninstall' -Wait
|
Remove-Item -Path $full_path -Force -ErrorAction SilentlyContinue
|
||||||
while ((Get-Process -Name 'setup','MicrosoftEdge*' -ErrorAction SilentlyContinue).Path -like '*\Microsoft\Edge*') {
|
}
|
||||||
Start-Sleep -Seconds 3
|
|
||||||
}
|
$edgePolicy = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge'
|
||||||
if ($also_remove_webview -eq 1) {
|
if (-not (Test-Path $edgePolicy)) {
|
||||||
foreach ($regPath in 'HKCU:', 'HKLM:') {
|
New-Item -Path $edgePolicy -Force | Out-Null
|
||||||
foreach ($node in '', '\Wow6432Node') {
|
}
|
||||||
Remove-Item -Path "$regPath\SOFTWARE$node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge Update" -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
$edgePrefs = @{
|
||||||
}
|
'Dword' = @{
|
||||||
Remove-Item -Path "$path\Microsoft\EdgeUpdate" -Recurse -Force -ErrorAction SilentlyContinue
|
'BrowserReplacementEnabled' = 1
|
||||||
Unregister-ScheduledTask -TaskName 'MicrosoftEdgeUpdate*' -Confirm:$false -ErrorAction SilentlyContinue
|
'HideFirstRunExperience' = 1
|
||||||
|
'HideImportEdgeFavoritesPrompt' = 1
|
||||||
|
'HideSyncSetupExperience' = 1
|
||||||
|
'FavoritesBarVisibility' = 1
|
||||||
|
}
|
||||||
|
'String' = @{
|
||||||
|
'AutoplayAllowed' = 'AllowOnce'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($entryType in $edgePrefs.Keys) {
|
||||||
|
foreach ($prefName in $edgePrefs[$entryType].Keys) {
|
||||||
|
Set-ItemProperty -Path $edgePolicy -Name $prefName -Value $edgePrefs[$entryType][$prefName] -Type $entryType -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Output Results
|
||||||
|
Write-Host "Edge Removal Complete" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Define constants and initial configuration
|
||||||
|
$ScriptVersion = "2023.05.10"
|
||||||
|
$EdgeProcessesToShutdown = @('explorer', 'Widgets', 'widgetservice', 'msedgewebview2', 'MicrosoftEdge*', 'chredge', 'msedge', 'edge', 'msteams', 'msfamily', 'WebViewHost', 'Clipchamp')
|
||||||
|
$EdgeRemovalOptions = @{
|
||||||
|
RemoveWin32 = @("Microsoft Edge", "Microsoft Edge Update")
|
||||||
|
RemoveAppx = @("MicrosoftEdge")
|
||||||
|
Skip = @() # Optional: @("DevTools")
|
||||||
|
AlsoRemoveWebView = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define main function to remove Microsoft Edge components
|
||||||
|
function Remove-MicrosoftEdge {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param()
|
||||||
|
|
||||||
|
# Function to shutdown processes related to Microsoft Edge
|
||||||
|
function Stop-EdgeProcesses {
|
||||||
|
$EdgeProcessesToShutdown | ForEach-Object {
|
||||||
|
Stop-Process -Name $_ -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Remove Edge shortcuts
|
# Function to remove registry entries related to Microsoft Edge
|
||||||
Remove-Item -Path "$appDataPath\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Tombstones\Microsoft Edge.lnk" -Force -ErrorAction SilentlyContinue
|
function Remove-EdgeRegistryEntries {
|
||||||
Remove-Item -Path "$appDataPath\Microsoft\Internet Explorer\Quick Launch\Microsoft Edge.lnk" -Force -ErrorAction SilentlyContinue
|
# Clean up certain registry entries
|
||||||
|
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe" -Recurse -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ie_to_edge_stub.exe" -Recurse -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Path 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\microsoft-edge' -Recurse -ErrorAction SilentlyContinue
|
||||||
|
Remove-Item -Path 'Registry::HKEY_Users\S-1-5-21*\Software\Classes\MSEdgeHTM' -Recurse -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# Revert settings related to Microsoft Edge
|
# Create new registry entries
|
||||||
foreach ($sid in $users) {
|
$EdgeExecutablePath = ($env:ProgramFiles, ${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem] + '\Microsoft\Edge\Application\msedge.exe'
|
||||||
foreach ($packageName in $eol) {
|
New-Item -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Force -ErrorAction SilentlyContinue
|
||||||
Remove-Item -Path "$store\EndOfLife\$sid\$packageName" -Force -ErrorAction SilentlyContinue
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Name '(Default)' -Value "`"$EdgeExecutablePath`" --single-argument %%1" -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
New-Item -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Force -ErrorAction SilentlyContinue
|
||||||
|
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Name '(Default)' -Value "`"$EdgeExecutablePath`" --single-argument %%1" -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Set policies to prevent unsolicited reinstalls of Microsoft Edge
|
# Function to remove Microsoft Edge AppX packages
|
||||||
$registryPaths = @('HKLM:\SOFTWARE\Policies', 'HKLM:\SOFTWARE', 'HKLM:\SOFTWARE\WOW6432Node')
|
function Remove-EdgeAppxPackages {
|
||||||
$edgeUpdatePolicies = @{
|
$EdgeRemovalOptions.RemoveAppx | ForEach-Object {
|
||||||
'InstallDefault' = 0;
|
# Remove provisioned packages
|
||||||
'Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}' = 0;
|
Get-AppxProvisionedPackage -Online | Where-Object { $_.PackageName -like "*$_*" -and $EdgeRemovalOptions.Skip -notcontains $_.PackageName } | Remove-AppxProvisionedPackage -Online -AllUsers -ErrorAction SilentlyContinue
|
||||||
'Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' = 1;
|
|
||||||
'DoNotUpdateToEdgeWithChromium' = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($path in $registryPaths) {
|
# Remove installed packages
|
||||||
New-Item -Path "$path\Microsoft\EdgeUpdate" -Force -ErrorAction SilentlyContinue | Out-Null
|
Get-AppxPackage -AllUsers | Where-Object { $_.PackageFullName -like "*$_*" -and $EdgeRemovalOptions.Skip -notcontains $_.PackageFullName } | Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
|
||||||
foreach ($policy in $edgeUpdatePolicies.GetEnumerator()) {
|
|
||||||
Set-ItemProperty -Path "$path\Microsoft\EdgeUpdate" -Name $policy.Key -Value $policy.Value -Type Dword -Force
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$edgeUpdateActions = @('on-os-upgrade', 'on-logon', 'on-logon-autolaunch', 'on-logon-startup-boost')
|
|
||||||
$edgeUpdateClients = @(
|
|
||||||
'Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}',
|
|
||||||
'Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'
|
|
||||||
)
|
|
||||||
foreach ($client in $edgeUpdateClients) {
|
|
||||||
foreach ($action in $edgeUpdateActions) {
|
|
||||||
foreach ($regBase in 'HKLM:\SOFTWARE', 'HKLM:\SOFTWARE\Wow6432Node') {
|
|
||||||
$regPath = "$regBase\$client\Commands\$action"
|
|
||||||
New-Item -Path $regPath -Force -ErrorAction SilentlyContinue | Out-Null
|
|
||||||
Set-ItemProperty -Path $regPath -Name 'CommandLine' -Value 'systray.exe' -Force
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Function to remove Microsoft Edge processes, registry entries, and AppX packages
|
||||||
|
try {
|
||||||
|
Stop-EdgeProcesses
|
||||||
|
Remove-EdgeRegistryEntries
|
||||||
|
Remove-EdgeAppxPackages
|
||||||
|
Write-Output "Microsoft Edge components have been successfully removed."
|
||||||
|
} catch {
|
||||||
|
Write-Error "Failed to remove Microsoft Edge components: $_"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
## Redirect Edge Shortcuts
|
# Execute the main function
|
||||||
|
Remove-MicrosoftEdge
|
||||||
# Define Microsoft Edge Paths
|
|
||||||
$MSEP = ($env:ProgramFiles, ${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem] + '\Microsoft\Edge\Application'
|
|
||||||
$IFEO = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options'
|
|
||||||
$MIN = ('--headless', '--width 1 --height 1')[([environment]::OSVersion.Version.Build) -gt 25179]
|
|
||||||
$CMD = "$env:systemroot\system32\conhost.exe $MIN"
|
|
||||||
$DIR = "$env:SystemDrive\Scripts"
|
|
||||||
|
|
||||||
# Setup Microsoft Edge Registry Entries
|
|
||||||
New-Item -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Force | Out-Null
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge" -Name '(Default)' -Value 'URL:microsoft-edge' -Force
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge" -Name 'URL Protocol' -Value '' -Force
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge" -Name 'NoOpenWith' -Value '' -Force
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -Name '(Default)' -Value "`"$DIR\ie_to_edge_stub.exe`" %1" -Force
|
|
||||||
|
|
||||||
# Setup MSEdgeHTM Registry Entries
|
|
||||||
New-Item -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Force | Out-Null
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM" -Name 'NoOpenWith' -Value '' -Force
|
|
||||||
Set-ItemProperty -Path "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -Name '(Default)' -Value "`"$DIR\ie_to_edge_stub.exe`" %1" -Force
|
|
||||||
|
|
||||||
# Setup Image File Execution Options for Edge and Edge WebView
|
|
||||||
$exeSettings = @(
|
|
||||||
@{ ExeName = 'ie_to_edge_stub.exe'; Debugger = "$CMD $DIR\OpenWebSearch.cmd"; FilterPath = "$DIR\ie_to_edge_stub.exe" },
|
|
||||||
@{ ExeName = 'msedge.exe'; Debugger = "$CMD $DIR\OpenWebSearch.cmd"; FilterPath = "$MSEP\msedge.exe" }
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($setting in $exeSettings) {
|
|
||||||
New-Item -Path "$IFEO\$($setting.ExeName)\0" -Force | Out-Null
|
|
||||||
Set-ItemProperty -Path "$IFEO\$($setting.ExeName)" -Name 'UseFilter' -Value 1 -Type Dword -Force
|
|
||||||
Set-ItemProperty -Path "$IFEO\$($setting.ExeName)\0" -Name 'FilterFullPath' -Value $setting.FilterPath -Force
|
|
||||||
Set-ItemProperty -Path "$IFEO\$($setting.ExeName)\0" -Name 'Debugger' -Value $setting.Debugger -Force
|
|
||||||
}
|
|
||||||
|
|
||||||
# Write OpenWebSearch Batch Script
|
|
||||||
$OpenWebSearch = @'
|
|
||||||
@echo off
|
|
||||||
@title OpenWebSearch Redux
|
|
||||||
|
|
||||||
:: Minimize prompt
|
|
||||||
for /f %%E in ('"prompt $E$S & for %%e in (1) do rem"') do echo;%%E[2t >nul 2>&1
|
|
||||||
|
|
||||||
:: Get default browser from registry
|
|
||||||
call :get_registry_value "HKCU\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice" ProgID DefaultBrowser
|
|
||||||
if not defined DefaultBrowser (
|
|
||||||
echo Error: Failed to get default browser from registry.
|
|
||||||
pause
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
if /i "%DefaultBrowser%" equ "MSEdgeHTM" (
|
|
||||||
echo Error: Default browser is set to Edge! Change it or remove OpenWebSearch script.
|
|
||||||
pause
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Get browser command line
|
|
||||||
call :get_registry_value "HKCR\%DefaultBrowser%\shell\open\command" "" BrowserCommand
|
|
||||||
if not defined BrowserCommand (
|
|
||||||
echo Error: Failed to get browser command from registry.
|
|
||||||
pause
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
set Browser=& for %%i in (%BrowserCommand%) do if not defined Browser set "Browser=%%~i"
|
|
||||||
|
|
||||||
:: Set fallback for Edge
|
|
||||||
call :get_registry_value "HKCR\MSEdgeMHT\shell\open\command" "" FallBack
|
|
||||||
set EdgeCommand=& for %%i in (%FallBack%) do if not defined EdgeCommand set "EdgeCommand=%%~i"
|
|
||||||
|
|
||||||
:: Parse command line arguments and check for redirect or noop conditions
|
|
||||||
set "URI=" & set "URL=" & set "NOOP=" & set "PassThrough=%EdgeCommand:msedge=edge%"
|
|
||||||
set "CommandLineArgs=%CMDCMDLINE:"=``% "
|
|
||||||
call :parse_arguments
|
|
||||||
|
|
||||||
if defined NOOP (
|
|
||||||
if not exist "%PassThrough%" (
|
|
||||||
echo Error: PassThrough path doesn't exist.
|
|
||||||
pause
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
start "" "%PassThrough%" %ParsedArgs%
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Decode URL
|
|
||||||
call :decode_url
|
|
||||||
if not defined URL (
|
|
||||||
echo Error: Failed to decode URL.
|
|
||||||
pause
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Open URL in default browser
|
|
||||||
start "" "%Browser%" "%URL%"
|
|
||||||
exit
|
|
||||||
|
|
||||||
:: Functions
|
|
||||||
|
|
||||||
:get_registry_value
|
|
||||||
setlocal
|
|
||||||
set regQuery=reg query "%~1" /v %2 /z /se "," /f /e
|
|
||||||
if "%~2" equ "" set regQuery=reg query "%~1" /ve /z /se "," /f /e
|
|
||||||
for /f "skip=2 tokens=* delims=" %%V in ('%regQuery% 2^>nul') do set "result=%%V"
|
|
||||||
if defined result (set "result=%result:*) =%") else (set "%~3=")
|
|
||||||
endlocal & set "%~3=%result%"
|
|
||||||
exit /b
|
|
||||||
|
|
||||||
:decode_url
|
|
||||||
:: Brute URL percent decoding
|
|
||||||
setlocal enabledelayedexpansion
|
|
||||||
set "decoded=%URL:!=}%"
|
|
||||||
call :brute_decode
|
|
||||||
endlocal & set "URL=%decoded%"
|
|
||||||
exit /b
|
|
||||||
|
|
||||||
:parse_arguments
|
|
||||||
:: Remove specific substrings from arguments
|
|
||||||
set "CommandLineArgs=%CommandLineArgs:*ie_to_edge_stub.exe`` =%"
|
|
||||||
set "CommandLineArgs=%CommandLineArgs:*ie_to_edge_stub.exe =%"
|
|
||||||
set "CommandLineArgs=%CommandLineArgs:*msedge.exe`` =%"
|
|
||||||
set "CommandLineArgs=%CommandLineArgs:*msedge.exe =%"
|
|
||||||
|
|
||||||
:: Remove any trailing spaces
|
|
||||||
if "%CommandLineArgs:~-1%"==" " set "CommandLineArgs=%CommandLineArgs:~0,-1%"
|
|
||||||
|
|
||||||
:: Check if arguments are a redirect or URL
|
|
||||||
set "RedirectArg=%CommandLineArgs:microsoft-edge=%"
|
|
||||||
set "UrlArg=%CommandLineArgs:http=%"
|
|
||||||
set "ParsedArgs=%CommandLineArgs:``="%"
|
|
||||||
|
|
||||||
:: Set NOOP flag if no changes to arguments
|
|
||||||
if "%CommandLineArgs%" equ "%RedirectArg%" (set NOOP=1) else if "%CommandLineArgs%" equ "%UrlArg%" (set NOOP=1)
|
|
||||||
|
|
||||||
:: Extract URL if present
|
|
||||||
if not defined NOOP (
|
|
||||||
set "URL=%CommandLineArgs:*microsoft-edge=%"
|
|
||||||
set "URL=http%URL:*http=%"
|
|
||||||
if "%URL:~-2%"=="``" set "URL=%URL:~0,-2%"
|
|
||||||
)
|
|
||||||
exit /b
|
|
||||||
|
|
||||||
|
|
||||||
:brute_decode
|
|
||||||
:: Brute force URL percent decoding
|
|
||||||
|
|
||||||
set "decoded=%decoded:%%20= %"
|
|
||||||
set "decoded=%decoded:%%21=!!"
|
|
||||||
set "decoded=%decoded:%%22="%""
|
|
||||||
set "decoded=%decoded:%%23=#%"
|
|
||||||
set "decoded=%decoded:%%24=$%"
|
|
||||||
set "decoded=%decoded:%%25=%%%"
|
|
||||||
set "decoded=%decoded:%%26=&%"
|
|
||||||
set "decoded=%decoded:%%27='%"
|
|
||||||
set "decoded=%decoded:%%28=(%"
|
|
||||||
set "decoded=%decoded:%%29=)%"
|
|
||||||
set "decoded=%decoded:%%2A=*%"
|
|
||||||
set "decoded=%decoded:%%2B=+%"
|
|
||||||
set "decoded=%decoded:%%2C=,%"
|
|
||||||
set "decoded=%decoded:%%2D=-%"
|
|
||||||
set "decoded=%decoded:%%2E=.%"
|
|
||||||
set "decoded=%decoded:%%2F=/%"
|
|
||||||
:: ... Continue for other encodings ...
|
|
||||||
|
|
||||||
:: Correct any double percentage signs
|
|
||||||
set "decoded=%decoded:%%%%=%"
|
|
||||||
|
|
||||||
exit /b
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'@
|
|
||||||
[io.file]::WriteAllText("$DIR\OpenWebSearch.cmd", $OpenWebSearch)
|
|
||||||
|
|
||||||
|
|
||||||
# Final Steps
|
|
||||||
|
|
||||||
# Retrieve the Edge_Removal property from the specified registry paths
|
|
||||||
$userRegPaths = Get-ChildItem -Path 'Registry::HKEY_Users\S-1-5-21*\Volatile*' -ErrorAction SilentlyContinue
|
|
||||||
$edgeRemovalPath = $userRegPaths | Get-ItemProperty -Name 'Edge_Removal' -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
# If the Edge_Removal property exists, remove it
|
|
||||||
if ($edgeRemovalPath) {
|
|
||||||
Remove-ItemProperty -Path $edgeRemovalPath.PSPath -Name 'Edge_Removal' -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure the explorer process is running
|
|
||||||
if (-not (Get-Process -Name 'explorer' -ErrorAction SilentlyContinue)) {
|
|
||||||
Start-Process 'explorer'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,27 +1,93 @@
|
|||||||
function ConvertTo-Icon {
|
function ConvertTo-Icon {
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function will convert PNG to ICO file
|
This function will convert BMP, GIF, EXIF, JPG, PNG and TIFF to ICO file
|
||||||
|
|
||||||
|
.PARAMETER bitmapPath
|
||||||
|
The file path to bitmap image to make '.ico' file out of.
|
||||||
|
Supported file types according to Microsoft Documentation is the following:
|
||||||
|
BMP, GIF, EXIF, JPG, PNG and TIFF.
|
||||||
|
|
||||||
|
.PARAMETER iconPath
|
||||||
|
The file path to write the new '.ico' resource.
|
||||||
|
|
||||||
|
.PARAMETER overrideIconFile
|
||||||
|
An optional boolean Parameter that makes the function overrides
|
||||||
|
the Icon File Path if the file exists. Defaults to $true.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath $iconPath
|
try {
|
||||||
|
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico"
|
||||||
|
} catch [System.IO.FileNotFoundException] {
|
||||||
|
# Handle the thrown exception here...
|
||||||
|
}
|
||||||
|
|
||||||
|
This Example makes a '.ico' file at "$env:TEMP\cttlogo.ico" File Path using the bitmap file
|
||||||
|
found in "$env:TEMP\cttlogo.png", the function overrides the '.ico' File if it's found.
|
||||||
|
this function will throw a FileNotFound Exception at the event of not finding the provided bitmap File Path.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
try {
|
||||||
|
ConvertTo-Icon "$env:TEMP\cttlogo.png" "$env:TEMP\cttlogo.ico"
|
||||||
|
} catch [System.IO.FileNotFoundException] {
|
||||||
|
# Handle the thrown exception here...
|
||||||
|
}
|
||||||
|
|
||||||
|
This Example is the same as Example 1, but uses Positional Parameters instead.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
if (Test-Path "$env:TEMP\cttlogo.png") {
|
||||||
|
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico"
|
||||||
|
}
|
||||||
|
|
||||||
|
This Example is same as Example 1, but checks if the bitmap File exists before calling 'ConvertTo-Icon' Function.
|
||||||
|
This's the recommended way of using this function, as it doesn't require any try-catch blocks.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
try {
|
||||||
|
ConvertTo-Icon -bitmapPath "$env:TEMP\cttlogo.png" -iconPath "$env:TEMP\cttlogo.ico" -overrideIconFile $false
|
||||||
|
} catch [System.IO.FileNotFoundException] {
|
||||||
|
# Handle the thrown exception here...
|
||||||
|
}
|
||||||
|
|
||||||
|
This Example make use of '-overrideIconFile' Optional Parameter, the default for this paramter is $true.
|
||||||
|
By doing '-overrideIconFile $false', the 'ConvertTo-Icon' function will raise an exception that needs to be catched throw a 'catch' Code Block,
|
||||||
|
otherwise it'll crash the running PowerShell instance/process.
|
||||||
|
|
||||||
#>
|
#>
|
||||||
param( [Parameter(Mandatory=$true)]
|
param(
|
||||||
$bitmapPath,
|
[Parameter(Mandatory=$true, position=0)]
|
||||||
$iconPath = "$env:temp\newicon.ico"
|
[string]$bitmapPath,
|
||||||
)
|
[Parameter(Mandatory=$true, position=1)]
|
||||||
|
[string]$iconPath,
|
||||||
Add-Type -AssemblyName System.Drawing
|
[Parameter(position=2)]
|
||||||
|
[bool]$overrideIconFile = $true
|
||||||
if (Test-Path $bitmapPath) {
|
)
|
||||||
$b = [System.Drawing.Bitmap]::FromFile($bitmapPath)
|
|
||||||
$icon = [System.Drawing.Icon]::FromHandle($b.GetHicon())
|
Add-Type -AssemblyName System.Drawing
|
||||||
$file = New-Object System.IO.FileStream($iconPath, 'OpenOrCreate')
|
|
||||||
$icon.Save($file)
|
if (Test-Path $bitmapPath) {
|
||||||
$file.Close()
|
if ((Test-Path $iconPath) -AND ($overrideIconFile -eq $false)) {
|
||||||
$icon.Dispose()
|
Write-Host "[ConvertTo-Icon] Icon File is found at '$iconPath', and the 'overrideIconFile' Parameter is set to '$overrideIconFile'. Skipping the bitmap to icon convertion..." -ForegroundColor Yellow
|
||||||
#explorer "/SELECT,$iconpath"
|
return
|
||||||
}
|
}
|
||||||
else { Write-Warning "$BitmapPath does not exist" }
|
|
||||||
}
|
# Load bitmap file into memory, and make an Icon version out of it
|
||||||
|
$b = [System.Drawing.Bitmap]::FromFile($bitmapPath)
|
||||||
|
$icon = [System.Drawing.Icon]::FromHandle($b.GetHicon())
|
||||||
|
|
||||||
|
# Create the folder for the new icon file if it doesn't exists
|
||||||
|
$iconFolder = (New-Object System.IO.FileInfo($iconPath)).Directory.FullName
|
||||||
|
[System.IO.Directory]::CreateDirectory($iconFolder) | Out-Null
|
||||||
|
|
||||||
|
# Write the Icon File and do some cleaning-up
|
||||||
|
$file = New-Object System.IO.FileStream($iconPath, 'OpenOrCreate')
|
||||||
|
$icon.Save($file)
|
||||||
|
$file.Close()
|
||||||
|
$icon.Dispose()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw [System.IO.FileNotFoundException] "[ConvertTo-Icon] The provided bitmap File Path is not found at '$bitmapPath'."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
function Copy-Files {
|
function Copy-Files {
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function will make all modifications to the registry
|
This function will make all modifications to the registry
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
|
|
||||||
Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0"
|
Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0"
|
||||||
|
|
||||||
#>
|
#>
|
||||||
param (
|
param (
|
||||||
[string] $Path,
|
[string] $Path,
|
||||||
[string] $Destination,
|
[string] $Destination,
|
||||||
[switch] $Recurse = $false,
|
[switch] $Recurse = $false,
|
||||||
[switch] $Force = $false
|
[switch] $Force = $false
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$files = Get-ChildItem -Path $path -Recurse:$recurse
|
$files = Get-ChildItem -Path $path -Recurse:$recurse
|
||||||
Write-Host "Copy $($files.Count)(s) from $path to $destination"
|
Write-Host "Copy $($files.Count)(s) from $path to $destination"
|
||||||
@ -35,9 +35,9 @@ function Copy-Files {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Write-Debug "Copy from $($file.FullName) to $($destination+$restpath)"
|
Write-Debug "Copy from $($file.FullName) to $($destination+$restpath)"
|
||||||
Copy-Item $file.FullName ($destination+$restpath) -ErrorAction SilentlyContinue -Force:$force
|
Copy-Item $file.FullName ($destination+$restpath) -ErrorAction SilentlyContinue -Force:$force
|
||||||
Set-ItemProperty -Path ($destination+$restpath) -Name IsReadOnly -Value $false
|
Set-ItemProperty -Path ($destination+$restpath) -Name IsReadOnly -Value $false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed
|
Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
function Get-LocalizedYesNo {
|
function Get-LocalizedYesNo {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
This function runs choice.exe and captures its output to extract yes no in a localized Windows
|
This function runs choice.exe and captures its output to extract yes no in a localized Windows
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
The function retrieves the output of the command 'cmd /c "choice <nul 2>nul"' and converts the default output for Yes and No
|
The function retrieves the output of the command 'cmd /c "choice <nul 2>nul"' and converts the default output for Yes and No
|
||||||
in the localized format, such as "Yes=<first character>, No=<second character>".
|
in the localized format, such as "Yes=<first character>, No=<second character>".
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
$yesNoArray = Get-LocalizedYesNo
|
$yesNoArray = Get-LocalizedYesNo
|
||||||
Write-Host "Yes=$($yesNoArray[0]), No=$($yesNoArray[1])"
|
Write-Host "Yes=$($yesNoArray[0]), No=$($yesNoArray[1])"
|
||||||
#>
|
#>
|
||||||
|
|
||||||
# Run choice and capture its options as output
|
# Run choice and capture its options as output
|
||||||
# The output shows the options for Yes and No as "[Y,N]?" in the (partitially) localized format.
|
# The output shows the options for Yes and No as "[Y,N]?" in the (partitially) localized format.
|
||||||
# eg. English: [Y,N]?
|
# eg. English: [Y,N]?
|
||||||
@ -21,7 +21,7 @@ function Get-LocalizedYesNo {
|
|||||||
# Spanish: [S,N]?
|
# Spanish: [S,N]?
|
||||||
# Italian: [S,N]?
|
# Italian: [S,N]?
|
||||||
# Russian: [Y,N]?
|
# Russian: [Y,N]?
|
||||||
|
|
||||||
$line = cmd /c "choice <nul 2>nul"
|
$line = cmd /c "choice <nul 2>nul"
|
||||||
$charactersArray = @()
|
$charactersArray = @()
|
||||||
$regexPattern = '([a-zA-Z])'
|
$regexPattern = '([a-zA-Z])'
|
||||||
@ -30,58 +30,5 @@ function Get-LocalizedYesNo {
|
|||||||
Write-Debug "According to takeown.exe local Yes is $charactersArray[0]"
|
Write-Debug "According to takeown.exe local Yes is $charactersArray[0]"
|
||||||
# Return the array of characters
|
# Return the array of characters
|
||||||
return $charactersArray
|
return $charactersArray
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Get-LocalizedYesNoTakeown {
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
This function runs takeown.exe and captures its output to extract yes no in a localized Windows
|
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
The function retrieves lines from the output of takeown.exe until there are at least 2 characters
|
|
||||||
captured in a specific format, such as "Yes=<first character>, No=<second character>".
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
$yesNoArray = Get-LocalizedYesNo
|
|
||||||
Write-Host "Yes=$($yesNoArray[0]), No=$($yesNoArray[1])"
|
|
||||||
#>
|
|
||||||
|
|
||||||
# Run takeown.exe and capture its output
|
|
||||||
$takeownOutput = & takeown.exe /? | Out-String
|
|
||||||
|
|
||||||
# Parse the output and retrieve lines until there are at least 2 characters in the array
|
|
||||||
$found = $false
|
|
||||||
$charactersArray = @()
|
|
||||||
foreach ($line in $takeownOutput -split "`r`n")
|
|
||||||
{
|
|
||||||
# skip everything before /D flag help
|
|
||||||
if ($found)
|
|
||||||
{
|
|
||||||
# now that /D is found start looking for a single character in double quotes
|
|
||||||
# in help text there is another string in double quotes but it is not a single character
|
|
||||||
$regexPattern = '"([a-zA-Z])"'
|
|
||||||
|
|
||||||
$charactersArray = [regex]::Matches($line, $regexPattern) | ForEach-Object { $_.Groups[1].Value }
|
|
||||||
|
|
||||||
# if ($charactersArray.Count -gt 0) {
|
|
||||||
# Write-Output "Extracted symbols: $($matches -join ', ')"
|
|
||||||
# } else {
|
|
||||||
# Write-Output "No matches found."
|
|
||||||
# }
|
|
||||||
|
|
||||||
if ($charactersArray.Count -ge 2)
|
|
||||||
{
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif ($line -match "/D ")
|
|
||||||
{
|
|
||||||
$found = $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Debug "According to takeown.exe local Yes is $charactersArray[0]"
|
|
||||||
# Return the array of characters
|
|
||||||
return $charactersArray
|
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
function Get-Oscdimg {
|
function Get-Oscdimg {
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function will get oscdimg file for from github Release foldersand put it into env:temp
|
This function will download oscdimg file from github Release folders and put it into env:temp folder
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Get-Oscdimg
|
Get-Oscdimg
|
||||||
#>
|
#>
|
||||||
param( [Parameter(Mandatory=$true)]
|
param( [Parameter(Mandatory=$true)]
|
||||||
[string]$oscdimgPath
|
[string]$oscdimgPath
|
||||||
)
|
)
|
||||||
$oscdimgPath = "$env:TEMP\oscdimg.exe"
|
$oscdimgPath = "$env:TEMP\oscdimg.exe"
|
||||||
@ -24,4 +24,4 @@ function Get-Oscdimg {
|
|||||||
} else {
|
} else {
|
||||||
Write-Host "Hashes do not match. File may be corrupted or tampered with."
|
Write-Host "Hashes do not match. File may be corrupted or tampered with."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,19 +6,31 @@ function Get-TabXaml {
|
|||||||
It takes the tabname and the number of columns to display the applications in as input and returns the XAML for the tab as output
|
It takes the tabname and the number of columns to display the applications in as input and returns the XAML for the tab as output
|
||||||
.PARAMETER tabname
|
.PARAMETER tabname
|
||||||
The name of the tab to generate XAML for
|
The name of the tab to generate XAML for
|
||||||
|
Note: the 'tabname' parameter must equal one of the json files found in $sync.configs variable
|
||||||
|
Otherwise, it'll throw an exception
|
||||||
.PARAMETER columncount
|
.PARAMETER columncount
|
||||||
The number of columns to display the applications in
|
The number of columns to display the applications in, default is 0
|
||||||
.OUTPUTS
|
.OUTPUTS
|
||||||
The XAML for the tab
|
The XAML for the tab
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Get-TabXaml "applications" 3
|
Get-TabXaml "applications" 3
|
||||||
#>
|
#>
|
||||||
|
|
||||||
|
|
||||||
param( [Parameter(Mandatory=$true)]
|
param(
|
||||||
$tabname,
|
[Parameter(Mandatory, position=0)]
|
||||||
$columncount = 0
|
[string]$tabname,
|
||||||
|
|
||||||
|
[Parameter(position=1)]
|
||||||
|
[ValidateRange(0,10)] # 10 panels as max number is more then enough
|
||||||
|
[int]$columncount = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Validate tabname
|
||||||
|
if ($sync.configs.$tabname -eq $null) {
|
||||||
|
throw "Invalid parameter passed, can't find '$tabname' in '`$sync.configs' variable, please double check any calls to 'Get-TabXaml' function."
|
||||||
|
}
|
||||||
|
|
||||||
$organizedData = @{}
|
$organizedData = @{}
|
||||||
# Iterate through JSON data and organize by panel and category
|
# Iterate through JSON data and organize by panel and category
|
||||||
foreach ($appName in $sync.configs.$tabname.PSObject.Properties.Name) {
|
foreach ($appName in $sync.configs.$tabname.PSObject.Properties.Name) {
|
||||||
@ -39,6 +51,7 @@ function Get-TabXaml {
|
|||||||
ComboItems = $appInfo.ComboItems
|
ComboItems = $appInfo.ComboItems
|
||||||
# Checked is the property to set startup checked status of checkbox (Default is false)
|
# Checked is the property to set startup checked status of checkbox (Default is false)
|
||||||
Checked = $appInfo.Checked
|
Checked = $appInfo.Checked
|
||||||
|
ButtonWidth = $appInfo.ButtonWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-not $organizedData.ContainsKey($appObject.panel)) {
|
if (-not $organizedData.ContainsKey($appObject.panel)) {
|
||||||
@ -53,7 +66,22 @@ function Get-TabXaml {
|
|||||||
# Add Order property to keep the original order of tweaks and features
|
# Add Order property to keep the original order of tweaks and features
|
||||||
$organizedData[$appObject.panel][$appInfo.Category]["$($appInfo.order)$appName"] = $appObject
|
$organizedData[$appObject.panel][$appInfo.Category]["$($appInfo.order)$appName"] = $appObject
|
||||||
}
|
}
|
||||||
$panelcount=0
|
|
||||||
|
# Same tab amount in last line of 'inputXML.xaml' file
|
||||||
|
# TODO: Get the base repeat (amount) of tabs from last line (or even lines)
|
||||||
|
# so it can dynamicly react to whatever is before this generated XML string.
|
||||||
|
# .. may be solve this even before calling this function, and pass the result as a parameter?
|
||||||
|
$tab_repeat = 7
|
||||||
|
$spaces_per_tab = 4 # The convenction used across the code base
|
||||||
|
$tab_as_spaces = $(" " * $spaces_per_tab)
|
||||||
|
$precal_indent = $($tab_as_spaces * $tab_repeat)
|
||||||
|
$precal_indent_p1 = $($tab_as_spaces * ($tab_repeat + 1))
|
||||||
|
$precal_indent_p2 = $($tab_as_spaces * ($tab_repeat + 2))
|
||||||
|
$precal_indent_m1 = $($tab_as_spaces * ($tab_repeat - 1))
|
||||||
|
$precal_indent_m2 = $($tab_as_spaces * ($tab_repeat - 2))
|
||||||
|
|
||||||
|
# Calculate the needed number of panels
|
||||||
|
$panelcount = 0
|
||||||
$paneltotal = $organizedData.Keys.Count
|
$paneltotal = $organizedData.Keys.Count
|
||||||
if ($columncount -gt 0) {
|
if ($columncount -gt 0) {
|
||||||
$appcount = $sync.configs.$tabname.PSObject.Properties.Name.count + $organizedData["0"].Keys.count
|
$appcount = $sync.configs.$tabname.PSObject.Properties.Name.count + $organizedData["0"].Keys.count
|
||||||
@ -61,65 +89,129 @@ function Get-TabXaml {
|
|||||||
$paneltotal = $columncount
|
$paneltotal = $columncount
|
||||||
}
|
}
|
||||||
# add ColumnDefinitions to evenly draw colums
|
# add ColumnDefinitions to evenly draw colums
|
||||||
$blockXml="<Grid.ColumnDefinitions>`n"+("<ColumnDefinition Width=""*""/>`n"*($paneltotal))+"</Grid.ColumnDefinitions>`n"
|
$blockXml = "<Grid.ColumnDefinitions>"
|
||||||
# Iterate through organizedData by panel, category, and application
|
$blockXml += $("`r`n" + " " * ($spaces_per_tab * $tab_repeat) +
|
||||||
|
"<ColumnDefinition Width=""*""/>") * $paneltotal
|
||||||
|
$blockXml += $("`r`n" + " " * ($spaces_per_tab * ($tab_repeat - 1))) +
|
||||||
|
"</Grid.ColumnDefinitions>" + "`r`n"
|
||||||
|
|
||||||
|
# Iterate through 'organizedData' by panel, category, and application
|
||||||
$count = 0
|
$count = 0
|
||||||
foreach ($panel in ($organizedData.Keys | Sort-Object)) {
|
foreach ($panel in ($organizedData.Keys | Sort-Object)) {
|
||||||
$blockXml += "<Border Grid.Row=""1"" Grid.Column=""$panelcount"">`n<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">`n"
|
$blockXml += $precal_indent_m1 + "<Border Grid.Row=""1"" Grid.Column=""$panelcount"">" + "`r`n"
|
||||||
|
$blockXml += $precal_indent + "<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">" + "`r`n"
|
||||||
$panelcount++
|
$panelcount++
|
||||||
foreach ($category in ($organizedData[$panel].Keys | Sort-Object)) {
|
foreach ($category in ($organizedData[$panel].Keys | Sort-Object)) {
|
||||||
$count++
|
$count++
|
||||||
if ($columncount -gt 0) {
|
if ($columncount -gt 0) {
|
||||||
$panelcount2 = [Int](($count)/$maxcount-0.5)
|
$panelcount2 = [Int](($count)/$maxcount-0.5)
|
||||||
if ($panelcount -eq $panelcount2 ) {
|
if ($panelcount -eq $panelcount2 ) {
|
||||||
$blockXml +="`n</StackPanel>`n</Border>`n"
|
$blockXml += $precal_indent_p2 + "</StackPanel>" + "`r`n"
|
||||||
$blockXml += "<Border Grid.Row=""1"" Grid.Column=""$panelcount"">`n<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">`n"
|
$blockXml += $precal_indent_p1 + "</Border>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_p1 + "<Border Grid.Row=""1"" Grid.Column=""$panelcount"">" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_p2 + "<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">" + "`r`n"
|
||||||
$panelcount++
|
$panelcount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$blockXml += "<Label Content=""$($category -replace '^.__', '')"" FontSize=""16""/>`n"
|
|
||||||
|
# Dot-source the Get-WPFObjectName function
|
||||||
|
. .\functions\private\Get-WPFObjectName
|
||||||
|
|
||||||
|
$categorycontent = $($category -replace '^.__', '')
|
||||||
|
$categoryname = Get-WPFObjectName -type "Label" -name $categorycontent
|
||||||
|
$blockXml += $("`r`n" + " " * ($spaces_per_tab * $tab_repeat)) +
|
||||||
|
"<Label Name=""$categoryname"" Content=""$categorycontent""" + " " +
|
||||||
|
"FontSize=""{FontSizeHeading}"" FontFamily=""{HeaderFontFamily}""/>" + "`r`n" + "`r`n"
|
||||||
$sortedApps = $organizedData[$panel][$category].Keys | Sort-Object
|
$sortedApps = $organizedData[$panel][$category].Keys | Sort-Object
|
||||||
foreach ($appName in $sortedApps) {
|
foreach ($appName in $sortedApps) {
|
||||||
$count++
|
$count++
|
||||||
|
|
||||||
if ($columncount -gt 0) {
|
if ($columncount -gt 0) {
|
||||||
$panelcount2 = [Int](($count)/$maxcount-0.5)
|
$panelcount2 = [Int](($count)/$maxcount-0.5)
|
||||||
|
# Verify the indentation actually works...
|
||||||
if ($panelcount -eq $panelcount2 ) {
|
if ($panelcount -eq $panelcount2 ) {
|
||||||
$blockXml +="`n</StackPanel>`n</Border>`n"
|
$blockXml += $precal_indent_m1 +
|
||||||
$blockXml += "<Border Grid.Row=""1"" Grid.Column=""$panelcount"">`n<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">`n"
|
"</StackPanel>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_m2 +
|
||||||
|
"</Border>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_m2 +
|
||||||
|
"<Border Grid.Row=""1"" Grid.Column=""$panelcount"">" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_m1 +
|
||||||
|
"<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">" + "`r`n"
|
||||||
$panelcount++
|
$panelcount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$appInfo = $organizedData[$panel][$category][$appName]
|
$appInfo = $organizedData[$panel][$category][$appName]
|
||||||
if ("Toggle" -eq $appInfo.Type) {
|
switch ($appInfo.Type) {
|
||||||
$blockXml += "<StackPanel Orientation=`"Horizontal`" Margin=`"0,10,0,0`">`n<Label Content=`"$($appInfo.Content)`" Style=`"{StaticResource labelfortweaks}`" ToolTip=`"$($appInfo.Description)`" />`n"
|
"Toggle" {
|
||||||
$blockXml += "<CheckBox Name=`"$($appInfo.Name)`" Style=`"{StaticResource ColorfulToggleSwitchStyle}`" Margin=`"2.5,0`"/>`n</StackPanel>`n"
|
$blockXml += $precal_indent_m1 +
|
||||||
} elseif ("Combobox" -eq $appInfo.Type) {
|
"<DockPanel LastChildFill=""True"">" + "`r`n"
|
||||||
$blockXml += "<StackPanel Orientation=`"Horizontal`" Margin=`"0,5,0,0`">`n<Label Content=`"$($appInfo.Content)`" HorizontalAlignment=`"Left`" VerticalAlignment=`"Center`"/>`n"
|
$blockXml += $precal_indent +
|
||||||
$blockXml += "<ComboBox Name=`"$($appInfo.Name)`" Height=`"32`" Width=`"186`" HorizontalAlignment=`"Left`" VerticalAlignment=`"Center`" Margin=`"5,5`">`n"
|
"<CheckBox Name=""$($appInfo.Name)"" Style=""{StaticResource ColorfulToggleSwitchStyle}"" Margin=""4,0""" + " " +
|
||||||
$addfirst="IsSelected=`"True`""
|
"HorizontalAlignment=""Right"" FontSize=""{FontSize}""/>" + "`r`n"
|
||||||
foreach ($comboitem in ($appInfo.ComboItems -split " ")) {
|
$blockXml += $precal_indent +
|
||||||
$blockXml += "<ComboBoxItem $addfirst Content=`"$comboitem`"/>`n"
|
"<Label Content=""$($appInfo.Content)"" ToolTip=""$($appInfo.Description)""" + " " +
|
||||||
$addfirst=""
|
"HorizontalAlignment=""Left"" FontSize=""{FontSize}""/>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_m1 +
|
||||||
|
"</DockPanel>" + "`r`n"
|
||||||
}
|
}
|
||||||
$blockXml += "</ComboBox>`n</StackPanel>"
|
|
||||||
# If it is a digit, type is button and button length is digits
|
"Combobox" {
|
||||||
} elseif ($appInfo.Type -match "^[\d\.]+$") {
|
$blockXml += $precal_indent_m1 +
|
||||||
$blockXml += "<Button Name=`"$($appInfo.Name)`" Content=`"$($appInfo.Content)`" HorizontalAlignment = `"Left`" Width=`"$($appInfo.Type)`" Margin=`"5`" Padding=`"20,5`" />`n"
|
"<StackPanel Orientation=""Horizontal"" Margin=""0,5,0,0"">" + "`r`n"
|
||||||
# else it is a checkbox
|
$blockXml += $precal_indent + "<Label Content=""$($appInfo.Content)"" HorizontalAlignment=""Left""" + " " +
|
||||||
} else {
|
"VerticalAlignment=""Center"" FontSize=""{FontSize}""/>" + "`r`n"
|
||||||
$checkedStatus = If ($null -eq $appInfo.Checked) {""} Else {"IsChecked=`"$($appInfo.Checked)`" "}
|
$blockXml += $precal_indent +
|
||||||
if ($null -eq $appInfo.Link)
|
"<ComboBox Name=""$($appInfo.Name)"" Height=""32"" Width=""186"" HorizontalAlignment=""Left""" + " " +
|
||||||
{
|
"VerticalAlignment=""Center"" Margin=""5,5"" FontSize=""{FontSize}"">" + "`r`n"
|
||||||
$blockXml += "<CheckBox Name=`"$($appInfo.Name)`" Content=`"$($appInfo.Content)`" $($checkedStatus)Margin=`"5,0`" ToolTip=`"$($appInfo.Description)`"/>`n"
|
|
||||||
|
$addfirst="IsSelected=""True"""
|
||||||
|
foreach ($comboitem in ($appInfo.ComboItems -split " ")) {
|
||||||
|
$blockXml += $precal_indent_p1 +
|
||||||
|
"<ComboBoxItem $addfirst Content=""$comboitem"" FontSize=""{FontSize}""/>" + "`r`n"
|
||||||
|
$addfirst=""
|
||||||
|
}
|
||||||
|
|
||||||
|
$blockXml += $precal_indent_p1 + "</ComboBox>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent + "</StackPanel>" + "`r`n"
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
"Button" {
|
||||||
$blockXml += "<StackPanel Orientation=""Horizontal"">`n<CheckBox Name=""$($appInfo.Name)"" Content=""$($appInfo.Content)"" $($checkedStatus)ToolTip=""$($appInfo.Description)"" Margin=""0,0,2,0""/><TextBlock Name=""$($appInfo.Name)Link"" Style=""{StaticResource HoverTextBlockStyle}"" Text=""(?)"" ToolTip=""$($appInfo.Link)"" />`n</StackPanel>`n"
|
if ($appInfo.ButtonWidth -ne $null) {
|
||||||
|
$ButtonWidthStr = "Width=""$($appInfo.ButtonWidth)"""
|
||||||
|
}
|
||||||
|
$blockXml += $precal_indent +
|
||||||
|
"<Button Name=""$($appInfo.Name)"" Content=""$($appInfo.Content)""" + " " +
|
||||||
|
"HorizontalAlignment=""Left"" Margin=""5"" Padding=""20,5"" $($ButtonWidthStr)/>" + "`r`n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# else it is a checkbox
|
||||||
|
default {
|
||||||
|
$checkedStatus = If ($appInfo.Checked -eq $null) {""} Else {" IsChecked=""$($appInfo.Checked)"""}
|
||||||
|
if ($appInfo.Link -eq $null) {
|
||||||
|
$blockXml += $precal_indent +
|
||||||
|
"<CheckBox Name=""$($appInfo.Name)"" Content=""$($appInfo.Content)""$($checkedStatus) Margin=""5,0""" + " " +
|
||||||
|
"ToolTip=""$($appInfo.Description)""/>" + "`r`n"
|
||||||
|
} else {
|
||||||
|
$blockXml += $precal_indent +
|
||||||
|
"<StackPanel Orientation=""Horizontal"">" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_p1 +
|
||||||
|
"<CheckBox Name=""$($appInfo.Name)"" Content=""$($appInfo.Content)""$($checkedStatus)" + " " +
|
||||||
|
"ToolTip=""$($appInfo.Description)"" Margin=""0,0,2,0""/>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent_p1 +
|
||||||
|
"<TextBlock Name=""$($appInfo.Name)Link"" Style=""{StaticResource HoverTextBlockStyle}"" Text=""(?)""" + " " +
|
||||||
|
"ToolTip=""$($appInfo.Link)""/>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent +
|
||||||
|
"</StackPanel>" + "`r`n"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$blockXml +="`n</StackPanel>`n</Border>`n"
|
|
||||||
|
$blockXml += $precal_indent_p1 + "</StackPanel>" + "`r`n"
|
||||||
|
$blockXml += $precal_indent + "</Border>" + "`r`n"
|
||||||
}
|
}
|
||||||
return ($blockXml)
|
return ($blockXml)
|
||||||
}
|
}
|
||||||
|
27
functions/private/Get-WPFObjectName.ps1
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
function Get-WPFObjectName {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
This is a helper function that generates an objectname with the prefix WPF that can be used as a Powershell Variable after compilation.
|
||||||
|
To achieve this, all characters that are not a-z, A-Z or 0-9 are simply removed from the name.
|
||||||
|
.PARAMETER type
|
||||||
|
The type of object for which the name should be generated. (e.g. Label, Button, CheckBox...)
|
||||||
|
.PARAMETER name
|
||||||
|
The name or description to be used for the object. (invalid characters are removed)
|
||||||
|
.OUTPUTS
|
||||||
|
A string that can be used as a object/variable name in powershell.
|
||||||
|
For example: WPFLabelMicrosoftTools
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Get-WPFObjectName -type Label -name "Microsoft Tools"
|
||||||
|
#>
|
||||||
|
|
||||||
|
param( [Parameter(Mandatory=$true)]
|
||||||
|
$type,
|
||||||
|
$name
|
||||||
|
)
|
||||||
|
|
||||||
|
$Output = $("WPF"+$type+$name) -replace '[^a-zA-Z0-9]', ''
|
||||||
|
|
||||||
|
return $Output
|
||||||
|
|
||||||
|
}
|
@ -5,9 +5,6 @@ Function Get-WinUtilCheckBoxes {
|
|||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Finds all checkboxes that are checked on the specific tab and inputs them into a script.
|
Finds all checkboxes that are checked on the specific tab and inputs them into a script.
|
||||||
|
|
||||||
.PARAMETER Group
|
|
||||||
The group of checkboxes to check
|
|
||||||
|
|
||||||
.PARAMETER unCheck
|
.PARAMETER unCheck
|
||||||
Whether to uncheck the checkboxes that are checked. Defaults to true
|
Whether to uncheck the checkboxes that are checked. Defaults to true
|
||||||
|
|
||||||
@ -32,23 +29,33 @@ Function Get-WinUtilCheckBoxes {
|
|||||||
|
|
||||||
$CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] }
|
$CheckBoxes = $sync.GetEnumerator() | Where-Object { $_.Value -is [System.Windows.Controls.CheckBox] }
|
||||||
|
|
||||||
|
# First check and add WPFTweaksRestorePoint if checked
|
||||||
|
$RestorePoint = $CheckBoxes | Where-Object { $_.Key -eq 'WPFTweaksRestorePoint' -and $_.Value.IsChecked -eq $true }
|
||||||
|
if ($RestorePoint) {
|
||||||
|
$Output["WPFTweaks"] = @('WPFTweaksRestorePoint')
|
||||||
|
Write-Debug "Adding WPFTweaksRestorePoint as first in WPFTweaks"
|
||||||
|
|
||||||
|
if ($unCheck) {
|
||||||
|
$RestorePoint.Value.IsChecked = $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($CheckBox in $CheckBoxes) {
|
foreach ($CheckBox in $CheckBoxes) {
|
||||||
|
if ($CheckBox.Key -eq 'WPFTweaksRestorePoint') { continue } # Skip since it's already handled
|
||||||
|
|
||||||
$group = if ($CheckBox.Key.StartsWith("WPFInstall")) { "Install" }
|
$group = if ($CheckBox.Key.StartsWith("WPFInstall")) { "Install" }
|
||||||
elseif ($CheckBox.Key.StartsWith("WPFTweaks")) { "WPFTweaks" }
|
elseif ($CheckBox.Key.StartsWith("WPFTweaks")) { "WPFTweaks" }
|
||||||
elseif ($CheckBox.Key.StartsWith("WPFFeature")) { "WPFFeature" }
|
elseif ($CheckBox.Key.StartsWith("WPFFeature")) { "WPFFeature" }
|
||||||
|
|
||||||
if ($group) {
|
if ($group) {
|
||||||
if ($CheckBox.Value.IsChecked -eq $true) {
|
if ($CheckBox.Value.IsChecked -eq $true) {
|
||||||
$feature = switch ($group) {
|
$feature = switch ($group) {
|
||||||
"Install" {
|
"Install" {
|
||||||
# Get the winget value
|
# Get the winget value
|
||||||
$wingetValue = $sync.configs.applications.$($CheckBox.Name).winget
|
[PsCustomObject]@{
|
||||||
|
winget="$($sync.configs.applications.$($CheckBox.Name).winget)";
|
||||||
if (-not [string]::IsNullOrWhiteSpace($wingetValue) -and $wingetValue -ne "na") {
|
choco="$($sync.configs.applications.$($CheckBox.Name).choco)";
|
||||||
$wingetValue -split ";"
|
|
||||||
} else {
|
|
||||||
$sync.configs.applications.$($CheckBox.Name).choco
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
default {
|
default {
|
||||||
$CheckBox.Name
|
$CheckBox.Name
|
||||||
@ -66,12 +73,11 @@ Function Get-WinUtilCheckBoxes {
|
|||||||
Write-Debug "Adding: $($feature) under: $($group)"
|
Write-Debug "Adding: $($feature) under: $($group)"
|
||||||
$Output[$group] += $feature
|
$Output[$group] += $feature
|
||||||
|
|
||||||
if ($uncheck -eq $true) {
|
if ($unCheck) {
|
||||||
$CheckBox.Value.IsChecked = $false
|
$CheckBox.Value.IsChecked = $false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $Output
|
return $Output
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ Function Get-WinUtilToggleStatus {
|
|||||||
else{
|
else{
|
||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($ToggleSwitch -eq "WPFToggleShowExt"){
|
if($ToggleSwitch -eq "WPFToggleShowExt"){
|
||||||
$hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt
|
$hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt
|
||||||
if($hideextvalue -eq 0){
|
if($hideextvalue -eq 0){
|
||||||
@ -58,7 +58,16 @@ Function Get-WinUtilToggleStatus {
|
|||||||
else{
|
else{
|
||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($ToggleSwitch -eq "WPFToggleSnapWindow"){
|
||||||
|
$hidesnap = (Get-ItemProperty -path 'HKCU:\Control Panel\Desktop').WindowArrangementActive
|
||||||
|
if($hidesnap -eq 0){
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
if($ToggleSwitch -eq "WPFToggleSnapFlyout"){
|
if($ToggleSwitch -eq "WPFToggleSnapFlyout"){
|
||||||
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout
|
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout
|
||||||
if($hidesnap -eq 0){
|
if($hidesnap -eq 0){
|
||||||
@ -67,7 +76,16 @@ Function Get-WinUtilToggleStatus {
|
|||||||
else{
|
else{
|
||||||
return $true
|
return $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($ToggleSwitch -eq "WPFToggleSnapSuggestion"){
|
||||||
|
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').SnapAssist
|
||||||
|
if($hidesnap -eq 0){
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
if($ToggleSwitch -eq "WPFToggleMouseAcceleration"){
|
if($ToggleSwitch -eq "WPFToggleMouseAcceleration"){
|
||||||
$MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed
|
$MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed
|
||||||
$MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1
|
$MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1
|
||||||
@ -80,6 +98,15 @@ Function Get-WinUtilToggleStatus {
|
|||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($ToggleSwitch -eq "WPFToggleTaskbarSearch"){
|
||||||
|
$SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode
|
||||||
|
if($SearchButton -eq 0){
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($ToggleSwitch -eq "WPFToggleStickyKeys") {
|
if ($ToggleSwitch -eq "WPFToggleStickyKeys") {
|
||||||
$StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags
|
$StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags
|
||||||
if($StickyKeys -eq 58){
|
if($StickyKeys -eq 58){
|
||||||
@ -89,4 +116,42 @@ Function Get-WinUtilToggleStatus {
|
|||||||
return $true
|
return $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if ($ToggleSwitch -eq "WPFToggleTaskView") {
|
||||||
|
$TaskView = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').ShowTaskViewButton
|
||||||
|
if($TaskView -eq 0){
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ToggleSwitch -eq "WPFToggleHiddenFiles") {
|
||||||
|
$HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden
|
||||||
|
if($HiddenFiles -eq 0){
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ToggleSwitch -eq "WPFToggleTaskbarWidgets") {
|
||||||
|
$TaskbarWidgets = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskBarDa
|
||||||
|
if($TaskbarWidgets -eq 0) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($ToggleSwitch -eq "WPFToggleTaskbarAlignment") {
|
||||||
|
$TaskbarAlignment = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskbarAl
|
||||||
|
if($TaskbarAlignment -eq 0) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,9 +11,7 @@ function Get-WinUtilVariables {
|
|||||||
[Parameter()]
|
[Parameter()]
|
||||||
[string[]]$Type
|
[string[]]$Type
|
||||||
)
|
)
|
||||||
|
$keys = ($sync.keys).where{ $_ -like "WPF*" }
|
||||||
$keys = $sync.keys | Where-Object { $_ -like "WPF*" }
|
|
||||||
|
|
||||||
if ($Type) {
|
if ($Type) {
|
||||||
$output = $keys | ForEach-Object {
|
$output = $keys | ForEach-Object {
|
||||||
Try {
|
Try {
|
||||||
|
27
functions/private/Get-WinUtilWingetLatest.ps1
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
function Get-WinUtilWingetLatest {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Uses GitHub API to check for the latest release of Winget.
|
||||||
|
.DESCRIPTION
|
||||||
|
This function grabs the latest version of Winget and returns the download path to Install-WinUtilWinget for installation.
|
||||||
|
#>
|
||||||
|
# Invoke-WebRequest is notoriously slow when the byte progress is displayed. The following lines disable the progress bar and reset them at the end of the function
|
||||||
|
$PreviousProgressPreference = $ProgressPreference
|
||||||
|
$ProgressPreference = "silentlyContinue"
|
||||||
|
Try{
|
||||||
|
# Grabs the latest release of Winget from the Github API for the install process.
|
||||||
|
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/Winget-cli/releases/latest" -Method Get -ErrorAction Stop
|
||||||
|
$latestVersion = $response.tag_name #Stores version number of latest release.
|
||||||
|
$licenseWingetUrl = $response.assets.browser_download_url | Where-Object {$_ -like "*License1.xml"} #Index value for License file.
|
||||||
|
Write-Host "Latest Version:`t$($latestVersion)`n"
|
||||||
|
Write-Host "Downloading..."
|
||||||
|
$assetUrl = $response.assets.browser_download_url | Where-Object {$_ -like "*Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle"}
|
||||||
|
Invoke-WebRequest -Uri $licenseWingetUrl -OutFile $ENV:TEMP\License1.xml
|
||||||
|
# The only pain is that the msixbundle for winget-cli is 246MB. In some situations this can take a bit, with slower connections.
|
||||||
|
Invoke-WebRequest -Uri $assetUrl -OutFile $ENV:TEMP\Microsoft.DesktopAppInstaller.msixbundle
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
throw [WingetFailedInstall]::new('Failed to get latest Winget release and license')
|
||||||
|
}
|
||||||
|
$ProgressPreference = $PreviousProgressPreference
|
||||||
|
}
|
29
functions/private/Get-WinUtilWingetPrerequisites.ps1
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
function Get-WinUtilWingetPrerequisites {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Downloads the Winget Prereqs.
|
||||||
|
.DESCRIPTION
|
||||||
|
Downloads Prereqs for Winget. Version numbers are coded as variables and can be updated as uncommonly as Microsoft updates the prereqs.
|
||||||
|
#>
|
||||||
|
|
||||||
|
# I don't know of a way to detect the prereqs automatically, so if someone has a better way of defining these, that would be great.
|
||||||
|
# Microsoft.VCLibs version rarely changes, but for future compatibility I made it a variable.
|
||||||
|
$versionVCLibs = "14.00"
|
||||||
|
$fileVCLibs = "https://aka.ms/Microsoft.VCLibs.x64.${versionVCLibs}.Desktop.appx"
|
||||||
|
# Write-Host "$fileVCLibs"
|
||||||
|
# Microsoft.UI.Xaml version changed recently, so I made the version numbers variables.
|
||||||
|
$versionUIXamlMinor = "2.8"
|
||||||
|
$versionUIXamlPatch = "2.8.6"
|
||||||
|
$fileUIXaml = "https://github.com/microsoft/microsoft-ui-xaml/releases/download/v${versionUIXamlPatch}/Microsoft.UI.Xaml.${versionUIXamlMinor}.x64.appx"
|
||||||
|
# Write-Host "$fileUIXaml"
|
||||||
|
|
||||||
|
Try{
|
||||||
|
Write-Host "Downloading Microsoft.VCLibs Dependency..."
|
||||||
|
Invoke-WebRequest -Uri $fileVCLibs -OutFile $ENV:TEMP\Microsoft.VCLibs.x64.Desktop.appx
|
||||||
|
Write-Host "Downloading Microsoft.UI.Xaml Dependency...`n"
|
||||||
|
Invoke-WebRequest -Uri $fileUIXaml -OutFile $ENV:TEMP\Microsoft.UI.Xaml.x64.appx
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
throw [WingetFailedInstall]::new('Failed to install prerequsites')
|
||||||
|
}
|
||||||
|
}
|
@ -10,20 +10,19 @@ function Install-WinUtilChoco {
|
|||||||
try {
|
try {
|
||||||
Write-Host "Checking if Chocolatey is Installed..."
|
Write-Host "Checking if Chocolatey is Installed..."
|
||||||
|
|
||||||
if((Get-Command -Name choco -ErrorAction Ignore)) {
|
if((Test-WinUtilPackageManager -choco) -eq "installed") {
|
||||||
Write-Host "Chocolatey Already Installed"
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "Seems Chocolatey is not installed, installing now"
|
Write-Host "Seems Chocolatey is not installed, installing now."
|
||||||
Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) -ErrorAction Stop
|
Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) -ErrorAction Stop
|
||||||
powershell choco feature enable -n allowGlobalConfirmation
|
powershell choco feature enable -n allowGlobalConfirmation
|
||||||
|
|
||||||
}
|
}
|
||||||
Catch {
|
Catch {
|
||||||
Write-Host "==========================================="
|
Write-Host "===========================================" -Foregroundcolor Red
|
||||||
Write-Host "-- Chocolatey failed to install ---"
|
Write-Host "-- Chocolatey failed to install ---" -Foregroundcolor Red
|
||||||
Write-Host "==========================================="
|
Write-Host "===========================================" -Foregroundcolor Red
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
102
functions/private/Install-WinUtilProgramChoco.ps1
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
function Install-WinUtilProgramChoco {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Manages the provided programs using Chocolatey
|
||||||
|
|
||||||
|
.PARAMETER ProgramsToInstall
|
||||||
|
A list of programs to manage
|
||||||
|
|
||||||
|
.PARAMETER manage
|
||||||
|
The action to perform on the programs, can be either 'Installing' or 'Uninstalling'
|
||||||
|
|
||||||
|
.NOTES
|
||||||
|
The triple quotes are required any time you need a " in a normal script block.
|
||||||
|
#>
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory, Position=0)]
|
||||||
|
[PsCustomObject]$ProgramsToInstall,
|
||||||
|
|
||||||
|
[Parameter(Position=1)]
|
||||||
|
[String]$manage = "Installing"
|
||||||
|
)
|
||||||
|
|
||||||
|
$x = 0
|
||||||
|
$count = $ProgramsToInstall.Count
|
||||||
|
|
||||||
|
# This check isn't really necessary, as there's a couple of checks before this Private Function gets called, but just to make sure ;)
|
||||||
|
if($count -le 0) {
|
||||||
|
throw "Private Function 'Install-WinUtilProgramChoco' expected Parameter 'ProgramsToInstall' to be of size 1 or greater, instead got $count,`nPlease double check your code and re-compile WinUtil."
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0
|
||||||
|
Write-Host "==========================================="
|
||||||
|
Write-Host "-- Configuring Chocolatey pacakages ---"
|
||||||
|
Write-Host "==========================================="
|
||||||
|
Foreach ($Program in $ProgramsToInstall){
|
||||||
|
Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.choco) $($x + 1) of $count" -PercentComplete $($x/$count*100)
|
||||||
|
if($manage -eq "Installing"){
|
||||||
|
write-host "Starting install of $($Program.choco) with Chocolatey."
|
||||||
|
try{
|
||||||
|
$tryUpgrade = $false
|
||||||
|
$installOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
|
||||||
|
New-Item -ItemType File -Path $installOutputFilePath
|
||||||
|
$chocoInstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "install $($Program.choco) -y" -Wait -PassThru -RedirectStandardOutput $installOutputFilePath).ExitCode
|
||||||
|
if(($chocoInstallStatus -eq 0) -AND (Test-Path -Path $installOutputFilePath)) {
|
||||||
|
$keywordsFound = Get-Content -Path $installOutputFilePath | Where-Object {$_ -match "reinstall" -OR $_ -match "already installed"}
|
||||||
|
if ($keywordsFound) {
|
||||||
|
$tryUpgrade = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# TODO: Implement the Upgrade part using 'choco upgrade' command, this will make choco consistent with WinGet, as WinGet tries to Upgrade when you use the install command.
|
||||||
|
if ($tryUpgrade) {
|
||||||
|
throw "Automatic Upgrade for Choco isn't implemented yet, a feature to make it consistent with WinGet, the install command using choco simply failed because $($Program.choco) is already installed."
|
||||||
|
}
|
||||||
|
if(($chocoInstallStatus -eq 0) -AND ($tryUpgrade -eq $false)){
|
||||||
|
Write-Host "$($Program.choco) installed successfully using Chocolatey."
|
||||||
|
$X++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
Write-Host "Failed to install $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $installOutputFilePath)."
|
||||||
|
$X++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "Failed to install $($Program.choco) due to an error: $_"
|
||||||
|
$X++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($manage -eq "Uninstalling"){
|
||||||
|
write-host "Starting uninstall of $($Program.choco) with Chocolatey."
|
||||||
|
try{
|
||||||
|
$uninstallOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt"
|
||||||
|
New-Item -ItemType File -Path $uninstallOutputFilePath
|
||||||
|
$chocoUninstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "uninstall $($Program.choco) -y" -Wait -PassThru).ExitCode
|
||||||
|
if($chocoUninstallStatus -eq 0){
|
||||||
|
Write-Host "$($Program.choco) uninstalled successfully using Chocolatey."
|
||||||
|
$x++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
Write-Host "Failed to uninstall $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $uninstallOutputFilePath)."
|
||||||
|
$x++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "Failed to uninstall $($Program.choco) due to an error: $_"
|
||||||
|
$x++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
|
||||||
|
|
||||||
|
# Cleanup leftovers files
|
||||||
|
if(Test-Path -Path $installOutputFilePath){ Remove-Item -Path $installOutputFilePath }
|
||||||
|
if(Test-Path -Path $uninstallOutputFilePath){ Remove-Item -Path $uninstallOutputFilePath }
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
@ -1,44 +1,116 @@
|
|||||||
Function Install-WinUtilProgramWinget {
|
Function Install-WinUtilProgramWinget {
|
||||||
|
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Manages the provided programs using Winget
|
Manages the provided programs using Winget
|
||||||
|
|
||||||
.PARAMETER ProgramsToInstall
|
.PARAMETER ProgramsToInstall
|
||||||
A list of programs to manage
|
A list of programs to manage
|
||||||
|
|
||||||
.PARAMETER manage
|
.PARAMETER manage
|
||||||
The action to perform on the programs, can be either 'Installing' or 'Uninstalling'
|
The action to perform on the programs, can be either 'Installing' or 'Uninstalling'
|
||||||
|
|
||||||
.NOTES
|
.NOTES
|
||||||
The triple quotes are required any time you need a " in a normal script block.
|
The triple quotes are required any time you need a " in a normal script block.
|
||||||
|
The winget Return codes are documented here: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param(
|
param(
|
||||||
$ProgramsToInstall,
|
[Parameter(Mandatory, Position=0)]
|
||||||
$manage = "Installing"
|
[PsCustomObject]$ProgramsToInstall,
|
||||||
|
|
||||||
|
[Parameter(Position=1)]
|
||||||
|
[String]$manage = "Installing"
|
||||||
)
|
)
|
||||||
|
|
||||||
$x = 0
|
$count = $ProgramsToInstall.Count
|
||||||
$count = $($ProgramsToInstall -split ",").Count
|
|
||||||
|
|
||||||
Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0
|
Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0
|
||||||
|
Write-Host "==========================================="
|
||||||
Foreach ($Program in $($ProgramsToInstall -split ",")){
|
Write-Host "-- Configuring winget packages ---"
|
||||||
|
Write-Host "==========================================="
|
||||||
Write-Progress -Activity "$manage Applications" -Status "$manage $Program $($x + 1) of $count" -PercentComplete $($x/$count*100)
|
for ($i = 0; $i -lt $count; $i++) {
|
||||||
if($manage -eq "Installing"){
|
$Program = $ProgramsToInstall[$i]
|
||||||
Start-Process -FilePath winget -ArgumentList "install -e --accept-source-agreements --accept-package-agreements --scope=machine --silent $Program" -NoNewWindow -Wait
|
$failedPackages = @()
|
||||||
|
Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.winget) $($i + 1) of $count" -PercentComplete $((($i + 1)/$count) * 100)
|
||||||
|
if($manage -eq "Installing") {
|
||||||
|
# Install package via ID, if it fails try again with different scope and then with an unelevated prompt.
|
||||||
|
# Since Install-WinGetPackage might not be directly available, we use winget install command as a workaround.
|
||||||
|
# Winget, not all installers honor any of the following: System-wide, User Installs, or Unelevated Prompt OR Silent Install Mode.
|
||||||
|
# This is up to the individual package maintainers to enable these options. Aka. not as clean as Linux Package Managers.
|
||||||
|
Write-Host "Starting install of $($Program.winget) with winget."
|
||||||
|
try {
|
||||||
|
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
|
||||||
|
if($status -eq 0) {
|
||||||
|
Write-Host "$($Program.winget) installed successfully."
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ($status -eq -1978335189) {
|
||||||
|
Write-Host "$($Program.winget) No applicable update found"
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
Write-Host "Attempt with User scope"
|
||||||
|
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --scope user --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
|
||||||
|
if($status -eq 0) {
|
||||||
|
Write-Host "$($Program.winget) installed successfully with User scope."
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ($status -eq -1978335189) {
|
||||||
|
Write-Host "$($Program.winget) No applicable update found"
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
Write-Host "Attempt with User prompt"
|
||||||
|
$userChoice = [System.Windows.MessageBox]::Show("Do you want to attempt $($Program.winget) installation with specific user credentials? Select 'Yes' to proceed or 'No' to skip.", "User Credential Prompt", [System.Windows.MessageBoxButton]::YesNo)
|
||||||
|
if ($userChoice -eq 'Yes') {
|
||||||
|
$getcreds = Get-Credential
|
||||||
|
$process = Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Credential $getcreds -PassThru -NoNewWindow
|
||||||
|
Wait-Process -Id $process.Id
|
||||||
|
$status = $process.ExitCode
|
||||||
|
} else {
|
||||||
|
Write-Host "Skipping installation with specific user credentials."
|
||||||
|
}
|
||||||
|
if($status -eq 0) {
|
||||||
|
Write-Host "$($Program.winget) installed successfully with User prompt."
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ($status -eq -1978335189) {
|
||||||
|
Write-Host "$($Program.winget) No applicable update found"
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "Failed to install $($Program.winget). With winget"
|
||||||
|
$failedPackages += $Program
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if($manage -eq "Uninstalling"){
|
elseif($manage -eq "Uninstalling") {
|
||||||
Start-Process -FilePath winget -ArgumentList "uninstall -e --purge --force --silent $Program" -NoNewWindow -Wait
|
# Uninstall package via ID using winget directly.
|
||||||
|
try {
|
||||||
|
$status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode
|
||||||
|
if($status -ne 0) {
|
||||||
|
Write-Host "Failed to uninstall $($Program.winget)."
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
||||||
|
} else {
|
||||||
|
Write-Host "$($Program.winget) uninstalled successfully."
|
||||||
|
$failedPackages += $Program
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "Failed to uninstall $($Program.winget) due to an error: $_"
|
||||||
|
$failedPackages += $Program
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" })
|
||||||
|
}
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage"
|
||||||
}
|
}
|
||||||
|
|
||||||
$X++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
|
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
|
||||||
|
return $failedPackages;
|
||||||
}
|
}
|
||||||
|
@ -1,50 +1,68 @@
|
|||||||
function Get-LatestHash {
|
|
||||||
$shaUrl = ((Invoke-WebRequest $apiLatestUrl -UseBasicParsing | ConvertFrom-Json).assets | Where-Object { $_.name -match '^Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.txt$' }).browser_download_url
|
|
||||||
|
|
||||||
$shaFile = Join-Path -Path $tempFolder -ChildPath 'Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.txt'
|
|
||||||
$WebClient.DownloadFile($shaUrl, $shaFile)
|
|
||||||
|
|
||||||
Get-Content $shaFile
|
|
||||||
}
|
|
||||||
|
|
||||||
function Install-WinUtilWinget {
|
function Install-WinUtilWinget {
|
||||||
|
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Installs Winget if it is not already installed
|
Installs Winget if it is not already installed.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function will download the latest version of winget and install it. If winget is already installed, it will do nothing.
|
This function will download the latest version of Winget and install it. If Winget is already installed, it will do nothing.
|
||||||
#>
|
#>
|
||||||
Try{
|
$isWingetInstalled = Test-WinUtilPackageManager -winget
|
||||||
Write-Host "Checking if Winget is Installed..."
|
|
||||||
if (Test-WinUtilPackageManager -winget) {
|
Try {
|
||||||
# Checks if winget executable exists and if the Windows Version is 1809 or higher
|
if ($isWingetInstalled -eq "installed") {
|
||||||
Write-Host "Winget Already Installed"
|
Write-Host "`nWinget is already installed.`r" -ForegroundColor Green
|
||||||
return
|
return
|
||||||
|
} elseif ($isWingetInstalled -eq "outdated") {
|
||||||
|
Write-Host "`nWinget is Outdated. Continuing with install.`r" -ForegroundColor Yellow
|
||||||
|
} else {
|
||||||
|
Write-Host "`nWinget is not Installed. Continuing with install.`r" -ForegroundColor Red
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Gets the computer's information
|
# Gets the computer's information
|
||||||
if ($null -eq $sync.ComputerInfo){
|
if ($null -eq $sync.ComputerInfo){
|
||||||
$ComputerInfo = Get-ComputerInfo -ErrorAction Stop
|
$ComputerInfo = Get-ComputerInfo -ErrorAction Stop
|
||||||
}
|
} else {
|
||||||
Else {
|
|
||||||
$ComputerInfo = $sync.ComputerInfo
|
$ComputerInfo = $sync.ComputerInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($ComputerInfo.WindowsVersion) -lt "1809") {
|
if (($ComputerInfo.WindowsVersion) -lt "1809") {
|
||||||
# Checks if Windows Version is too old for winget
|
# Checks if Windows Version is too old for Winget
|
||||||
Write-Host "Winget is not supported on this version of Windows (Pre-1809)"
|
Write-Host "Winget is not supported on this version of Windows (Pre-1809)" -ForegroundColor Red
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "Running Alternative Installer and Direct Installing"
|
# Install Winget via GitHub method.
|
||||||
Start-Process -Verb runas -FilePath powershell.exe -ArgumentList "choco install winget"
|
# Used part of my own script with some modification: ruxunderscore/windows-initialization
|
||||||
|
Write-Host "Downloading Winget Prerequsites`n"
|
||||||
|
Get-WinUtilWingetPrerequisites
|
||||||
|
Write-Host "Downloading Winget and License File`r"
|
||||||
|
Get-WinUtilWingetLatest
|
||||||
|
Write-Host "Installing Winget w/ Prerequsites`r"
|
||||||
|
Add-AppxProvisionedPackage -Online -PackagePath $ENV:TEMP\Microsoft.DesktopAppInstaller.msixbundle -DependencyPackagePath $ENV:TEMP\Microsoft.VCLibs.x64.Desktop.appx, $ENV:TEMP\Microsoft.UI.Xaml.x64.appx -LicensePath $ENV:TEMP\License1.xml
|
||||||
|
Write-Host "Manually adding Winget Sources, from Winget CDN."
|
||||||
|
Add-AppxPackage -Path https://cdn.winget.microsoft.com/cache/source.msix #Seems some installs of Winget don't add the repo source, this should makes sure that it's installed every time.
|
||||||
|
Write-Host "Winget Installed" -ForegroundColor Green
|
||||||
|
Write-Host "Enabling NuGet and Module..."
|
||||||
|
Install-PackageProvider -Name NuGet -Force
|
||||||
|
Install-Module -Name Microsoft.WinGet.Client -Force
|
||||||
|
# Winget only needs a refresh of the environment variables to be used.
|
||||||
|
Write-Output "Refreshing Environment Variables...`n"
|
||||||
|
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
|
} Catch {
|
||||||
|
Write-Host "Failure detected while installing via GitHub method. Continuing with Chocolatey method as fallback." -ForegroundColor Red
|
||||||
|
# In case install fails via GitHub method.
|
||||||
|
Try {
|
||||||
|
# Install Choco if not already present
|
||||||
|
Install-WinUtilChoco
|
||||||
|
Start-Process -Verb runas -FilePath powershell.exe -ArgumentList "choco install winget-cli"
|
||||||
|
Write-Host "Winget Installed" -ForegroundColor Green
|
||||||
|
Write-Output "Refreshing Environment Variables...`n"
|
||||||
|
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
|
} Catch {
|
||||||
|
throw [WingetFailedInstall]::new('Failed to install!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Winget Installed"
|
}
|
||||||
}
|
|
||||||
Catch{
|
|
||||||
throw [WingetFailedInstall]::new('Failed to install')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,45 +1,24 @@
|
|||||||
function Invoke-MicroWin-Helper {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
checking unit tests
|
|
||||||
|
|
||||||
.PARAMETER Name
|
|
||||||
no parameters
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
placeholder
|
|
||||||
|
|
||||||
#>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function Test-CompatibleImage() {
|
function Test-CompatibleImage() {
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Checks the version of a Windows image and determines whether or not it is compatible depending on the Major property
|
Checks the version of a Windows image and determines whether or not it is compatible with a specific feature depending on a desired version
|
||||||
|
|
||||||
.PARAMETER imgVersion
|
.PARAMETER Name
|
||||||
The version of the Windows image
|
imgVersion - The version of the Windows image
|
||||||
|
desiredVersion - The version to compare the image version with
|
||||||
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param
|
param
|
||||||
(
|
(
|
||||||
[Parameter(Mandatory = $true)] [string] $imgVersion
|
[Parameter(Mandatory = $true, Position=0)] [string] $imgVersion,
|
||||||
|
[Parameter(Mandatory = $true, Position=1)] [Version] $desiredVersion
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$version = [Version]$imgVersion
|
$version = [Version]$imgVersion
|
||||||
if ($version.Major -ge 10)
|
return $version -ge $desiredVersion
|
||||||
{
|
|
||||||
return $True
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return $False
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
return $False
|
return $False
|
||||||
}
|
}
|
||||||
@ -59,82 +38,104 @@ function Remove-Features([switch] $dumpFeatures = $false, [switch] $keepDefender
|
|||||||
Remove-Features -keepDefender:$false
|
Remove-Features -keepDefender:$false
|
||||||
|
|
||||||
#>
|
#>
|
||||||
$appxlist = dism /English /image:$scratchDir /Get-Features | Select-String -Pattern "Feature Name : " -CaseSensitive -SimpleMatch
|
try
|
||||||
$appxlist = $appxlist -split "Feature Name : " | Where-Object {$_}
|
|
||||||
if ($dumpFeatures)
|
|
||||||
{
|
{
|
||||||
$appxlist > allfeaturesdump.txt
|
$featlist = (Get-WindowsOptionalFeature -Path $scratchDir).FeatureName
|
||||||
|
if ($dumpFeatures)
|
||||||
|
{
|
||||||
|
$featlist > allfeaturesdump.txt
|
||||||
|
}
|
||||||
|
|
||||||
|
$featlist = $featlist | Where-Object {
|
||||||
|
$_ -NotLike "*Printing*" -AND
|
||||||
|
$_ -NotLike "*TelnetClient*" -AND
|
||||||
|
$_ -NotLike "*PowerShell*" -AND
|
||||||
|
$_ -NotLike "*NetFx*" -AND
|
||||||
|
$_ -NotLike "*Media*" -AND
|
||||||
|
$_ -NotLike "*NFS*"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($keepDefender) { $featlist = $featlist | Where-Object { $_ -NotLike "*Defender*" }}
|
||||||
|
|
||||||
|
foreach($feature in $featlist)
|
||||||
|
{
|
||||||
|
$status = "Removing feature $feature"
|
||||||
|
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
|
||||||
|
Write-Debug "Removing feature $feature"
|
||||||
|
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $feature -Remove -ErrorAction SilentlyContinue -NoRestart
|
||||||
|
}
|
||||||
|
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
|
||||||
|
Write-Host "You can re-enable the disabled features at any time, using either Windows Update or the SxS folder in <installation media>\Sources."
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
$appxlist = $appxlist | Where-Object {
|
|
||||||
$_ -NotLike "*Printing*" -AND
|
|
||||||
$_ -NotLike "*TelnetClient*" -AND
|
|
||||||
$_ -NotLike "*PowerShell*" -AND
|
|
||||||
$_ -NotLike "*NetFx*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($keepDefender) { $appxlist = $appxlist | Where-Object { $_ -NotLike "*Defender*" }}
|
|
||||||
|
|
||||||
foreach($feature in $appxlist)
|
|
||||||
{
|
{
|
||||||
$status = "Removing feature $feature"
|
Write-Host "Unable to get information about the features. MicroWin processing will continue, but features will not be processed"
|
||||||
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$appxlist.Count*100)
|
|
||||||
Write-Debug "Removing feature $feature"
|
|
||||||
# dism /image:$scratchDir /Disable-Feature /FeatureName:$feature /Remove /NoRestart > $null
|
|
||||||
}
|
}
|
||||||
Write-Progress -Activity "Removing features" -Status "Ready" -Completed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Remove-Packages
|
function Remove-Packages
|
||||||
{
|
{
|
||||||
$appxlist = dism /English /Image:$scratchDir /Get-Packages | Select-String -Pattern "Package Identity : " -CaseSensitive -SimpleMatch
|
try
|
||||||
$appxlist = $appxlist -split "Package Identity : " | Where-Object {$_}
|
|
||||||
|
|
||||||
$appxlist = $appxlist | Where-Object {
|
|
||||||
$_ -NotLike "*ApplicationModel*" -AND
|
|
||||||
$_ -NotLike "*indows-Client-LanguagePack*" -AND
|
|
||||||
$_ -NotLike "*LanguageFeatures-Basic*" -AND
|
|
||||||
$_ -NotLike "*Package_for_ServicingStack*" -AND
|
|
||||||
$_ -NotLike "*.NET*" -AND
|
|
||||||
$_ -NotLike "*Store*" -AND
|
|
||||||
$_ -NotLike "*VCLibs*" -AND
|
|
||||||
$_ -NotLike "*AAD.BrokerPlugin",
|
|
||||||
$_ -NotLike "*LockApp*" -AND
|
|
||||||
$_ -NotLike "*Notepad*" -AND
|
|
||||||
$_ -NotLike "*immersivecontrolpanel*" -AND
|
|
||||||
$_ -NotLike "*ContentDeliveryManager*" -AND
|
|
||||||
$_ -NotLike "*PinningConfirMationDialog*" -AND
|
|
||||||
$_ -NotLike "*SecHealthUI*" -AND
|
|
||||||
$_ -NotLike "*SecureAssessmentBrowser*" -AND
|
|
||||||
$_ -NotLike "*PrintDialog*" -AND
|
|
||||||
$_ -NotLike "*AssignedAccessLockApp*" -AND
|
|
||||||
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
|
|
||||||
$_ -NotLike "*Apprep.ChxApp*" -AND
|
|
||||||
$_ -NotLike "*CBS*" -AND
|
|
||||||
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
|
|
||||||
$_ -NotLike "*PeopleExperienceHost*" -AND
|
|
||||||
$_ -NotLike "*ParentalControls*" -AND
|
|
||||||
$_ -NotLike "*Win32WebViewHost*" -AND
|
|
||||||
$_ -NotLike "*InputApp*" -AND
|
|
||||||
$_ -NotLike "*AccountsControl*" -AND
|
|
||||||
$_ -NotLike "*AsyncTextService*" -AND
|
|
||||||
$_ -NotLike "*CapturePicker*" -AND
|
|
||||||
$_ -NotLike "*CredDialogHost*" -AND
|
|
||||||
$_ -NotLike "*BioEnrollMent*" -AND
|
|
||||||
$_ -NotLike "*ShellExperienceHost*" -AND
|
|
||||||
$_ -NotLike "*DesktopAppInstaller*" -AND
|
|
||||||
$_ -NotLike "*WebMediaExtensions*" -AND
|
|
||||||
$_ -NotLike "*WMIC*" -AND
|
|
||||||
$_ -NotLike "*UI.XaML*"
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($appx in $appxlist)
|
|
||||||
{
|
{
|
||||||
$status = "Removing $appx"
|
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
|
||||||
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$appxlist.Count*100)
|
|
||||||
dism /English /image:$scratchDir /Remove-Package /PackageName:$appx /NoRestart
|
$pkglist = $pkglist | Where-Object {
|
||||||
|
$_ -NotLike "*ApplicationModel*" -AND
|
||||||
|
$_ -NotLike "*indows-Client-LanguagePack*" -AND
|
||||||
|
$_ -NotLike "*LanguageFeatures-Basic*" -AND
|
||||||
|
$_ -NotLike "*Package_for_ServicingStack*" -AND
|
||||||
|
$_ -NotLike "*.NET*" -AND
|
||||||
|
$_ -NotLike "*Store*" -AND
|
||||||
|
$_ -NotLike "*VCLibs*" -AND
|
||||||
|
$_ -NotLike "*AAD.BrokerPlugin",
|
||||||
|
$_ -NotLike "*LockApp*" -AND
|
||||||
|
$_ -NotLike "*Notepad*" -AND
|
||||||
|
$_ -NotLike "*immersivecontrolpanel*" -AND
|
||||||
|
$_ -NotLike "*ContentDeliveryManager*" -AND
|
||||||
|
$_ -NotLike "*PinningConfirMationDialog*" -AND
|
||||||
|
$_ -NotLike "*SecHealthUI*" -AND
|
||||||
|
$_ -NotLike "*SecureAssessmentBrowser*" -AND
|
||||||
|
$_ -NotLike "*PrintDialog*" -AND
|
||||||
|
$_ -NotLike "*AssignedAccessLockApp*" -AND
|
||||||
|
$_ -NotLike "*OOBENetworkConnectionFlow*" -AND
|
||||||
|
$_ -NotLike "*Apprep.ChxApp*" -AND
|
||||||
|
$_ -NotLike "*CBS*" -AND
|
||||||
|
$_ -NotLike "*OOBENetworkCaptivePortal*" -AND
|
||||||
|
$_ -NotLike "*PeopleExperienceHost*" -AND
|
||||||
|
$_ -NotLike "*ParentalControls*" -AND
|
||||||
|
$_ -NotLike "*Win32WebViewHost*" -AND
|
||||||
|
$_ -NotLike "*InputApp*" -AND
|
||||||
|
$_ -NotLike "*AccountsControl*" -AND
|
||||||
|
$_ -NotLike "*AsyncTextService*" -AND
|
||||||
|
$_ -NotLike "*CapturePicker*" -AND
|
||||||
|
$_ -NotLike "*CredDialogHost*" -AND
|
||||||
|
$_ -NotLike "*BioEnrollMent*" -AND
|
||||||
|
$_ -NotLike "*ShellExperienceHost*" -AND
|
||||||
|
$_ -NotLike "*DesktopAppInstaller*" -AND
|
||||||
|
$_ -NotLike "*WebMediaExtensions*" -AND
|
||||||
|
$_ -NotLike "*WMIC*" -AND
|
||||||
|
$_ -NotLike "*UI.XaML*"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($pkg in $pkglist)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$status = "Removing $pkg"
|
||||||
|
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
|
||||||
|
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
# This can happen if the package that is being removed is a permanent one, like FodMetadata
|
||||||
|
Write-Host "Could not remove OS package $($pkg)"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-Host "Unable to get information about the packages. MicroWin processing will continue, but packages will not be processed"
|
||||||
}
|
}
|
||||||
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
|
function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
|
||||||
@ -161,9 +162,9 @@ function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
|
|||||||
$_.PackageName -NotLike "*Notepad*" -and
|
$_.PackageName -NotLike "*Notepad*" -and
|
||||||
$_.PackageName -NotLike "*Printing*" -and
|
$_.PackageName -NotLike "*Printing*" -and
|
||||||
$_.PackageName -NotLike "*Wifi*" -and
|
$_.PackageName -NotLike "*Wifi*" -and
|
||||||
$_.PackageName -NotLike "*Foundation*"
|
$_.PackageName -NotLike "*Foundation*"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($?)
|
if ($?)
|
||||||
{
|
{
|
||||||
if ($keepSecurity) { $appxProvisionedPackages = $appxProvisionedPackages | Where-Object { $_.PackageName -NotLike "*SecHealthUI*" }}
|
if ($keepSecurity) { $appxProvisionedPackages = $appxProvisionedPackages | Where-Object { $_.PackageName -NotLike "*SecHealthUI*" }}
|
||||||
@ -172,7 +173,13 @@ function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
|
|||||||
{
|
{
|
||||||
$status = "Removing Provisioned $($appx.PackageName)"
|
$status = "Removing Provisioned $($appx.PackageName)"
|
||||||
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
|
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
|
||||||
dism /English /image:$scratchDir /Remove-ProvisionedAppxPackage /PackageName:$($appx.PackageName) /NoRestart
|
try {
|
||||||
|
Remove-AppxProvisionedPackage -Path $scratchDir -PackageName $appx.PackageName -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "Application $($appx.PackageName) could not be removed"
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
|
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
|
||||||
}
|
}
|
||||||
@ -200,7 +207,7 @@ function Copy-ToUSB([string] $fileToCopy)
|
|||||||
Write-Progress -Activity "Copying File" -Status "Progress" -PercentComplete $completed -CurrentOperation ("{0:N2} MB / {1:N2} MB" -f ($_.BytesTransferred / 1MB), ($totalSize / 1MB))
|
Write-Progress -Activity "Copying File" -Status "Progress" -PercentComplete $completed -CurrentOperation ("{0:N2} MB / {1:N2} MB" -f ($_.BytesTransferred / 1MB), ($totalSize / 1MB))
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "File copied to Ventoy drive $($volume.DriveLette)"
|
Write-Host "File copied to Ventoy drive $($volume.DriveLetter)"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,13 +231,13 @@ function Remove-FileOrDirectory([string] $pathToDelete, [string] $mask = "", [sw
|
|||||||
# Remove-Item -Path $directoryPath -Recurse -Force
|
# Remove-Item -Path $directoryPath -Recurse -Force
|
||||||
|
|
||||||
# # Grant full control to BUILTIN\Administrators using icacls
|
# # Grant full control to BUILTIN\Administrators using icacls
|
||||||
# $directoryPath = "$($scratchDir)\Windows\System32\WebThreatDefSvc"
|
# $directoryPath = "$($scratchDir)\Windows\System32\WebThreatDefSvc"
|
||||||
# takeown /a /r /d $yesNo[0] /f "$($directoryPath)" > $null
|
# takeown /a /r /d $yesNo[0] /f "$($directoryPath)" > $null
|
||||||
# icacls "$($directoryPath)" /q /c /t /reset > $null
|
# icacls "$($directoryPath)" /q /c /t /reset > $null
|
||||||
# icacls $directoryPath /setowner "*S-1-5-32-544"
|
# icacls $directoryPath /setowner "*S-1-5-32-544"
|
||||||
# icacls $directoryPath /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
# icacls $directoryPath /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
||||||
# Remove-Item -Path $directoryPath -Recurse -Force
|
# Remove-Item -Path $directoryPath -Recurse -Force
|
||||||
|
|
||||||
$itemsToDelete = [System.Collections.ArrayList]::new()
|
$itemsToDelete = [System.Collections.ArrayList]::new()
|
||||||
|
|
||||||
if ($mask -eq "")
|
if ($mask -eq "")
|
||||||
@ -238,19 +245,19 @@ function Remove-FileOrDirectory([string] $pathToDelete, [string] $mask = "", [sw
|
|||||||
Write-Debug "Adding $($pathToDelete) to array."
|
Write-Debug "Adding $($pathToDelete) to array."
|
||||||
[void]$itemsToDelete.Add($pathToDelete)
|
[void]$itemsToDelete.Add($pathToDelete)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
|
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
|
||||||
if ($Directory) { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory }
|
if ($Directory) { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory }
|
||||||
else { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse }
|
else { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse }
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($itemToDelete in $itemsToDelete)
|
foreach($itemToDelete in $itemsToDelete)
|
||||||
{
|
{
|
||||||
$status = "Deleteing $($itemToDelete)"
|
$status = "Deleting $($itemToDelete)"
|
||||||
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ($counter++/$itemsToDelete.Count*100)
|
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ($counter++/$itemsToDelete.Count*100)
|
||||||
|
|
||||||
if (Test-Path -Path "$($itemToDelete)" -PathType Container)
|
if (Test-Path -Path "$($itemToDelete)" -PathType Container)
|
||||||
{
|
{
|
||||||
$status = "Deleting directory: $($itemToDelete)"
|
$status = "Deleting directory: $($itemToDelete)"
|
||||||
|
|
||||||
@ -321,7 +328,7 @@ function New-Unattend {
|
|||||||
<unattend xmlns="urn:schemas-microsoft-com:unattend"
|
<unattend xmlns="urn:schemas-microsoft-com:unattend"
|
||||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
|
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<#REPLACEME#>
|
||||||
<settings pass="auditUser">
|
<settings pass="auditUser">
|
||||||
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<RunSynchronous>
|
<RunSynchronous>
|
||||||
@ -362,7 +369,27 @@ function New-Unattend {
|
|||||||
</settings>
|
</settings>
|
||||||
</unattend>
|
</unattend>
|
||||||
'@
|
'@
|
||||||
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force
|
$specPass = @'
|
||||||
|
<settings pass="specialize">
|
||||||
|
<component name="Microsoft-Windows-SQMApi" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<CEIPEnabled>0</CEIPEnabled>
|
||||||
|
</component>
|
||||||
|
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<ConfigureChatAutoInstall>false</ConfigureChatAutoInstall>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
'@
|
||||||
|
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,22000,1))) -eq $false)
|
||||||
|
{
|
||||||
|
# Replace the placeholder text with an empty string to make it valid for Windows 10 Setup
|
||||||
|
$unattend = $unattend.Replace("<#REPLACEME#>", "").Trim()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# Replace the placeholder text with the Specialize pass
|
||||||
|
$unattend = $unattend.Replace("<#REPLACEME#>", $specPass).Trim()
|
||||||
|
}
|
||||||
|
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8
|
||||||
}
|
}
|
||||||
|
|
||||||
function New-CheckInstall {
|
function New-CheckInstall {
|
||||||
@ -450,16 +477,16 @@ function New-FirstRun {
|
|||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$RegistryPath,
|
[string]$RegistryPath,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$ValueName
|
[string]$ValueName
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if the registry path exists
|
# Check if the registry path exists
|
||||||
if (Test-Path -Path $RegistryPath)
|
if (Test-Path -Path $RegistryPath)
|
||||||
{
|
{
|
||||||
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
|
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
# Check if the registry value exists
|
# Check if the registry value exists
|
||||||
if ($registryValue)
|
if ($registryValue)
|
||||||
{
|
{
|
||||||
@ -477,7 +504,7 @@ function New-FirstRun {
|
|||||||
Write-Host "Registry path '$RegistryPath' not found."
|
Write-Host "Registry path '$RegistryPath' not found."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Stop-UnnecessaryServices
|
function Stop-UnnecessaryServices
|
||||||
{
|
{
|
||||||
$servicesToExclude = @(
|
$servicesToExclude = @(
|
||||||
@ -543,8 +570,8 @@ function New-FirstRun {
|
|||||||
"vm3dservice",
|
"vm3dservice",
|
||||||
"webthreatdefusersvc_dc2a4",
|
"webthreatdefusersvc_dc2a4",
|
||||||
"wscsvc"
|
"wscsvc"
|
||||||
)
|
)
|
||||||
|
|
||||||
$runningServices = Get-Service | Where-Object { $servicesToExclude -notcontains $_.Name }
|
$runningServices = Get-Service | Where-Object { $servicesToExclude -notcontains $_.Name }
|
||||||
foreach($service in $runningServices)
|
foreach($service in $runningServices)
|
||||||
{
|
{
|
||||||
@ -553,28 +580,28 @@ function New-FirstRun {
|
|||||||
"Stopping service $($service.Name)" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
|
"Stopping service $($service.Name)" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"FirstStartup has worked" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
|
"FirstStartup has worked" | Out-File -FilePath c:\windows\LogFirstRun.txt -Append -NoClobber
|
||||||
|
|
||||||
$Theme = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
|
$Theme = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
|
||||||
Set-ItemProperty -Path $Theme -Name AppsUseLightTheme -Value 1
|
Set-ItemProperty -Path $Theme -Name AppsUseLightTheme -Value 1
|
||||||
Set-ItemProperty -Path $Theme -Name SystemUsesLightTheme -Value 1
|
Set-ItemProperty -Path $Theme -Name SystemUsesLightTheme -Value 1
|
||||||
|
|
||||||
# figure this out later how to set updates to security only
|
# figure this out later how to set updates to security only
|
||||||
#Import-Module -Name PSWindowsUpdate;
|
#Import-Module -Name PSWindowsUpdate;
|
||||||
#Stop-Service -Name wuauserv
|
#Stop-Service -Name wuauserv
|
||||||
#Set-WUSettings -MicrosoftUpdateEnabled -AutoUpdateOption 'Never'
|
#Set-WUSettings -MicrosoftUpdateEnabled -AutoUpdateOption 'Never'
|
||||||
#Start-Service -Name wuauserv
|
#Start-Service -Name wuauserv
|
||||||
|
|
||||||
Stop-UnnecessaryServices
|
Stop-UnnecessaryServices
|
||||||
|
|
||||||
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
|
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
|
||||||
# Delete all files on the Taskbar
|
# Delete all files on the Taskbar
|
||||||
Get-ChildItem -Path $taskbarPath -File | Remove-Item -Force
|
Get-ChildItem -Path $taskbarPath -File | Remove-Item -Force
|
||||||
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesRemovedChanges"
|
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesRemovedChanges"
|
||||||
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesChanges"
|
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "FavoritesChanges"
|
||||||
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "Favorites"
|
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "Favorites"
|
||||||
|
|
||||||
# Stop-Process -Name explorer -Force
|
# Stop-Process -Name explorer -Force
|
||||||
|
|
||||||
$process = Get-Process -Name "explorer"
|
$process = Get-Process -Name "explorer"
|
||||||
@ -586,9 +613,9 @@ function New-FirstRun {
|
|||||||
# Delete Edge Icon from the desktop
|
# Delete Edge Icon from the desktop
|
||||||
$edgeShortcutFiles = Get-ChildItem -Path $desktopPath -Filter "*Edge*.lnk"
|
$edgeShortcutFiles = Get-ChildItem -Path $desktopPath -Filter "*Edge*.lnk"
|
||||||
# Check if Edge shortcuts exist on the desktop
|
# Check if Edge shortcuts exist on the desktop
|
||||||
if ($edgeShortcutFiles)
|
if ($edgeShortcutFiles)
|
||||||
{
|
{
|
||||||
foreach ($shortcutFile in $edgeShortcutFiles)
|
foreach ($shortcutFile in $edgeShortcutFiles)
|
||||||
{
|
{
|
||||||
# Remove each Edge shortcut
|
# Remove each Edge shortcut
|
||||||
Remove-Item -Path $shortcutFile.FullName -Force
|
Remove-Item -Path $shortcutFile.FullName -Force
|
||||||
@ -608,7 +635,7 @@ function New-FirstRun {
|
|||||||
$shortcutPath = Join-Path $desktopPath 'winutil.lnk'
|
$shortcutPath = Join-Path $desktopPath 'winutil.lnk'
|
||||||
# Create a shell object
|
# Create a shell object
|
||||||
$shell = New-Object -ComObject WScript.Shell
|
$shell = New-Object -ComObject WScript.Shell
|
||||||
|
|
||||||
# Create a shortcut object
|
# Create a shortcut object
|
||||||
$shortcut = $shell.CreateShortcut($shortcutPath)
|
$shortcut = $shell.CreateShortcut($shortcutPath)
|
||||||
|
|
||||||
@ -616,19 +643,26 @@ function New-FirstRun {
|
|||||||
{
|
{
|
||||||
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
|
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Set properties of the shortcut
|
# Set properties of the shortcut
|
||||||
$shortcut.TargetPath = "powershell.exe"
|
$shortcut.TargetPath = "powershell.exe"
|
||||||
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
|
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
|
||||||
# Save the shortcut
|
# Save the shortcut
|
||||||
$shortcut.Save()
|
$shortcut.Save()
|
||||||
|
|
||||||
|
# Make the shortcut have 'Run as administrator' property on
|
||||||
|
$bytes = [System.IO.File]::ReadAllBytes($shortcutPath)
|
||||||
|
# Set byte value at position 0x15 in hex, or 21 in decimal, from the value 0x00 to 0x20 in hex
|
||||||
|
$bytes[0x15] = $bytes[0x15] -bor 0x20
|
||||||
|
[System.IO.File]::WriteAllBytes($shortcutPath, $bytes)
|
||||||
|
|
||||||
Write-Host "Shortcut created at: $shortcutPath"
|
Write-Host "Shortcut created at: $shortcutPath"
|
||||||
#
|
#
|
||||||
# Done create WinUtil shortcut on the desktop
|
# Done create WinUtil shortcut on the desktop
|
||||||
# ************************************************
|
# ************************************************
|
||||||
|
|
||||||
Start-Process explorer
|
Start-Process explorer
|
||||||
|
|
||||||
'@
|
'@
|
||||||
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
|
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,9 @@ Function Invoke-WinUtilCurrentSystem {
|
|||||||
$values += $False
|
$values += $False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$values += $False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@ function Invoke-WinUtilFeatureInstall {
|
|||||||
$CheckBox
|
$CheckBox
|
||||||
)
|
)
|
||||||
|
|
||||||
|
$x = 0
|
||||||
|
|
||||||
$CheckBox | ForEach-Object {
|
$CheckBox | ForEach-Object {
|
||||||
if($sync.configs.feature.$psitem.feature){
|
if($sync.configs.feature.$psitem.feature){
|
||||||
Foreach( $feature in $sync.configs.feature.$psitem.feature ){
|
Foreach( $feature in $sync.configs.feature.$psitem.feature ){
|
||||||
@ -20,9 +22,11 @@ function Invoke-WinUtilFeatureInstall {
|
|||||||
Catch{
|
Catch{
|
||||||
if ($psitem.Exception.Message -like "*requires elevation*"){
|
if ($psitem.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" })
|
||||||
}
|
}
|
||||||
|
|
||||||
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 $psitem.Exception.StackTrace
|
||||||
}
|
}
|
||||||
@ -40,14 +44,18 @@ function Invoke-WinUtilFeatureInstall {
|
|||||||
Catch{
|
Catch{
|
||||||
if ($psitem.Exception.Message -like "*requires elevation*"){
|
if ($psitem.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" })
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ 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 $psitem.Exception.StackTrace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$X++
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$CheckBox.Count) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
functions/private/Invoke-WinUtilGPU.ps1
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
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)*",
|
||||||
|
"*UHD*"
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($gpu in $gpuInfo) {
|
||||||
|
foreach ($gpuPattern in $lowPowerGPUs){
|
||||||
|
if ($gpu.Name -like $gpuPattern) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $true
|
||||||
|
}
|
34
functions/private/Invoke-WinUtilHiddenFiles.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-WinUtilHiddenFiles {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Enable/Disable Hidden Files
|
||||||
|
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to enable or disable Hidden Files
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Enabling Hidden Files"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Disabling Hidden Files"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
|
||||||
|
Set-ItemProperty -Path $Path -Name Hidden -Value $value
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
@ -15,13 +15,13 @@ Function Invoke-WinUtilMouseAcceleration {
|
|||||||
$MouseSpeed = 1
|
$MouseSpeed = 1
|
||||||
$MouseThreshold1 = 6
|
$MouseThreshold1 = 6
|
||||||
$MouseThreshold2 = 10
|
$MouseThreshold2 = 10
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host "Disabling Mouse Acceleration"
|
Write-Host "Disabling Mouse Acceleration"
|
||||||
$MouseSpeed = 0
|
$MouseSpeed = 0
|
||||||
$MouseThreshold1 = 0
|
$MouseThreshold1 = 0
|
||||||
$MouseThreshold2 = 0
|
$MouseThreshold2 = 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$Path = "HKCU:\Control Panel\Mouse"
|
$Path = "HKCU:\Control Panel\Mouse"
|
||||||
|
@ -15,7 +15,8 @@ function Invoke-WinUtilNumLock {
|
|||||||
Write-Host "Disabling Numlock on startup"
|
Write-Host "Disabling Numlock on startup"
|
||||||
$value = 0
|
$value = 0
|
||||||
}
|
}
|
||||||
$Path = "HKCU:\Control Panel\Keyboard"
|
New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS
|
||||||
|
$Path = "HKU:\.Default\Control Panel\Keyboard"
|
||||||
Set-ItemProperty -Path $Path -Name InitialKeyboardIndicators -Value $value
|
Set-ItemProperty -Path $Path -Name InitialKeyboardIndicators -Value $value
|
||||||
}
|
}
|
||||||
Catch [System.Security.SecurityException] {
|
Catch [System.Security.SecurityException] {
|
||||||
|
34
functions/private/Invoke-WinUtilSnapSuggestion.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-WinUtilSnapSuggestion {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Disables/Enables Snap Assist Suggestions on startup
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to enable or disable Snap Assist Suggestions on startup
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Enabling Snap Assist Suggestion On startup"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Disabling Snap Assist Suggestion On startup"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
# taskkill.exe /F /IM "explorer.exe"
|
||||||
|
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
|
||||||
|
taskkill.exe /F /IM "explorer.exe"
|
||||||
|
Set-ItemProperty -Path $Path -Name SnapAssist -Value $value
|
||||||
|
Start-Process "explorer.exe"
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
31
functions/private/Invoke-WinUtilSnapWindow.ps1
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
function Invoke-WinUtilSnapWindow {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Disables/Enables Snapping Windows on startup
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to enable or disable Snapping Windows on startup
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Enabling Snap Windows On startup | Relogin Required"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Disabling Snap Windows On startup | Relogin Required"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
$Path = "HKCU:\Control Panel\Desktop"
|
||||||
|
Set-ItemProperty -Path $Path -Name WindowArrangementActive -Value $value
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
45
functions/private/Invoke-WinUtilSponsors.ps1
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
Function Invoke-WinUtilSponsors {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Lists Sponsors from ChrisTitusTech
|
||||||
|
.DESCRIPTION
|
||||||
|
Lists Sponsors from ChrisTitusTech
|
||||||
|
.EXAMPLE
|
||||||
|
Invoke-WinUtilSponsors
|
||||||
|
.NOTES
|
||||||
|
This function is used to list sponsors from ChrisTitusTech
|
||||||
|
#>
|
||||||
|
try {
|
||||||
|
# Define the URL and headers
|
||||||
|
$url = "https://github.com/sponsors/ChrisTitusTech"
|
||||||
|
$headers = @{
|
||||||
|
"User-Agent" = "Chrome/58.0.3029.110"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch the webpage content
|
||||||
|
try {
|
||||||
|
$html = Invoke-RestMethod -Uri $url -Headers $headers
|
||||||
|
} catch {
|
||||||
|
Write-Output $_.Exception.Message
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use regex to extract the content between "Current sponsors" and "Past sponsors"
|
||||||
|
$currentSponsorsPattern = '(?s)(?<=Current sponsors).*?(?=Past sponsors)'
|
||||||
|
$currentSponsorsHtml = [regex]::Match($html, $currentSponsorsPattern).Value
|
||||||
|
|
||||||
|
# Use regex to extract the sponsor usernames from the alt attributes in the "Current Sponsors" section
|
||||||
|
$sponsorPattern = '(?<=alt="@)[^"]+'
|
||||||
|
$sponsors = [regex]::Matches($currentSponsorsHtml, $sponsorPattern) | ForEach-Object { $_.Value }
|
||||||
|
|
||||||
|
# Exclude "ChrisTitusTech" from the sponsors
|
||||||
|
$sponsors = $sponsors | Where-Object { $_ -ne "ChrisTitusTech" }
|
||||||
|
|
||||||
|
# Return the sponsors
|
||||||
|
return $sponsors
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred while fetching or processing the sponsors: $_"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@ Function Invoke-WinUtilStickyKeys {
|
|||||||
Indicates whether to enable or disable Sticky Keys on startup
|
Indicates whether to enable or disable Sticky Keys on startup
|
||||||
#>
|
#>
|
||||||
Param($Enabled)
|
Param($Enabled)
|
||||||
Try {
|
Try {
|
||||||
if ($Enabled -eq $false){
|
if ($Enabled -eq $false){
|
||||||
Write-Host "Enabling Sticky Keys On startup"
|
Write-Host "Enabling Sticky Keys On startup"
|
||||||
$value = 510
|
$value = 510
|
34
functions/private/Invoke-WinUtilTaskView.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-WinUtilTaskView {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Enable/Disable Task View
|
||||||
|
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to enable or disable Task View
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Enabling Task View"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Disabling Task View"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
|
||||||
|
Set-ItemProperty -Path $Path -Name ShowTaskViewButton -Value $value
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
34
functions/private/Invoke-WinUtilTaskbarAlignment.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-WinUtilTaskbarAlignment {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Switches between Center & Left Taskbar Alignment
|
||||||
|
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to make Taskbar Alignment Center or Left
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Making Taskbar Alignment to the Center"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Making Taskbar Alignment to the Left"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
|
||||||
|
Set-ItemProperty -Path $Path -Name "TaskbarAl" -Value $value
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
34
functions/private/Invoke-WinUtilTaskbarSearch.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-WinUtilTaskbarSearch {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Enable/Disable Taskbar Search Button.
|
||||||
|
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to enable or disable Taskbar Search Button.
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Enabling Search Button"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Disabling Search Button"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search\"
|
||||||
|
Set-ItemProperty -Path $Path -Name SearchboxTaskbarMode -Value $value
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
34
functions/private/Invoke-WinUtilTaskbarWidgets.ps1
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-WinUtilTaskbarWidgets {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Enable/Disable Taskbar Widgets
|
||||||
|
|
||||||
|
.PARAMETER Enabled
|
||||||
|
Indicates whether to enable or disable Taskbar Widgets
|
||||||
|
|
||||||
|
#>
|
||||||
|
Param($Enabled)
|
||||||
|
Try{
|
||||||
|
if ($Enabled -eq $false){
|
||||||
|
Write-Host "Enabling Taskbar Widgets"
|
||||||
|
$value = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Disabling Taskbar Widgets"
|
||||||
|
$value = 0
|
||||||
|
}
|
||||||
|
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
|
||||||
|
Set-ItemProperty -Path $Path -Name TaskbarDa -Value $value
|
||||||
|
}
|
||||||
|
Catch [System.Security.SecurityException] {
|
||||||
|
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
|
||||||
|
}
|
||||||
|
Catch [System.Management.Automation.ItemNotFoundException] {
|
||||||
|
Write-Warning $psitem.Exception.ErrorRecord
|
||||||
|
}
|
||||||
|
Catch{
|
||||||
|
Write-Warning "Unable to set $Name due to unhandled exception"
|
||||||
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
|
}
|
||||||
|
}
|
@ -10,11 +10,15 @@ function Invoke-WinUtilTweaks {
|
|||||||
.PARAMETER undo
|
.PARAMETER undo
|
||||||
Indicates whether to undo the operation contained in the checkbox
|
Indicates whether to undo the operation contained in the checkbox
|
||||||
|
|
||||||
|
.PARAMETER KeepServiceStartup
|
||||||
|
Indicates whether to override the startup of a service with the one given from WinUtil,
|
||||||
|
or to keep the startup of said service, if it was changed by the user, or another program, from its default value.
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param(
|
param(
|
||||||
$CheckBox,
|
$CheckBox,
|
||||||
$undo = $false
|
$undo = $false,
|
||||||
|
$KeepServiceStartup = $true
|
||||||
)
|
)
|
||||||
|
|
||||||
Write-Debug "Tweaks: $($CheckBox)"
|
Write-Debug "Tweaks: $($CheckBox)"
|
||||||
@ -32,6 +36,7 @@ function Invoke-WinUtilTweaks {
|
|||||||
Registry = "Value"
|
Registry = "Value"
|
||||||
ScheduledTask = "State"
|
ScheduledTask = "State"
|
||||||
Service = "StartupType"
|
Service = "StartupType"
|
||||||
|
OriginalService = "OriginalType"
|
||||||
ScriptType = "InvokeScript"
|
ScriptType = "InvokeScript"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,9 +47,29 @@ function Invoke-WinUtilTweaks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($sync.configs.tweaks.$CheckBox.service){
|
if($sync.configs.tweaks.$CheckBox.service){
|
||||||
|
Write-Debug "KeepServiceStartup is $KeepServiceStartup"
|
||||||
$sync.configs.tweaks.$CheckBox.service | ForEach-Object {
|
$sync.configs.tweaks.$CheckBox.service | ForEach-Object {
|
||||||
Write-Debug "$($psitem.Name) and state is $($psitem.$($values.service))"
|
$changeservice = $true
|
||||||
Set-WinUtilService -Name $psitem.Name -StartupType $psitem.$($values.Service)
|
|
||||||
|
# The check for !($undo) is required, without it the script will throw an error for accessing unavailable memeber, which's the 'OriginalService' Property
|
||||||
|
if($KeepServiceStartup -AND !($undo)) {
|
||||||
|
try {
|
||||||
|
# Check if the service exists
|
||||||
|
$service = Get-Service -Name $psitem.Name -ErrorAction Stop
|
||||||
|
if(!($service.StartType.ToString() -eq $psitem.$($values.OriginalService))) {
|
||||||
|
Write-Debug "Service $($service.Name) was changed in the past to $($service.StartType.ToString()) from it's original type of $($psitem.$($values.OriginalService)), will not change it to $($psitem.$($values.service))"
|
||||||
|
$changeservice = $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch [System.ServiceProcess.ServiceNotFoundException] {
|
||||||
|
Write-Warning "Service $($psitem.Name) was not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($changeservice) {
|
||||||
|
Write-Debug "$($psitem.Name) and state is $($psitem.$($values.service))"
|
||||||
|
Set-WinUtilService -Name $psitem.Name -StartupType $psitem.$($values.Service)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($sync.configs.tweaks.$CheckBox.registry){
|
if($sync.configs.tweaks.$CheckBox.registry){
|
||||||
@ -70,4 +95,4 @@ function Invoke-WinUtilTweaks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ function Set-WinUtilDNS {
|
|||||||
}
|
}
|
||||||
Else{
|
Else{
|
||||||
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ("$($sync.configs.dns.$DNSProvider.Primary)", "$($sync.configs.dns.$DNSProvider.Secondary)")
|
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ("$($sync.configs.dns.$DNSProvider.Primary)", "$($sync.configs.dns.$DNSProvider.Secondary)")
|
||||||
|
Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ("$($sync.configs.dns.$DNSProvider.Primary6)", "$($sync.configs.dns.$DNSProvider.Secondary6)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,4 +32,4 @@ function Set-WinUtilDNS {
|
|||||||
Write-Warning "Unable to set DNS Provider due to an unhandled exception"
|
Write-Warning "Unable to set DNS Provider due to an unhandled exception"
|
||||||
Write-Warning $psitem.Exception.StackTrace
|
Write-Warning $psitem.Exception.StackTrace
|
||||||
}
|
}
|
||||||
}
|
}
|
86
functions/private/Set-WinUtilTaskbarItem.ps1
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
function Set-WinUtilTaskbaritem {
|
||||||
|
<#
|
||||||
|
|
||||||
|
.SYNOPSIS
|
||||||
|
Modifies the Taskbaritem of the WPF Form
|
||||||
|
|
||||||
|
.PARAMETER value
|
||||||
|
Value can be between 0 and 1, 0 being no progress done yet and 1 being fully completed
|
||||||
|
Value does not affect item without setting the state to 'Normal', 'Error' or 'Paused'
|
||||||
|
Set-WinUtilTaskbaritem -value 0.5
|
||||||
|
|
||||||
|
.PARAMETER state
|
||||||
|
State can be 'None' > No progress, 'Indeterminate' > inf. loading gray, 'Normal' > Gray, 'Error' > Red, 'Paused' > Yellow
|
||||||
|
no value needed:
|
||||||
|
- Set-WinUtilTaskbaritem -state "None"
|
||||||
|
- Set-WinUtilTaskbaritem -state "Indeterminate"
|
||||||
|
value needed:
|
||||||
|
- Set-WinUtilTaskbaritem -state "Error"
|
||||||
|
- Set-WinUtilTaskbaritem -state "Normal"
|
||||||
|
- Set-WinUtilTaskbaritem -state "Paused"
|
||||||
|
|
||||||
|
.PARAMETER overlay
|
||||||
|
Overlay icon to display on the taskbar item, there are the presets 'None', 'logo' and 'checkmark' or you can specify a path/link to an image file.
|
||||||
|
CTT logo preset:
|
||||||
|
- Set-WinUtilTaskbaritem -overlay "logo"
|
||||||
|
Checkmark preset:
|
||||||
|
- Set-WinUtilTaskbaritem -overlay "checkmark"
|
||||||
|
Warning preset:
|
||||||
|
- Set-WinUtilTaskbaritem -overlay "warning"
|
||||||
|
No overlay:
|
||||||
|
- Set-WinUtilTaskbaritem -overlay "None"
|
||||||
|
Custom icon (needs to be supported by WPF):
|
||||||
|
- Set-WinUtilTaskbaritem -overlay "C:\path\to\icon.png"
|
||||||
|
|
||||||
|
.PARAMETER description
|
||||||
|
Description to display on the taskbar item preview
|
||||||
|
Set-WinUtilTaskbaritem -description "This is a description"
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[string]$state,
|
||||||
|
[double]$value,
|
||||||
|
[string]$overlay,
|
||||||
|
[string]$description
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($value) {
|
||||||
|
$sync["Form"].taskbarItemInfo.ProgressValue = $value
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($state) {
|
||||||
|
switch ($state) {
|
||||||
|
'None' { $sync["Form"].taskbarItemInfo.ProgressState = "None" }
|
||||||
|
'Indeterminate' { $sync["Form"].taskbarItemInfo.ProgressState = "Indeterminate" }
|
||||||
|
'Normal' { $sync["Form"].taskbarItemInfo.ProgressState = "Normal" }
|
||||||
|
'Error' { $sync["Form"].taskbarItemInfo.ProgressState = "Error" }
|
||||||
|
'Paused' { $sync["Form"].taskbarItemInfo.ProgressState = "Paused" }
|
||||||
|
default { throw "[Set-WinUtilTaskbarItem] Invalid state" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($overlay) {
|
||||||
|
switch ($overlay) {
|
||||||
|
'logo' {
|
||||||
|
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\cttlogo.png"
|
||||||
|
}
|
||||||
|
'checkmark' {
|
||||||
|
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\checkmark.png"
|
||||||
|
}
|
||||||
|
'warning' {
|
||||||
|
$sync["Form"].taskbarItemInfo.Overlay = "$env:LOCALAPPDATA\winutil\warning.png"
|
||||||
|
}
|
||||||
|
'None' {
|
||||||
|
$sync["Form"].taskbarItemInfo.Overlay = $null
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
if (Test-Path $overlay) {
|
||||||
|
$sync["Form"].taskbarItemInfo.Overlay = $overlay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($description) {
|
||||||
|
$sync["Form"].taskbarItemInfo.Description = $description
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,10 @@ function Show-CustomDialog {
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Displays a custom dialog box with an image, heading, message, and an OK button.
|
Displays a custom dialog box with an image, heading, message, and an OK button.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background.
|
This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background.
|
||||||
|
|
||||||
.PARAMETER Message
|
.PARAMETER Message
|
||||||
The message to be displayed in the dialog box.
|
The message to be displayed in the dialog box.
|
||||||
|
|
||||||
@ -14,15 +14,31 @@ function Show-CustomDialog {
|
|||||||
|
|
||||||
.PARAMETER Height
|
.PARAMETER Height
|
||||||
The height of the custom dialog window.
|
The height of the custom dialog window.
|
||||||
|
|
||||||
|
.PARAMETER FontSize
|
||||||
|
The Font Size for text shown inside the custom dialog window.
|
||||||
|
|
||||||
|
.PARAMETER HeaderFontSize
|
||||||
|
The Font Size for the Header of the custom dialog window.
|
||||||
|
|
||||||
|
.PARAMETER IconSize
|
||||||
|
The Size to use for Icon inside the custom dialog window.
|
||||||
|
|
||||||
|
.PARAMETER EnableScroll
|
||||||
|
A flag indicating whether to enable scrolling if the content exceeds the window size.
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Show-CustomDialog -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200
|
Show-CustomDialog -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200
|
||||||
|
|
||||||
#>
|
#>
|
||||||
param(
|
param(
|
||||||
[string]$Message,
|
[string]$Message,
|
||||||
[int]$Width = 300,
|
[int]$Width = 300,
|
||||||
[int]$Height = 200
|
[int]$Height = 200,
|
||||||
|
[int]$FontSize = 10,
|
||||||
|
[int]$HeaderFontSize = 14,
|
||||||
|
[int]$IconSize = 25,
|
||||||
|
[bool]$EnableScroll = $false
|
||||||
)
|
)
|
||||||
|
|
||||||
Add-Type -AssemblyName PresentationFramework
|
Add-Type -AssemblyName PresentationFramework
|
||||||
@ -48,6 +64,7 @@ function Show-CustomDialog {
|
|||||||
$dialog.Foreground = $foregroundColor
|
$dialog.Foreground = $foregroundColor
|
||||||
$dialog.Background = $backgroundColor
|
$dialog.Background = $backgroundColor
|
||||||
$dialog.FontFamily = $font
|
$dialog.FontFamily = $font
|
||||||
|
$dialog.FontSize = $FontSize
|
||||||
|
|
||||||
# Create a Border for the green edge with rounded corners
|
# Create a Border for the green edge with rounded corners
|
||||||
$border = New-Object Windows.Controls.Border
|
$border = New-Object Windows.Controls.Border
|
||||||
@ -99,7 +116,7 @@ function Show-CustomDialog {
|
|||||||
$grid.RowDefinitions.Add($row0)
|
$grid.RowDefinitions.Add($row0)
|
||||||
$grid.RowDefinitions.Add($row1)
|
$grid.RowDefinitions.Add($row1)
|
||||||
$grid.RowDefinitions.Add($row2)
|
$grid.RowDefinitions.Add($row2)
|
||||||
|
|
||||||
# Add StackPanel for horizontal layout with margins
|
# Add StackPanel for horizontal layout with margins
|
||||||
$stackPanel = New-Object Windows.Controls.StackPanel
|
$stackPanel = New-Object Windows.Controls.StackPanel
|
||||||
$stackPanel.Margin = New-Object Windows.Thickness(10) # Add margins around the stack panel
|
$stackPanel.Margin = New-Object Windows.Thickness(10) # Add margins around the stack panel
|
||||||
@ -111,9 +128,9 @@ function Show-CustomDialog {
|
|||||||
[Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index)
|
[Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index)
|
||||||
|
|
||||||
$viewbox = New-Object Windows.Controls.Viewbox
|
$viewbox = New-Object Windows.Controls.Viewbox
|
||||||
$viewbox.Width = 25
|
$viewbox.Width = $IconSize
|
||||||
$viewbox.Height = 25
|
$viewbox.Height = $IconSize
|
||||||
|
|
||||||
# Combine the paths into a single string
|
# Combine the paths into a single string
|
||||||
# $cttLogoPath = @"
|
# $cttLogoPath = @"
|
||||||
# M174 1094 c-4 -14 -4 -55 -2 -92 3 -57 9 -75 41 -122 41 -60 45 -75 22 -84 -25 -9 -17 -21 30 -44 l45 -22 0 -103 c0 -91 3 -109 26 -155 30 -60 65 -87 204 -157 l95 -48 110 58 c184 96 205 127 205 293 l0 108 45 22 c47 23 55 36 30 46 -22 8 -18 30 9 63 13 16 34 48 46 71 20 37 21 52 15 116 l-6 73 -69 -23 c-38 -12 -137 -59 -220 -103 -82 -45 -160 -81 -171 -81 -12 0 -47 15 -78 34 -85 51 -239 127 -309 151 l-62 22 -6 -23z m500 -689 c20 -8 36 -19 36 -24 0 -18 -53 -51 -80 -51 -28 0 -80 33 -80 51 0 10 55 38 76 39 6 0 28 -7 48 -15z
|
# M174 1094 c-4 -14 -4 -55 -2 -92 3 -57 9 -75 41 -122 41 -60 45 -75 22 -84 -25 -9 -17 -21 30 -44 l45 -22 0 -103 c0 -91 3 -109 26 -155 30 -60 65 -87 204 -157 l95 -48 110 58 c184 96 205 127 205 293 l0 108 45 22 c47 23 55 36 30 46 -22 8 -18 30 9 63 13 16 34 48 46 71 20 37 21 52 15 116 l-6 73 -69 -23 c-38 -12 -137 -59 -220 -103 -82 -45 -160 -81 -171 -81 -12 0 -47 15 -78 34 -85 51 -239 127 -309 151 l-62 22 -6 -23z m500 -689 c20 -8 36 -19 36 -24 0 -18 -53 -51 -80 -51 -28 0 -80 33 -80 51 0 10 55 38 76 39 6 0 28 -7 48 -15z
|
||||||
@ -159,7 +176,7 @@ $cttLogoPath = @"
|
|||||||
46.21,102.83 36.63,98.57 31.04,93.68
|
46.21,102.83 36.63,98.57 31.04,93.68
|
||||||
16.88,81.28 19.00,62.88 19.00,46.00 Z
|
16.88,81.28 19.00,62.88 19.00,46.00 Z
|
||||||
"@
|
"@
|
||||||
|
|
||||||
# Add SVG path
|
# Add SVG path
|
||||||
$svgPath = New-Object Windows.Shapes.Path
|
$svgPath = New-Object Windows.Shapes.Path
|
||||||
$svgPath.Data = [Windows.Media.Geometry]::Parse($cttLogoPath)
|
$svgPath.Data = [Windows.Media.Geometry]::Parse($cttLogoPath)
|
||||||
@ -167,31 +184,89 @@ $cttLogoPath = @"
|
|||||||
|
|
||||||
# Add SVG path to Viewbox
|
# Add SVG path to Viewbox
|
||||||
$viewbox.Child = $svgPath
|
$viewbox.Child = $svgPath
|
||||||
|
|
||||||
# Add SVG path to the stack panel
|
# Add SVG path to the stack panel
|
||||||
$stackPanel.Children.Add($viewbox)
|
$stackPanel.Children.Add($viewbox)
|
||||||
|
|
||||||
# Add "Winutil" text
|
# Add "Winutil" text
|
||||||
$winutilTextBlock = New-Object Windows.Controls.TextBlock
|
$winutilTextBlock = New-Object Windows.Controls.TextBlock
|
||||||
$winutilTextBlock.Text = "Winutil"
|
$winutilTextBlock.Text = "Winutil"
|
||||||
$winutilTextBlock.FontSize = 18 # Adjust font size as needed
|
$winutilTextBlock.FontSize = $HeaderFontSize
|
||||||
$winutilTextBlock.Foreground = $foregroundColor
|
$winutilTextBlock.Foreground = $foregroundColor
|
||||||
$winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 10, 5) # Add margins around the text block
|
$winutilTextBlock.Margin = New-Object Windows.Thickness(10, 5, 10, 5) # Add margins around the text block
|
||||||
$stackPanel.Children.Add($winutilTextBlock)
|
$stackPanel.Children.Add($winutilTextBlock)
|
||||||
|
|
||||||
# Add TextBlock for information with text wrapping and margins
|
# Add TextBlock for information with text wrapping and margins
|
||||||
$messageTextBlock = New-Object Windows.Controls.TextBlock
|
$messageTextBlock = New-Object Windows.Controls.TextBlock
|
||||||
$messageTextBlock.Text = $Message
|
|
||||||
$messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping
|
$messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping
|
||||||
$messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left
|
$messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left
|
||||||
$messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top
|
$messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top
|
||||||
$messageTextBlock.Margin = New-Object Windows.Thickness(10) # Add margins around the text block
|
$messageTextBlock.Margin = New-Object Windows.Thickness(10) # Add margins around the text block
|
||||||
$grid.Children.Add($messageTextBlock)
|
|
||||||
[Windows.Controls.Grid]::SetRow($messageTextBlock, 1) # Set the row to the second row (0-based index)
|
# Define the Regex to find hyperlinks formatted as HTML <a> tags
|
||||||
|
$regex = [regex]::new('<a href="([^"]+)">([^<]+)</a>')
|
||||||
|
$lastPos = 0
|
||||||
|
|
||||||
|
# Iterate through each match and add regular text and hyperlinks
|
||||||
|
foreach ($match in $regex.Matches($Message)) {
|
||||||
|
# Add the text before the hyperlink, if any
|
||||||
|
$textBefore = $Message.Substring($lastPos, $match.Index - $lastPos)
|
||||||
|
if ($textBefore.Length -gt 0) {
|
||||||
|
$messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($textBefore)))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create and add the hyperlink
|
||||||
|
$hyperlink = New-Object Windows.Documents.Hyperlink
|
||||||
|
$hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value)
|
||||||
|
$hyperlink.Inlines.Add($match.Groups[2].Value)
|
||||||
|
$hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline
|
||||||
|
$hyperlink.Foreground = $foregroundColor
|
||||||
|
$hyperlink.Add_Click({
|
||||||
|
param($sender, $args)
|
||||||
|
Start-Process $sender.NavigateUri.AbsoluteUri
|
||||||
|
})
|
||||||
|
$hyperlink.Add_MouseEnter({
|
||||||
|
param($sender, $args)
|
||||||
|
$sender.Foreground = [Windows.Media.Brushes]::LightGray
|
||||||
|
})
|
||||||
|
$hyperlink.Add_MouseLeave({
|
||||||
|
param($sender, $args)
|
||||||
|
$sender.Foreground = $foregroundColor
|
||||||
|
})
|
||||||
|
|
||||||
|
$messageTextBlock.Inlines.Add($hyperlink)
|
||||||
|
|
||||||
|
# Update the last position
|
||||||
|
$lastPos = $match.Index + $match.Length
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add any remaining text after the last hyperlink
|
||||||
|
if ($lastPos -lt $Message.Length) {
|
||||||
|
$textAfter = $Message.Substring($lastPos)
|
||||||
|
$messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($textAfter)))
|
||||||
|
}
|
||||||
|
|
||||||
|
# If no matches, add the entire message as a run
|
||||||
|
if ($regex.Matches($Message).Count -eq 0) {
|
||||||
|
$messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($Message)))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a ScrollViewer if EnableScroll is true
|
||||||
|
if ($EnableScroll) {
|
||||||
|
$scrollViewer = New-Object System.Windows.Controls.ScrollViewer
|
||||||
|
$scrollViewer.VerticalScrollBarVisibility = 'Auto'
|
||||||
|
$scrollViewer.HorizontalScrollBarVisibility = 'Disabled'
|
||||||
|
$scrollViewer.Content = $messageTextBlock
|
||||||
|
$grid.Children.Add($scrollViewer)
|
||||||
|
[Windows.Controls.Grid]::SetRow($scrollViewer, 1) # Set the row to the second row (0-based index)
|
||||||
|
} else {
|
||||||
|
$grid.Children.Add($messageTextBlock)
|
||||||
|
[Windows.Controls.Grid]::SetRow($messageTextBlock, 1) # Set the row to the second row (0-based index)
|
||||||
|
}
|
||||||
|
|
||||||
# Add OK button
|
# Add OK button
|
||||||
$okButton = New-Object Windows.Controls.Button
|
$okButton = New-Object Windows.Controls.Button
|
||||||
$okButton.Content = "OK"
|
$okButton.Content = "OK"
|
||||||
|
$okButton.FontSize = $FontSize
|
||||||
$okButton.Width = 80
|
$okButton.Width = 80
|
||||||
$okButton.Height = 30
|
$okButton.Height = 30
|
||||||
$okButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Center
|
$okButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Center
|
||||||
|
@ -17,37 +17,81 @@ function Test-WinUtilPackageManager {
|
|||||||
[System.Management.Automation.SwitchParameter]$choco
|
[System.Management.Automation.SwitchParameter]$choco
|
||||||
)
|
)
|
||||||
|
|
||||||
# Install Winget if not detected
|
$status = "not-installed"
|
||||||
$wingetExists = Get-Command -Name winget -ErrorAction SilentlyContinue
|
|
||||||
if ($wingetExists) {
|
|
||||||
$wingetVersion = [System.Version]::Parse((winget --version).Trim('v'))
|
|
||||||
$minimumWingetVersion = [System.Version]::new(1,2,10691) # Win 11 23H2 comes with bad winget v1.2.10691
|
|
||||||
$wingetOutdated = $wingetVersion -le $minimumWingetVersion
|
|
||||||
|
|
||||||
Write-Host "Winget v$wingetVersion"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$wingetExists -or $wingetOutdated) {
|
|
||||||
if (!$wingetExists) {
|
|
||||||
Write-Host "Winget not detected"
|
|
||||||
} else {
|
|
||||||
Write-Host "- Winget out-dated"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($winget) {
|
if ($winget) {
|
||||||
if ($wingetExists -and !$wingetOutdated) {
|
# Check if Winget is available while getting it's Version if it's available
|
||||||
Write-Host "- Winget up-to-date"
|
$wingetExists = $true
|
||||||
return $true
|
try {
|
||||||
|
$wingetVersionFull = winget --version
|
||||||
|
} catch [System.Management.Automation.CommandNotFoundException], [System.Management.Automation.ApplicationFailedException] {
|
||||||
|
Write-Warning "Winget was not found due to un-availablity reasons"
|
||||||
|
$wingetExists = $false
|
||||||
|
} catch {
|
||||||
|
Write-Warning "Winget was not found due to un-known reasons, The Stack Trace is:`n$($psitem.Exception.StackTrace)"
|
||||||
|
$wingetExists = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# If Winget is available, Parse it's Version and give proper information to Terminal Output.
|
||||||
|
# If it isn't available, the return of this funtion will be "not-installed", indicating that
|
||||||
|
# Winget isn't installed/available on The System.
|
||||||
|
if ($wingetExists) {
|
||||||
|
# Check if Preview Version
|
||||||
|
if ($wingetVersionFull.Contains("-preview")) {
|
||||||
|
$wingetVersion = $wingetVersionFull.Trim("-preview")
|
||||||
|
$wingetPreview = $true
|
||||||
|
} else {
|
||||||
|
$wingetVersion = $wingetVersionFull
|
||||||
|
$wingetPreview = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if Winget's Version is too old.
|
||||||
|
$wingetCurrentVersion = [System.Version]::Parse($wingetVersion.Trim('v'))
|
||||||
|
# Grabs the latest release of Winget from the Github API for version check process.
|
||||||
|
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/Winget-cli/releases/latest" -Method Get -ErrorAction Stop
|
||||||
|
$wingetLatestVersion = [System.Version]::Parse(($response.tag_name).Trim('v')) #Stores version number of latest release.
|
||||||
|
$wingetOutdated = $wingetCurrentVersion -lt $wingetLatestVersion
|
||||||
|
Write-Host "===========================================" -ForegroundColor Green
|
||||||
|
Write-Host "--- Winget is installed ---" -ForegroundColor Green
|
||||||
|
Write-Host "===========================================" -ForegroundColor Green
|
||||||
|
Write-Host "Version: $wingetVersionFull" -ForegroundColor White
|
||||||
|
|
||||||
|
if (!$wingetPreview) {
|
||||||
|
Write-Host " - Winget is a release version." -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " - Winget is a preview version. Unexpected problems may occur." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$wingetOutdated) {
|
||||||
|
Write-Host " - Winget is Up to Date" -ForegroundColor Green
|
||||||
|
$status = "installed"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host " - Winget is Out of Date" -ForegroundColor Red
|
||||||
|
$status = "outdated"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "===========================================" -ForegroundColor Red
|
||||||
|
Write-Host "--- Winget is not installed ---" -ForegroundColor Red
|
||||||
|
Write-Host "===========================================" -ForegroundColor Red
|
||||||
|
$status = "not-installed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($choco){
|
if ($choco) {
|
||||||
if ((Get-Command -Name choco -ErrorAction Ignore) -and ($chocoVersion = (Get-Item "$env:ChocolateyInstall\choco.exe" -ErrorAction Ignore).VersionInfo.ProductVersion)){
|
if ((Get-Command -Name choco -ErrorAction Ignore) -and ($chocoVersion = (Get-Item "$env:ChocolateyInstall\choco.exe" -ErrorAction Ignore).VersionInfo.ProductVersion)) {
|
||||||
Write-Host "Chocolatey v$chocoVersion"
|
Write-Host "===========================================" -ForegroundColor Green
|
||||||
return $true
|
Write-Host "--- Chocolatey is installed ---" -ForegroundColor Green
|
||||||
|
Write-Host "===========================================" -ForegroundColor Green
|
||||||
|
Write-Host "Version: v$chocoVersion" -ForegroundColor White
|
||||||
|
$status = "installed"
|
||||||
|
} else {
|
||||||
|
Write-Host "===========================================" -ForegroundColor Red
|
||||||
|
Write-Host "--- Chocolatey is not installed ---" -ForegroundColor Red
|
||||||
|
Write-Host "===========================================" -ForegroundColor Red
|
||||||
|
$status = "not-installed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $false
|
return $status
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ Function Update-WinUtilProgramWinget {
|
|||||||
$host.ui.RawUI.WindowTitle = """Winget Install"""
|
$host.ui.RawUI.WindowTitle = """Winget Install"""
|
||||||
|
|
||||||
Start-Transcript $ENV:TEMP\winget-update.log -Append
|
Start-Transcript $ENV:TEMP\winget-update.log -Append
|
||||||
winget upgrade --all
|
winget upgrade --all --accept-source-agreements --accept-package-agreements --scope=machine --silent
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@ function Invoke-ScratchDialog {
|
|||||||
|
|
||||||
.PARAMETER Button
|
.PARAMETER Button
|
||||||
#>
|
#>
|
||||||
$sync.WPFMicrowinISOScratchDir.IsChecked
|
$sync.WPFMicrowinISOScratchDir.IsChecked
|
||||||
|
|
||||||
|
|
||||||
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
|
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
|
||||||
$Dialog = New-Object System.Windows.Forms.FolderBrowserDialog
|
$Dialog = New-Object System.Windows.Forms.FolderBrowserDialog
|
||||||
$Dialog.SelectedPath = $sync.MicrowinScratchDirBox.Text
|
$Dialog.SelectedPath = $sync.MicrowinScratchDirBox.Text
|
||||||
$Dialog.ShowDialog()
|
$Dialog.ShowDialog()
|
||||||
$filePath = $Dialog.SelectedPath
|
$filePath = $Dialog.SelectedPath
|
||||||
Write-Host "No ISO is chosen+ $filePath"
|
Write-Host "No ISO is chosen+ $filePath"
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ function Invoke-ScratchDialog {
|
|||||||
Write-Host "No Folder had chosen"
|
Write-Host "No Folder had chosen"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$sync.MicrowinScratchDirBox.Text = Join-Path $filePath "\"
|
$sync.MicrowinScratchDirBox.Text = Join-Path $filePath "\"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@ function Invoke-WPFButton {
|
|||||||
"WPFinstall" {Invoke-WPFInstall}
|
"WPFinstall" {Invoke-WPFInstall}
|
||||||
"WPFuninstall" {Invoke-WPFUnInstall}
|
"WPFuninstall" {Invoke-WPFUnInstall}
|
||||||
"WPFInstallUpgrade" {Invoke-WPFInstallUpgrade}
|
"WPFInstallUpgrade" {Invoke-WPFInstallUpgrade}
|
||||||
"WPFdesktop" {Invoke-WPFPresets "Desktop"}
|
"WPFstandard" {Invoke-WPFPresets "Standard"}
|
||||||
"WPFlaptop" {Invoke-WPFPresets "laptop"}
|
"WPFminimal" {Invoke-WPFPresets "Minimal"}
|
||||||
"WPFminimal" {Invoke-WPFPresets "minimal"}
|
|
||||||
"WPFclear" {Invoke-WPFPresets -preset $null -imported $true}
|
"WPFclear" {Invoke-WPFPresets -preset $null -imported $true}
|
||||||
"WPFclearWinget" {Invoke-WPFPresets -preset $null -imported $true -CheckBox "WPFInstall"}
|
"WPFclearWinget" {Invoke-WPFPresets -preset $null -imported $true -CheckBox "WPFInstall"}
|
||||||
"WPFtweaksbutton" {Invoke-WPFtweaksbutton}
|
"WPFtweaksbutton" {Invoke-WPFtweaksbutton}
|
||||||
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enabled"}
|
"WPFOOSUbutton" {Invoke-WPFOOSU}
|
||||||
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disabled"}
|
"WPFAddUltPerf" {Invoke-WPFUltimatePerformance -State "Enable"}
|
||||||
|
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
|
||||||
"WPFundoall" {Invoke-WPFundoall}
|
"WPFundoall" {Invoke-WPFundoall}
|
||||||
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
|
"WPFFeatureInstall" {Invoke-WPFFeatureInstall}
|
||||||
"WPFPanelDISM" {Invoke-WPFPanelDISM}
|
"WPFPanelDISM" {Invoke-WPFPanelDISM}
|
||||||
|
@ -16,12 +16,18 @@ function Invoke-WPFFeatureInstall {
|
|||||||
|
|
||||||
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
|
Invoke-WPFRunspace -ArgumentList $Features -DebugPreference $DebugPreference -ScriptBlock {
|
||||||
param($Features, $DebugPreference)
|
param($Features, $DebugPreference)
|
||||||
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
|
if ($Features.count -eq 1){
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
||||||
|
} else {
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
||||||
|
}
|
||||||
|
|
||||||
Invoke-WinUtilFeatureInstall $Features
|
Invoke-WinUtilFeatureInstall $Features
|
||||||
|
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
|
||||||
|
|
||||||
Write-Host "==================================="
|
Write-Host "==================================="
|
||||||
Write-Host "--- Features are Installed ---"
|
Write-Host "--- Features are Installed ---"
|
||||||
Write-Host "--- A Reboot may be required ---"
|
Write-Host "--- A Reboot may be required ---"
|
||||||
|
@ -3,11 +3,12 @@ function Invoke-WPFFixesWinget {
|
|||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Fixes Winget by running choco install winget
|
Fixes Winget by running choco install winget
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
BravoNorris for the fantastic idea of a button to reinstall winget
|
BravoNorris for the fantastic idea of a button to reinstall winget
|
||||||
#>
|
#>
|
||||||
|
# Install Choco if not already present
|
||||||
|
Install-WinUtilChoco
|
||||||
Start-Process -FilePath "choco" -ArgumentList "install winget -y --force" -NoNewWindow -Wait
|
Start-Process -FilePath "choco" -ArgumentList "install winget -y --force" -NoNewWindow -Wait
|
||||||
|
|
||||||
}
|
}
|
@ -16,10 +16,7 @@ function Invoke-WPFGetInstalled {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(Get-Command -Name winget -ErrorAction SilentlyContinue) -and $checkbox -eq "winget"){
|
if(((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget"){
|
||||||
Write-Host "==========================================="
|
|
||||||
Write-Host "-- Winget is not installed ---"
|
|
||||||
Write-Host "==========================================="
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +24,7 @@ function Invoke-WPFGetInstalled {
|
|||||||
param($checkbox, $DebugPreference)
|
param($checkbox, $DebugPreference)
|
||||||
|
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" })
|
||||||
|
|
||||||
if($checkbox -eq "winget"){
|
if($checkbox -eq "winget"){
|
||||||
Write-Host "Getting Installed Programs..."
|
Write-Host "Getting Installed Programs..."
|
||||||
@ -45,5 +43,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" })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,38 +12,37 @@ function Invoke-WPFGetIso {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$sync.BusyMessage.Visibility="Visible"
|
$sync.BusyMessage.Visibility="Visible"
|
||||||
$sync.BusyText.Text="N Busy"
|
$sync.BusyText.Text="N Busy"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Write-Host " _ __ __ _ "
|
Write-Host " _ __ __ _ "
|
||||||
Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ "
|
Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ "
|
||||||
Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ "
|
Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ "
|
||||||
Write-Host "/ /\/\ \| || (__ | | | (_) | \ /\ / | || | | | "
|
Write-Host "/ /\/\ \| || (__ | | | (_) | \ /\ / | || | | | "
|
||||||
Write-Host "\/ \/|_| \___||_| \___/ \/ \/ |_||_| |_| "
|
Write-Host "\/ \/|_| \___||_| \___/ \/ \/ |_||_| |_| "
|
||||||
|
|
||||||
$oscdimgPath = Join-Path $env:TEMP 'oscdimg.exe'
|
$oscdimgPath = Join-Path $env:TEMP 'oscdimg.exe'
|
||||||
if( ! (Test-Path $oscdimgPath -PathType Leaf) ) {
|
|
||||||
$oscdimgPath = Join-Path '.\releases\' 'oscdimg.exe'
|
|
||||||
}
|
|
||||||
|
|
||||||
$oscdImgFound = [bool] (Get-Command -ErrorAction Ignore -Type Application oscdimg.exe) -or (Test-Path $oscdimgPath -PathType Leaf)
|
$oscdImgFound = [bool] (Get-Command -ErrorAction Ignore -Type Application oscdimg.exe) -or (Test-Path $oscdimgPath -PathType Leaf)
|
||||||
Write-Host "oscdimg.exe on system: $oscdImgFound"
|
Write-Host "oscdimg.exe on system: $oscdImgFound"
|
||||||
|
|
||||||
if (!$oscdImgFound)
|
if (!$oscdImgFound)
|
||||||
{
|
{
|
||||||
$downloadFromGitHub = $sync.WPFMicrowinDownloadFromGitHub.IsChecked
|
$downloadFromGitHub = $sync.WPFMicrowinDownloadFromGitHub.IsChecked
|
||||||
$sync.BusyMessage.Visibility="Hidden"
|
$sync.BusyMessage.Visibility="Hidden"
|
||||||
|
|
||||||
if (!$downloadFromGitHub)
|
if (!$downloadFromGitHub)
|
||||||
{
|
{
|
||||||
# only show the message to people who did check the box to download from github, if you check the box
|
# only show the message to people who did check the box to download from github, if you check the box
|
||||||
# you consent to downloading it, no need to show extra dialogs
|
# you consent to downloading it, no need to show extra dialogs
|
||||||
[System.Windows.MessageBox]::Show("oscdimge.exe is not found on the system, winutil will now attempt do download and install it using choco. This might take a long time.")
|
[System.Windows.MessageBox]::Show("oscdimge.exe is not found on the system, winutil will now attempt do download and install it using choco. This might take a long time.")
|
||||||
# the step below needs choco to download oscdimg
|
# the step below needs choco to download oscdimg
|
||||||
|
# Install Choco if not already present
|
||||||
|
Install-WinUtilChoco
|
||||||
$chocoFound = [bool] (Get-Command -ErrorAction Ignore -Type Application choco)
|
$chocoFound = [bool] (Get-Command -ErrorAction Ignore -Type Application choco)
|
||||||
Write-Host "choco on system: $chocoFound"
|
Write-Host "choco on system: $chocoFound"
|
||||||
if (!$chocoFound)
|
if (!$chocoFound)
|
||||||
{
|
{
|
||||||
[System.Windows.MessageBox]::Show("choco.exe is not found on the system, you need choco to download oscdimg.exe")
|
[System.Windows.MessageBox]::Show("choco.exe is not found on the system, you need choco to download oscdimg.exe")
|
||||||
return
|
return
|
||||||
@ -90,6 +89,32 @@ function Invoke-WPFGetIso {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||||
|
|
||||||
|
# Detect the file size of the ISO and compare it with the free space of the system drive
|
||||||
|
$isoSize = (Get-Item -Path $filePath).Length
|
||||||
|
Write-Debug "Size of ISO file: $($isoSize) bytes"
|
||||||
|
# Use this procedure to get the free space of the drive depending on where the user profile folder is stored.
|
||||||
|
# This is done to guarantee a dynamic solution, as the installation drive may be mounted to a letter different than C
|
||||||
|
$driveSpace = (Get-Volume -DriveLetter ([IO.Path]::GetPathRoot([Environment]::GetFolderPath([Environment+SpecialFolder]::UserProfile)).Replace(":\", "").Trim())).SizeRemaining
|
||||||
|
Write-Debug "Free space on installation drive: $($driveSpace) bytes"
|
||||||
|
if ($driveSpace -lt ($isoSize * 2))
|
||||||
|
{
|
||||||
|
# It's not critical and we _may_ continue. Output a warning
|
||||||
|
Write-Warning "You may not have enough space for this operation. Proceed at your own risk."
|
||||||
|
}
|
||||||
|
elseif ($driveSpace -lt $isoSize)
|
||||||
|
{
|
||||||
|
# It's critical and we can't continue. Output an error
|
||||||
|
Write-Host "You don't have enough space for this operation. You need at least $([Math]::Round(($isoSize / ([Math]::Pow(1024, 2))) * 2, 2)) MB of free space to copy the ISO files to a temp directory and to be able to perform additional operations."
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-Host "You have enough space for this operation."
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Write-Host "Mounting Iso. Please wait."
|
Write-Host "Mounting Iso. Please wait."
|
||||||
$mountedISO = Mount-DiskImage -PassThru "$filePath"
|
$mountedISO = Mount-DiskImage -PassThru "$filePath"
|
||||||
@ -101,6 +126,7 @@ function Invoke-WPFGetIso {
|
|||||||
Write-Error "Failed to mount the image. Error: $($_.Exception.Message)"
|
Write-Error "Failed to mount the image. Error: $($_.Exception.Message)"
|
||||||
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
|
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
|
||||||
Write-Error "Please refer to this wiki for more details https://github.com/ChrisTitusTech/winutil/blob/main/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting%2Cmd"
|
Write-Error "Please refer to this wiki for more details https://github.com/ChrisTitusTech/winutil/blob/main/wiki/Error-in-Winutil-MicroWin-during-ISO-mounting%2Cmd"
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
# storing off values in hidden fields for further steps
|
# storing off values in hidden fields for further steps
|
||||||
@ -124,13 +150,26 @@ function Invoke-WPFGetIso {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Detect if the folders already exist and remove them
|
||||||
|
if (($sync.MicrowinMountDir.Text -ne "") -and (Test-Path -Path $sync.MicrowinMountDir.Text))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Write-Host "Deleting temporary files from previous run. Please wait..."
|
||||||
|
Remove-Item -Path $sync.MicrowinMountDir.Text -Recurse -Force
|
||||||
|
Remove-Item -Path $sync.MicrowinScratchDir.Text -Recurse -Force
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "Could not delete temporary files. You need to delete those manually."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Setting up mount dir and scratch dirs"
|
Write-Host "Setting up mount dir and scratch dirs"
|
||||||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||||
$randomNumber = Get-Random -Minimum 1 -Maximum 9999
|
$randomNumber = Get-Random -Minimum 1 -Maximum 9999
|
||||||
$randomMicrowin = "Microwin_${timestamp}_${randomNumber}"
|
$randomMicrowin = "Microwin_${timestamp}_${randomNumber}"
|
||||||
$randomMicrowinScratch = "MicrowinScratch_${timestamp}_${randomNumber}"
|
$randomMicrowinScratch = "MicrowinScratch_${timestamp}_${randomNumber}"
|
||||||
$sync.BusyText.Text=" - Mounting"
|
$sync.BusyText.Text=" - Mounting"
|
||||||
Write-Host "Mounting Iso. Please wait."
|
Write-Host "Mounting Iso. Please wait."
|
||||||
if ($sync.MicrowinScratchDirBox.Text -eq "") {
|
if ($sync.MicrowinScratchDirBox.Text -eq "") {
|
||||||
$mountDir = Join-Path $env:TEMP $randomMicrowin
|
$mountDir = Join-Path $env:TEMP $randomMicrowin
|
||||||
$scratchDir = Join-Path $env:TEMP $randomMicrowinScratch
|
$scratchDir = Join-Path $env:TEMP $randomMicrowinScratch
|
||||||
@ -146,12 +185,12 @@ function Invoke-WPFGetIso {
|
|||||||
Write-Host "Image dir is $mountDir"
|
Write-Host "Image dir is $mountDir"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
#$data = @($driveLetter, $filePath)
|
#$data = @($driveLetter, $filePath)
|
||||||
New-Item -ItemType Directory -Force -Path "$($mountDir)" | Out-Null
|
New-Item -ItemType Directory -Force -Path "$($mountDir)" | Out-Null
|
||||||
New-Item -ItemType Directory -Force -Path "$($scratchDir)" | Out-Null
|
New-Item -ItemType Directory -Force -Path "$($scratchDir)" | Out-Null
|
||||||
Write-Host "Copying Windows image. This will take awhile, please don't use UI or cancel this step!"
|
Write-Host "Copying Windows image. This will take awhile, please don't use UI or cancel this step!"
|
||||||
|
|
||||||
# xcopy we can verify files and also not copy files that already exist, but hard to measure
|
# xcopy we can verify files and also not copy files that already exist, but hard to measure
|
||||||
# xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null
|
# xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null
|
||||||
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" $mountDir -Recurse -Force }
|
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" $mountDir -Recurse -Force }
|
||||||
@ -160,13 +199,19 @@ function Invoke-WPFGetIso {
|
|||||||
$wimFile = "$mountDir\sources\install.wim"
|
$wimFile = "$mountDir\sources\install.wim"
|
||||||
Write-Host "Getting image information $wimFile"
|
Write-Host "Getting image information $wimFile"
|
||||||
|
|
||||||
if (-not (Test-Path -Path $wimFile -PathType Leaf))
|
if ((-not (Test-Path -Path $wimFile -PathType Leaf)) -and (-not (Test-Path -Path $wimFile.Replace(".wim", ".esd").Trim() -PathType Leaf)))
|
||||||
{
|
{
|
||||||
$msg = "Install.wim file doesn't exist in the image, this could happen if you use unofficial Windows images, or a Media creation tool, which creates a final image that can not be modified. Please don't use shady images from the internet, use only official images. Here are instructions how to download ISO images if the Microsoft website is not showing the link to download and ISO. https://www.techrepublic.com/article/how-to-download-a-windows-10-iso-file-without-using-the-media-creation-tool/"
|
$msg = "Neither install.wim nor install.esd exist in the image, this could happen if you use unofficial Windows images. Please don't use shady images from the internet, use only official images. Here are instructions how to download ISO images if the Microsoft website is not showing the link to download and ISO. https://www.techrepublic.com/article/how-to-download-a-windows-10-iso-file-without-using-the-media-creation-tool/"
|
||||||
Write-Host $msg
|
Write-Host $msg
|
||||||
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
throw
|
throw
|
||||||
}
|
}
|
||||||
|
elseif ((-not (Test-Path -Path $wimFile -PathType Leaf)) -and (Test-Path -Path $wimFile.Replace(".wim", ".esd").Trim() -PathType Leaf))
|
||||||
|
{
|
||||||
|
Write-Host "Install.esd found on the image. It needs to be converted to a WIM file in order to begin processing"
|
||||||
|
$wimFile = $wimFile.Replace(".wim", ".esd").Trim()
|
||||||
|
}
|
||||||
$sync.MicrowinWindowsFlavors.Items.Clear()
|
$sync.MicrowinWindowsFlavors.Items.Clear()
|
||||||
Get-WindowsImage -ImagePath $wimFile | ForEach-Object {
|
Get-WindowsImage -ImagePath $wimFile | ForEach-Object {
|
||||||
$imageIdx = $_.ImageIndex
|
$imageIdx = $_.ImageIndex
|
||||||
@ -200,6 +245,7 @@ function Invoke-WPFGetIso {
|
|||||||
|
|
||||||
$sync.BusyMessage.Visibility="Hidden"
|
$sync.BusyMessage.Visibility="Hidden"
|
||||||
$sync.ProcessRunning = $false
|
$sync.ProcessRunning = $false
|
||||||
|
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,12 +33,12 @@ function Invoke-WPFImpex {
|
|||||||
|
|
||||||
if($FileBrowser.FileName -eq ""){
|
if($FileBrowser.FileName -eq ""){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$Config = $FileBrowser.FileName
|
$Config = $FileBrowser.FileName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type -eq "export"){
|
if ($type -eq "export"){
|
||||||
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false
|
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false
|
||||||
$jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force
|
$jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force
|
||||||
|
@ -2,43 +2,70 @@ function Invoke-WPFInstall {
|
|||||||
<#
|
<#
|
||||||
|
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Installs the selected programs using winget
|
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.
|
||||||
|
|
||||||
#>
|
#>
|
||||||
|
|
||||||
if($sync.ProcessRunning){
|
if($sync.ProcessRunning){
|
||||||
$msg = "[Invoke-WPFInstall] 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)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$WingetInstall = (Get-WinUtilCheckBoxes)["Install"]
|
$PackagesToInstall = (Get-WinUtilCheckBoxes)["Install"]
|
||||||
|
Write-Host $PackagesToInstall
|
||||||
if ($wingetinstall.Count -eq 0) {
|
if ($PackagesToInstall.Count -eq 0) {
|
||||||
$WarningMsg = "Please select the program(s) to install"
|
$WarningMsg = "Please select the program(s) to install or upgrade"
|
||||||
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Invoke-WPFRunspace -ArgumentList $WingetInstall -DebugPreference $DebugPreference -ScriptBlock {
|
|
||||||
param($WingetInstall, $DebugPreference)
|
Invoke-WPFRunspace -ArgumentList $PackagesToInstall -DebugPreference $DebugPreference -ScriptBlock {
|
||||||
|
param($PackagesToInstall, $DebugPreference)
|
||||||
|
if ($PackagesToInstall.count -eq 1){
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
|
||||||
|
} else {
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
|
||||||
|
}
|
||||||
|
$packagesWinget, $packagesChoco = {
|
||||||
|
$packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new()
|
||||||
|
$packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new()
|
||||||
|
foreach ($package in $PackagesToInstall) {
|
||||||
|
if ($package.winget -eq "na") {
|
||||||
|
$packagesChoco.add($package)
|
||||||
|
Write-Host "Queueing $($package.choco) for Chocolatey install"
|
||||||
|
} else {
|
||||||
|
$packagesWinget.add($package)
|
||||||
|
Write-Host "Queueing $($package.winget) for Winget install"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $packagesWinget, $packagesChoco
|
||||||
|
}.Invoke($PackagesToInstall)
|
||||||
|
|
||||||
try{
|
try{
|
||||||
$sync.ProcessRunning = $true
|
$sync.ProcessRunning = $true
|
||||||
|
$errorPackages = @()
|
||||||
Install-WinUtilWinget
|
if($packagesWinget.Count -gt 0){
|
||||||
Install-WinUtilProgramWinget -ProgramsToInstall $WingetInstall
|
Install-WinUtilWinget
|
||||||
|
$errorPackages += Install-WinUtilProgramWinget -ProgramsToInstall $packagesWinget
|
||||||
|
$errorPackages| ForEach-Object {if($_.choco -ne "na") {$packagesChoco += $_}}
|
||||||
|
}
|
||||||
|
if($packagesChoco.Count -gt 0){
|
||||||
|
Install-WinUtilChoco
|
||||||
|
Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco
|
||||||
|
}
|
||||||
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" })
|
||||||
}
|
}
|
||||||
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" })
|
||||||
}
|
}
|
||||||
Start-Sleep -Seconds 5
|
|
||||||
$sync.ProcessRunning = $False
|
$sync.ProcessRunning = $False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,7 @@ function Invoke-WPFInstallUpgrade {
|
|||||||
Invokes the function that upgrades all installed programs using winget
|
Invokes the function that upgrades all installed programs using winget
|
||||||
|
|
||||||
#>
|
#>
|
||||||
if(!(Get-Command -Name winget -ErrorAction SilentlyContinue)){
|
if((Test-WinUtilPackageManager -winget) -eq "not-installed"){
|
||||||
Write-Host "==========================================="
|
|
||||||
Write-Host "-- Winget is not installed ---"
|
|
||||||
Write-Host "==========================================="
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,10 +15,12 @@ function Invoke-WPFInstallUpgrade {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set-WinUtilTaskbaritem -state "Indeterminate"
|
||||||
|
|
||||||
Update-WinUtilProgramWinget
|
Update-WinUtilProgramWinget
|
||||||
|
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
Write-Host "-- Updates started ---"
|
Write-Host "-- Updates started ---"
|
||||||
Write-Host "-- You can close this window if desired ---"
|
Write-Host "-- You can close this window if desired ---"
|
||||||
Write-Host "==========================================="
|
Write-Host "==========================================="
|
||||||
}
|
}
|
||||||
|