Compare commits
463 Commits
7d36a688a0
...
main
Author | SHA1 | Date | |
---|---|---|---|
cea4e088cf | |||
32a4311901 | |||
ff95b35f24 | |||
aea9c2cb47 | |||
7fa0594267 | |||
5e65505007 | |||
686e65adcb | |||
1935375f88 | |||
069a1bda2f | |||
661dfa6318 | |||
d6b78d1d06 | |||
51f15a03c2 | |||
ce91307daf | |||
8fe09d0054 | |||
e74258acf4 | |||
28958938fc | |||
91de389c8f | |||
6b22c63d28 | |||
faa4701c43 | |||
cda2babc66 | |||
0e83879c64 | |||
00c295e8d5 | |||
4be99d5f8a | |||
febae28095 | |||
0a77838689 | |||
cccd4298ad | |||
bc7afe8b2a | |||
18de3d59ee | |||
59d968e7c4 | |||
afe85ad7f0 | |||
efb9e5bde6 | |||
56eba47a6c | |||
e57cde423c | |||
de9b643129 | |||
e430e0aad0 | |||
61fd4d2f91 | |||
b72cd83189 | |||
290292ec94 | |||
d22865d79b | |||
5c5b999a09 | |||
0c0e6bd243 | |||
dd06489d63 | |||
41df9d3d88 | |||
63d56bcac9 | |||
962b18e8fa | |||
14e761f438 | |||
3e416f5c14 | |||
95d28ee25d | |||
50071067b7 | |||
3b7d707262 | |||
ea95dac426 | |||
b4d3368680 | |||
0b5c44cbcf | |||
b8b16be24b | |||
14943e3c55 | |||
91365d50b5 | |||
82b6c268b0 | |||
d8c007d2db | |||
48f1c71584 | |||
f770642a6a | |||
963c0a17aa | |||
20769f66a1 | |||
86459b7e24 | |||
89919494e5 | |||
5f6bdb2e48 | |||
f614eea435 | |||
82447a1e7b | |||
51424abfad | |||
3caa3be9a3 | |||
7769a328bb | |||
425f11d787 | |||
6df94df594 | |||
29e2c4d197 | |||
b63a17b7dd | |||
abe059917c | |||
698f1644c3 | |||
fd03f33c50 | |||
8f9e7d1b7c | |||
b3dd1a1a50 | |||
4acad32a38 | |||
0f4fca31b9 | |||
36c984b66c | |||
d215d0fc2c | |||
52de4690ab | |||
ef97a8da24 | |||
18a7f17a0b | |||
5a8cf5deb6 | |||
e4b2a38372 | |||
94c5d89430 | |||
8a0e0c7715 | |||
1ae16f6f38 | |||
6038556e64 | |||
329a3de9a6 | |||
f6e5d0e053 | |||
364076c25e | |||
a051e64a91 | |||
dccda61ab4 | |||
048f580a56 | |||
bfb83ced79 | |||
e2b37445f6 | |||
c2fb98b0dc | |||
cf8787a700 | |||
53b723fa11 | |||
32cb94f392 | |||
5550e40270 | |||
bcecf67c7d | |||
3b50ff813c | |||
eba5b35978 | |||
254738a420 | |||
bcc801683d | |||
72c23823b2 | |||
4e1ce7e417 | |||
1dd0367417 | |||
201f24c76e | |||
9183e92692 | |||
fa9dbcace4 | |||
02f0f85c25 | |||
83ae0579ba | |||
5ebcacf404 | |||
28bea518f0 | |||
61c2e39ddb | |||
0dfa9617fc | |||
2ce4f54b80 | |||
a05556a896 | |||
985d415db1 | |||
f4d4bdad3c | |||
9d47514190 | |||
4fc34e44b3 | |||
c33946bde2 | |||
4466720493 | |||
1d0e3bfd5c | |||
83450aef7b | |||
e2ce998426 | |||
cf7f161a06 | |||
d6c1fbe4a2 | |||
0779dd9096 | |||
d48f212be4 | |||
9c52f01204 | |||
d49b21f881 | |||
39ee4d53c0 | |||
6e708bfe95 | |||
e2b9586b0d | |||
c418fe9030 | |||
d619ee7e85 | |||
bbc18b2d4b | |||
9778c0d572 | |||
8087a607fc | |||
e5b79559bd | |||
66e6aa7e96 | |||
def47fe018 | |||
b382f16ae8 | |||
171441ddcf | |||
7a0c40420e | |||
0f0d9d0ae3 | |||
6149738e6c | |||
aa0b03feda | |||
e0889d51db | |||
ce1ef2a519 | |||
77cb0a14c4 | |||
c254a43f77 | |||
640d2ca107 | |||
c186642998 | |||
47a4f1547e | |||
1caf3111d3 | |||
7dcdc4dbb7 | |||
bfaba14191 | |||
5640f9d04c | |||
c6a832b006 | |||
fe19094395 | |||
fdd32f441f | |||
e4565f1f6f | |||
1404efab26 | |||
1deb863f40 | |||
de73efa868 | |||
59097fc7e1 | |||
207ce43428 | |||
d92284ec83 | |||
d855b08119 | |||
0deac4ebb2 | |||
c6fcf21dce | |||
64ed00c2db | |||
e165388117 | |||
806cbd021a | |||
869071783c | |||
ae74965548 | |||
b43d31088c | |||
4fa1b0ddc7 | |||
f012064574 | |||
db26666f97 | |||
38cf922572 | |||
dd337be45e | |||
3670c78789 | |||
225e774f1e | |||
0703935bfb | |||
fd2ac35228 | |||
f516c09ab3 | |||
182fe09b64 | |||
02751c706d | |||
102231c0e3 | |||
b9d7619f9b | |||
4e39096b51 | |||
662139ca5f | |||
42febae25e | |||
395ac9495d | |||
6cc7d314fe | |||
ba45c3303e | |||
1f683d3f78 | |||
18dff2af5e | |||
377758758e | |||
3f2759f967 | |||
1ee7274bdb | |||
06baebc60b | |||
10917c159c | |||
0251757fc0 | |||
9136ed9802 | |||
b3bbe0dbe5 | |||
16b11e994b | |||
a5a06c2a9b | |||
81aead7a68 | |||
a55a44a54c | |||
9c0b0b8913 | |||
7fe0f9a163 | |||
8e5fcceddb | |||
19a3c7070a | |||
343a72f528 | |||
0b13ca4b11 | |||
215de06a58 | |||
80555d945e | |||
314588283a | |||
00668755c9 | |||
d3ef94f175 | |||
1ac24c236e | |||
ff363d686f | |||
9abe11c975 | |||
14d20cd161 | |||
2b9b1b026c | |||
e9a45a002f | |||
6d996495a3 | |||
473f04ddc5 | |||
95db85f791 | |||
5059b93cd7 | |||
380e1e73a6 | |||
ad37371492 | |||
1bfd8bddcc | |||
6ad31edef1 | |||
c1009c3d7c | |||
885108df7e | |||
b21bc35443 | |||
e2d539048d | |||
588008612d | |||
859a733740 | |||
3bb1881254 | |||
8b37420eec | |||
af7528a60b | |||
0c6b2adb91 | |||
0635145896 | |||
2d751f4e8c | |||
9b9d0c58f5 | |||
531cb4c63c | |||
42bda0dc47 | |||
3414a3eee1 | |||
a4302742b3 | |||
2a0d121cf0 | |||
a397f20ac6 | |||
bddf57bcee | |||
2b3f1a811d | |||
2af864f7ab | |||
2b8592a50a | |||
aad0356c28 | |||
01515db90f | |||
2ba5572b6c | |||
7e1c593510 | |||
b6141808af | |||
a21845327b | |||
2a355c00c8 | |||
2d3dbe4f6a | |||
d315963693 | |||
6c82adbdc9 | |||
c1dd88d84a | |||
b67ec35cbb | |||
c45f36d58f | |||
1fc79bccf2 | |||
2b7d0b6c4b | |||
42061faa81 | |||
889ec8f57d | |||
be6b5b3aa0 | |||
90ddfb02a4 | |||
ece57f8ee2 | |||
6a99be9e05 | |||
488cd8dd98 | |||
7eed393902 | |||
97876348d9 | |||
f8db21bbee | |||
3697be1be4 | |||
51068d9670 | |||
46f827fe2f | |||
f6b238ec30 | |||
cc157f6976 | |||
9ae5092e29 | |||
c741e006eb | |||
322d527a0c | |||
99aff2aefc | |||
cfb9edbce7 | |||
bcfbce66fd | |||
2748767a47 | |||
83fe6c5b12 | |||
2ea708eeb0 | |||
11d3c66fc0 | |||
3dd51a6c3c | |||
307980a7ef | |||
93c96fafd2 | |||
4d2ea15e19 | |||
b0d54e41ad | |||
d0fa506e4f | |||
67be99bb7b | |||
46d9e2c437 | |||
863dd83faa | |||
09eb4eaa00 | |||
17d523d8f8 | |||
fa17abdd49 | |||
8fd08f7ac5 | |||
6c3539edbe | |||
ed1cdf0233 | |||
a046bcd6a2 | |||
bf518522f8 | |||
35dfd847ab | |||
0e85f20680 | |||
bdfc4c076c | |||
8c4dc82d31 | |||
e90156adb9 | |||
5d7d121e1f | |||
0919e78693 | |||
41ac93d09a | |||
5994105fba | |||
0bce9e2647 | |||
723e1a132d | |||
5acbfbd253 | |||
1945fe288d | |||
6ff815eed3 | |||
138c5de5d3 | |||
c619d02724 | |||
a0d15f1584 | |||
c5f29df2b2 | |||
11333a1f17 | |||
ff4398e45c | |||
7841f4bbce | |||
5b993adba9 | |||
73d42dee20 | |||
ee0a2818b6 | |||
9a1fbd77a7 | |||
5e3c6ba452 | |||
478aa4ac7b | |||
123d78116b | |||
a2d9f47ea6 | |||
da824d58a7 | |||
f38f534850 | |||
04c84dce45 | |||
3903eaaa24 | |||
3b2af3fa2b | |||
c979dae926 | |||
a5a8f3ff6f | |||
31aedcf684 | |||
ab6898aebc | |||
68437c2406 | |||
7c214666b8 | |||
9284741cd3 | |||
97e517a9dd | |||
97f67fa4b2 | |||
a77ef020fe | |||
2b01fb739f | |||
f3df13a4ca | |||
33d5d55b15 | |||
0bea5f8ceb | |||
de8a79df22 | |||
1c9cef0079 | |||
49100e1dd6 | |||
547e433b0b | |||
4ee41cf198 | |||
c2addcfedf | |||
09575b0f8d | |||
5a89053534 | |||
1350013b3e | |||
80675b4c3f | |||
2a530d0c12 | |||
fb1a0b919c | |||
83bcf246f6 | |||
e2567bddc9 | |||
2508f28806 | |||
2d185e1919 | |||
5ac13f265e | |||
128593a950 | |||
e7328c2739 | |||
18f9f5e35d | |||
760fb3d30a | |||
a75c80057a | |||
514eddd0b6 | |||
3929459106 | |||
b4bf321e66 | |||
74f58e7957 | |||
875864060e | |||
e38615b4b4 | |||
9f33cb1b82 | |||
313c5f59de | |||
7de93ae208 | |||
140620e76c | |||
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 |
128
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
contact@christitus.com.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
117
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# 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 https://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
|
||||||
|
%%{init: {"flowchart": {"curve": "cardinal"}} }%%
|
||||||
|
graph TD
|
||||||
|
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];
|
||||||
|
H -->|No| J[Fix Issues];
|
||||||
|
J --> G;
|
||||||
|
E --> F[Push Branch];
|
||||||
|
F --> K[Create Pull Request];
|
||||||
|
K --> L[Fill out PR template];
|
||||||
|
classDef default stroke:#333,stroke-width:4px,font-size:12pt;
|
||||||
|
```
|
||||||
|
!!! 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.
|
26
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
## Describe the bug
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
## To Reproduce
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
## Expected behavior
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
## Additional context
|
|
||||||
Add any other context about the problem here.
|
|
62
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
name: "Bug report"
|
||||||
|
description: "Report a bug to help us identify and fix issues in the project."
|
||||||
|
labels: ["bug"]
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
# 🐞 **Issue Report**
|
||||||
|
Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
|
||||||
|
|
||||||
|
## ⚠️ **IMPORTANT**
|
||||||
|
- 🛠️ **Supported environments only:** We only support Windows 11. Custom ISOs that are not made using Microwin are not supported.
|
||||||
|
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: ⚙️ Issue Checklist
|
||||||
|
options:
|
||||||
|
- label: I have read the guidelines.
|
||||||
|
- label: I checked for duplicate issues.
|
||||||
|
- label: I searched for existing discussions.
|
||||||
|
- label: I checked for an existing pull request that addresses this issue.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: affected_part
|
||||||
|
attributes:
|
||||||
|
label: 📜 What part of Winutil are you having issues with?
|
||||||
|
placeholder: "e.g., Microwin, Tweaks, etc."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: issue_description
|
||||||
|
attributes:
|
||||||
|
label: 📝 Provide a clear and concise description of the issue.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: steps_to_reproduce
|
||||||
|
attributes:
|
||||||
|
label: 🔄 Steps to reproduce the issue.
|
||||||
|
placeholder: "e.g., Step 1: ..., Step 2: ..."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: error_output
|
||||||
|
attributes:
|
||||||
|
label: ❌ Paste the full error output (if available).
|
||||||
|
placeholder: "Include any relevant logs or error messages."
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional_context
|
||||||
|
attributes:
|
||||||
|
label: 🖼️ Additional context.
|
||||||
|
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
|
||||||
|
validations:
|
||||||
|
required: false
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: 💻 Community Discord
|
||||||
|
url: https://discord.gg/RUbZUZyByQ
|
||||||
|
about: Join our Community Discord server to chat with other users in the Winutil community.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
57
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
name: "Feature request"
|
||||||
|
description: "Suggest a new feature or improvement for the project."
|
||||||
|
labels: ["enhancement"]
|
||||||
|
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
# ✨ **Feature request**
|
||||||
|
Thank you for taking the time to suggest a feature! Please provide as much detail as possible to help us understand and evaluate your request.
|
||||||
|
|
||||||
|
## ⚠️ **IMPORTANT**
|
||||||
|
- 🛠️ **Supported environments only:** We only support Windows 11.
|
||||||
|
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: ⚙️ Issue Checklist
|
||||||
|
options:
|
||||||
|
- label: I have read the guidelines.
|
||||||
|
- label: I checked for duplicate issues.
|
||||||
|
- label: I searched for existing discussions.
|
||||||
|
- label: I checked for an existing pull request that addresses this request.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: problem_statement
|
||||||
|
attributes:
|
||||||
|
label: ❓ Is your feature request related to a problem?
|
||||||
|
placeholder: "Provide a clear and concise description of the issue you're facing. Example: 'I'm always frustrated when [...]'"
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: proposed_solution
|
||||||
|
attributes:
|
||||||
|
label: 💡 Describe the solution you'd like
|
||||||
|
placeholder: "Provide a clear and concise description of what you want to happen."
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: alternatives
|
||||||
|
attributes:
|
||||||
|
label: 🔄 Describe alternatives you've considered
|
||||||
|
placeholder: "Provide details on any alternative solutions or features you've thought about."
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: additional_context
|
||||||
|
attributes:
|
||||||
|
label: 🖼️ Additional context
|
||||||
|
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
|
||||||
|
validations:
|
||||||
|
required: false
|
15
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,7 +1,4 @@
|
|||||||
# Pull Request
|
<!--Before you make this PR have you followed the docs here? - https://christitustech.github.io/winutil/contribute/ -->
|
||||||
|
|
||||||
## Title
|
|
||||||
[Provide a succinct and descriptive title for the pull request.]
|
|
||||||
|
|
||||||
## Type of Change
|
## Type of Change
|
||||||
- [ ] New feature
|
- [ ] New feature
|
||||||
@ -13,20 +10,20 @@
|
|||||||
- [ ] UI/UX improvement
|
- [ ] UI/UX improvement
|
||||||
|
|
||||||
## Description
|
## 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.]
|
<!--[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
|
## Testing
|
||||||
[Detail the testing you have performed to ensure that these changes function as intended. Include information about any added tests.]
|
<!--[Detail the testing you have performed to ensure that these changes function as intended. Include information about any added tests.]-->
|
||||||
|
|
||||||
## Impact
|
## Impact
|
||||||
[Discuss the impact of your changes on the project. This might include effects on performance, new dependencies, or changes in behaviour.]
|
<!--[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
|
## Issue related to PR
|
||||||
[What issue/discussion is related to this PR (if any)]
|
<!--[What issue/discussion is related to this PR (if any)]-->
|
||||||
- Resolves #
|
- Resolves #
|
||||||
|
|
||||||
## Additional Information
|
## Additional Information
|
||||||
[Any additional information that reviewers should be aware of.]
|
<!--[Any additional information that reviewers should be aware of.]-->
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
- [ ] My code adheres to the coding and style guidelines of the project.
|
- [ ] My code adheres to the coding and style guidelines of the project.
|
||||||
|
5
.github/SECURITY.md
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
If you find a security issue please make post it in the issues tab. If you think it should be private you can email me at contact@christitus.com.
|
||||||
|
|
||||||
|
For immediate response check out our discord server @ [](https://discord.gg/RUbZUZyByQ)
|
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'
|
54
.github/release-drafter.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
tag-prefix: ''
|
||||||
|
categories:
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug Fixes'
|
||||||
|
labels:
|
||||||
|
- 'fix'
|
||||||
|
- 'bugfix'
|
||||||
|
- 'bug'
|
||||||
|
- title: '📚 Documentation'
|
||||||
|
label: 'documentation'
|
||||||
|
- title: '🔒 Security'
|
||||||
|
label: 'security'
|
||||||
|
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||||
|
template: |
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
$CHANGES
|
||||||
|
|
||||||
|
change-title-escapes: '\<*_&"'''
|
||||||
|
autolabeler:
|
||||||
|
- label: 'documentation'
|
||||||
|
files:
|
||||||
|
- '*.md'
|
||||||
|
branch:
|
||||||
|
- '/docs{0,1}\/.+/'
|
||||||
|
- label: 'bug'
|
||||||
|
branch:
|
||||||
|
- '/fix\/.+/'
|
||||||
|
title:
|
||||||
|
- '/fix/i'
|
||||||
|
- label: 'enhancement'
|
||||||
|
branch:
|
||||||
|
- '/feature\/.+/'
|
||||||
|
body:
|
||||||
|
- '/[A-Z]+-[0-9]+/'
|
||||||
|
- label: 'documentation'
|
||||||
|
files:
|
||||||
|
- '**/*.md'
|
||||||
|
- 'docs/**/*'
|
||||||
|
- label: 'security'
|
||||||
|
branch:
|
||||||
|
- '/security\/.+/'
|
||||||
|
replacers:
|
||||||
|
- search: /"/g
|
||||||
|
replace: ''
|
||||||
|
- search: /'/g
|
||||||
|
replace: ''
|
||||||
|
exclude-labels:
|
||||||
|
- 'skip-changelog'
|
||||||
|
|
||||||
|
filter-by-commitish: true
|
48
.github/workflows/close-discussion-on-pr.yaml
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
name: Close Discussion on PR Merge
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [closed]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
closeDiscussion:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- 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 Were Found
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
if: github.event.pull_request.merged == true
|
||||||
|
id: extract-discussion
|
||||||
|
run: |
|
||||||
|
pr_body="${{ github.event.pull_request.body }}"
|
||||||
|
discussion_ids=$(echo "$pr_body" | grep -oP '(?i)(resolve|fix|close)[s|d]? #\K[0-9]+')
|
||||||
|
|
||||||
|
if [ -z "$discussion_ids" ]; then
|
||||||
|
echo "No discussion IDs found."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for discussion_id in $discussion_ids; do
|
||||||
|
echo "Attempting to close discussion #$discussion_id"
|
||||||
|
response=$(curl -s -X PATCH -H "Authorization: token $GITHUB_TOKEN" \
|
||||||
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
-d '{"state": "closed"}' \
|
||||||
|
"https://api.github.com/repos/${{ github.repository }}/discussions/$discussion_id")
|
||||||
|
|
||||||
|
if echo "$response" | jq -e '.id' > /dev/null; then
|
||||||
|
echo "Successfully closed discussion #$discussion_id"
|
||||||
|
else
|
||||||
|
error_message=$(echo "$response" | jq -r '.message // "Unknown error"')
|
||||||
|
echo "Warning: Failed to close discussion #$discussion_id. Error: $error_message"
|
||||||
|
echo "Full response: $response"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
shell: bash
|
||||||
|
continue-on-error: true
|
30
.github/workflows/close-discussion.yml
vendored
@ -1,30 +0,0 @@
|
|||||||
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
|
|
||||||
if: github.event.pull_request.merged == true
|
|
||||||
id: extract-discussion
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=discussion::$(echo "${{ github.event.pull_request.body }}" | grep -oP '(?<=Resolves #)\d+')"
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Close the discussion
|
|
||||||
if: github.event.pull_request.merged == true && steps.extract-discussion.outputs.discussion
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
DISCUSSION_ID: ${{ steps.extract-discussion.outputs.discussion }}
|
|
||||||
run: |
|
|
||||||
curl -X PATCH -H "Authorization: token $GITHUB_TOKEN" \
|
|
||||||
-d '{"state": "closed"}' \
|
|
||||||
"https://api.github.com/repos/${{ github.repository }}/discussions/${DISCUSSION_ID}"
|
|
8
.github/workflows/close-old-issues.yaml
vendored
@ -22,14 +22,14 @@ jobs:
|
|||||||
exempt-issue-labels: "Keep Issue Open"
|
exempt-issue-labels: "Keep Issue Open"
|
||||||
# Split it into two weeks, after one week the issue will be marked as stale,
|
# Split it into two weeks, after one week the issue will be marked as stale,
|
||||||
# after another week have pasted without any update.. the issue will then be closed.
|
# after another week have pasted without any update.. the issue will then be closed.
|
||||||
days-before-issue-stale: 7
|
days-before-issue-stale: 90
|
||||||
days-before-issue-close: 7
|
days-before-issue-close: 365
|
||||||
# NEVER mark PRs as Stale or Close + this workflow should never have write permissions on PRs, EVER!
|
# NEVER mark PRs as Stale or Close + this workflow should never have write permissions on PRs, EVER!
|
||||||
days-before-pr-stale: -1
|
days-before-pr-stale: -1
|
||||||
days-before-pr-close: -1
|
days-before-pr-close: -1
|
||||||
# Sends a message for both the Stale and Close events of an issue.
|
# Sends a message for both the Stale and Close events of an issue.
|
||||||
stale-issue-message: "This issue was marked as stale because it has been inactive for 7 days"
|
stale-issue-message: "This issue was marked as stale due to inactivity."
|
||||||
close-issue-message: "This issue was closed because it has been inactive for 7 days since it was marked as stale"
|
close-issue-message: "This issue was closed after remaining stale without updates."
|
||||||
# Increase this value if the project receives a lot of
|
# Increase this value if the project receives a lot of
|
||||||
# PRs (yes.. apparently they're processed no matter what) & Issues.
|
# PRs (yes.. apparently they're processed no matter what) & Issues.
|
||||||
# Default value for it (according to the docs) is 30
|
# Default value for it (according to the docs) is 30
|
||||||
|
@ -1,25 +1,22 @@
|
|||||||
name: Compile
|
name: Compile & Check
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: ["main"]
|
||||||
- main
|
pull_request:
|
||||||
- test*
|
branches: ["main"]
|
||||||
workflow_dispatch: # Manual trigger added
|
workflow_dispatch: # Manual trigger added
|
||||||
|
workflow_call: # Allow other Actions to call this workflow
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-runspace:
|
Compile-and-Check:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout Sources
|
||||||
with:
|
uses: actions/checkout@v4
|
||||||
ref: ${{ github.head_ref }}
|
|
||||||
- name: Compile project
|
- name: Compile and Syntaxcheck winutil.ps1
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
Set-ExecutionPolicy Bypass -Scope Process -Force; ./Compile.ps1
|
Set-ExecutionPolicy Bypass -Scope Process -Force; ./Compile.ps1
|
||||||
continue-on-error: false # Directly fail the job on error, removing the need for a separate check
|
continue-on-error: false # Directly fail the job on error, removing the need for a separate check
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
|
||||||
with:
|
|
||||||
commit_message: Compile Winutil
|
|
||||||
if: success()
|
|
40
.github/workflows/createchangelog.yml
vendored
@ -1,40 +0,0 @@
|
|||||||
name: Update update.mb on Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update-file:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Get latest release and update update.mb file
|
|
||||||
run: |
|
|
||||||
# Fetch the latest release using GitHub CLI
|
|
||||||
latest_release=$(gh release view --json tagName,name,body --jq '{tag: .tagName, name: .name, body: .body}')
|
|
||||||
|
|
||||||
# Extract details
|
|
||||||
tag=$(echo "$latest_release" | jq -r '.tag')
|
|
||||||
name=$(echo "$latest_release" | jq -r '.name')
|
|
||||||
body=$(echo "$latest_release" | jq -r '.body')
|
|
||||||
version_numeric=$(echo "$tag" | grep -o -E '[0-9.]+')
|
|
||||||
|
|
||||||
# Append to update.mb
|
|
||||||
echo "## $version_numeric" >> docs/update.mb
|
|
||||||
echo "Release name: $name" >> docs/update.mb
|
|
||||||
echo "Release body: $body" >> docs/update.mb
|
|
||||||
echo "" >> docs/update.mb
|
|
||||||
|
|
||||||
- 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/update.mb
|
|
||||||
git commit -m "Update update.mb with latest release"
|
|
||||||
git push
|
|
23
.github/workflows/github-pages.yml
vendored
@ -1,23 +0,0 @@
|
|||||||
name: GitHub Pages Deploy
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- main
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: 3.x
|
|
||||||
- uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
key: ${{ github.ref }}
|
|
||||||
path: .cache
|
|
||||||
- run: pip install mkdocs-material
|
|
||||||
- run: pip install pillow cairosvg
|
|
||||||
- run: mkdocs gh-deploy --force
|
|
94
.github/workflows/issue-slash-commands.yaml
vendored
@ -1,11 +1,13 @@
|
|||||||
name: Close issue on /close
|
name: Issue slash commands
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issue_comment:
|
issue_comment:
|
||||||
types: [created, edited]
|
types: [created, edited]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
closeIssueOnClose:
|
issueCommands:
|
||||||
|
# Skip this job if the comment was created/edited on a PR
|
||||||
|
if: ${{ !github.event.issue.pull_request }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
permissions:
|
permissions:
|
||||||
issues: write
|
issues: write
|
||||||
@ -13,31 +15,101 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check for /close comment
|
- run: echo "command=false" >> $GITHUB_ENV
|
||||||
id: check_comment
|
|
||||||
|
- name: Check for /label command
|
||||||
|
id: check_label_command
|
||||||
|
run: |
|
||||||
|
if [[ "${{ contains(github.event.comment.body, '/label') }}" == "true" ]]; then
|
||||||
|
echo "command=true" >> $GITHUB_ENV
|
||||||
|
LABEL_NAME=$(echo "${{ github.event.comment.body }}" | awk -F"/label" '/\/label/ { match($2, /'\''([^'\'']*)'\''/, arr); if (arr[1] != "") print arr[1] }')
|
||||||
|
echo "label_command=true" >> $GITHUB_ENV
|
||||||
|
echo "label_name=${LABEL_NAME}" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "label_command=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for /unlabel command
|
||||||
|
id: check_unlabel_command
|
||||||
|
run: |
|
||||||
|
if [[ "${{ contains(github.event.comment.body, '/unlabel') }}" == "true" ]]; then
|
||||||
|
echo "command=true" >> $GITHUB_ENV
|
||||||
|
UNLABEL_NAME=$(echo "${{ github.event.comment.body }}" | awk -F"/unlabel" '/\/unlabel/ { match($2, /'\''([^'\'']*)'\''/, arr); if (arr[1] != "") print arr[1] }')
|
||||||
|
echo "unlabel_command=true" >> $GITHUB_ENV
|
||||||
|
echo "unlabel_name=${UNLABEL_NAME}" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "unlabel_command=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for /close command
|
||||||
|
id: check_close_command
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then
|
if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then
|
||||||
echo "comment=true" >> $GITHUB_ENV
|
echo "command=true" >> $GITHUB_ENV
|
||||||
|
echo "close_command=true" >> $GITHUB_ENV
|
||||||
|
echo "reopen_command=false" >> $GITHUB_ENV
|
||||||
else
|
else
|
||||||
echo "comment=false" >> $GITHUB_ENV
|
echo "close_command=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for /open or /reopen command
|
||||||
|
id: check_reopen_command
|
||||||
|
run: |
|
||||||
|
if [[ "${{ contains(github.event.comment.body, '/open') }}" == "true" ]] || [[ "${{ contains(github.event.comment.body, '/reopen') }}" == "true" ]]; then
|
||||||
|
echo "command=true" >> $GITHUB_ENV
|
||||||
|
echo "reopen_command=true" >> $GITHUB_ENV
|
||||||
|
echo "close_command=false" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "reopen_command=false" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Check if the user is allowed
|
- name: Check if the user is allowed
|
||||||
id: check_user
|
id: check_user
|
||||||
if: env.comment == 'true'
|
if: env.command == 'true'
|
||||||
run: |
|
run: |
|
||||||
ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC")
|
ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC" "CodingWonders")
|
||||||
if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then
|
if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then
|
||||||
echo "user=true" >> $GITHUB_ENV
|
echo "user=true" >> $GITHUB_ENV
|
||||||
else
|
else
|
||||||
echo "user=false" >> $GITHUB_ENV
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Close issue if conditions are met
|
- name: Close issue
|
||||||
if: env.comment == 'true' && env.user == 'true'
|
if: env.close_command == 'true'
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||||
run: |
|
run: |
|
||||||
echo Closing the issue...
|
echo Closing the issue...
|
||||||
|
if [[ "${{ contains(github.event.comment.body, 'not planned') }}" == "true" ]]; then
|
||||||
|
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }} --reason 'not planned'
|
||||||
|
else
|
||||||
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
|
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Reopen issue
|
||||||
|
if: env.reopen_command == 'true'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||||
|
run: |
|
||||||
|
echo Reopening the issue...
|
||||||
|
gh issue reopen $ISSUE_NUMBER --repo ${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Label issue
|
||||||
|
if: env.label_command == 'true'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||||
|
run: |
|
||||||
|
echo Labeling the issue...
|
||||||
|
gh issue edit $ISSUE_NUMBER --repo ${{ github.repository }} --add-label "${{ env.label_name }}"
|
||||||
|
|
||||||
|
- name: Remove labels
|
||||||
|
if: env.unlabel_command == 'true'
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||||
|
run: |
|
||||||
|
echo Unlabeling the issue...
|
||||||
|
gh issue edit $ISSUE_NUMBER --repo ${{ github.repository }} --remove-label "${{ env.unlabel_name }}"
|
||||||
|
70
.github/workflows/pre-release.yaml
vendored
@ -1,49 +1,75 @@
|
|||||||
name: Pre-Release WinUtil
|
name: Pre-Release WinUtil
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
actions: read
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
|
||||||
workflows: ["Compile"] #Ensure Compile winget.ps1 is done
|
|
||||||
types:
|
|
||||||
- completed
|
|
||||||
workflow_dispatch: # Manual trigger added
|
workflow_dispatch: # Manual trigger added
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-runspace:
|
build-runspace:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
outputs:
|
env:
|
||||||
version: ${{ steps.extract_version.outputs.version }}
|
CERTIFICATE_BASE64: ${{ secrets.CERTIFICATE_BASE64 }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repository
|
- name: Checkout Repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Extract Version from winutil.ps1
|
- 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
|
||||||
|
|
||||||
|
- name: Set Version to Todays Date
|
||||||
id: extract_version
|
id: extract_version
|
||||||
run: |
|
run: |
|
||||||
$version = ''
|
$version = (Get-Date -Format "yy.MM.dd")
|
||||||
Get-Content ./winutil.ps1 -TotalCount 30 | ForEach-Object {
|
echo "VERSION=$version" >> $env:GITHUB_ENV
|
||||||
if ($_ -match 'Version\s*:\s*(\d{2}\.\d{2}\.\d{2})') {
|
shell: pwsh
|
||||||
$version = "pre"+$matches[1]
|
|
||||||
echo "version=$version" >> $GITHUB_ENV
|
- name: Create Tag
|
||||||
echo "::set-output name=version::$version"
|
id: create_tag
|
||||||
break
|
run: |
|
||||||
}
|
$tagExists = git tag -l $env:VERSION
|
||||||
}
|
if ($tagExists -eq "") {
|
||||||
if (-not $version) {
|
git tag $env:VERSION
|
||||||
Write-Error "Version not found in winutil.ps1"
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "Failed to create tag $env:VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
git push origin $env:VERSION
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "Failed to push tag $env:VERSION"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Tag $env:VERSION already exists, skipping tag creation"
|
||||||
|
}
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
|
- name: Generate Release Notes
|
||||||
|
id: generate_notes
|
||||||
|
uses: release-drafter/release-drafter@v6
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
config-name: release-drafter.yml
|
||||||
|
version: ${{ env.VERSION }} # Pass the version variable
|
||||||
|
|
||||||
- name: Create and Upload Release
|
- name: Create and Upload Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ steps.extract_version.outputs.version }}
|
tag_name: ${{ env.VERSION }}
|
||||||
name: Pre-Release ${{ steps.extract_version.outputs.version }}
|
name: Pre-Release ${{ env.VERSION }}
|
||||||
body: ""
|
body: |
|
||||||
|
${{ steps.generate_notes.outputs.body }}
|
||||||
|
|
||||||
|

|
||||||
append_body: false
|
append_body: false
|
||||||
files: ./winutil.ps1
|
files: ./winutil.ps1
|
||||||
prerelease: true
|
prerelease: true
|
||||||
generate_release_notes: true
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
45
.github/workflows/release.yaml
vendored
@ -1,45 +0,0 @@
|
|||||||
name: Release WinUtil
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch: # Manual trigger added
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-runspace:
|
|
||||||
runs-on: windows-latest
|
|
||||||
outputs:
|
|
||||||
version: ${{ steps.extract_version.outputs.version }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Extract Version from winutil.ps1
|
|
||||||
id: extract_version
|
|
||||||
run: |
|
|
||||||
$version = ''
|
|
||||||
Get-Content ./winutil.ps1 -TotalCount 30 | ForEach-Object {
|
|
||||||
if ($_ -match 'Version\s*:\s*(\d{2}\.\d{2}\.\d{2})') {
|
|
||||||
$version = $matches[1]
|
|
||||||
echo "version=$version" >> $GITHUB_ENV
|
|
||||||
echo "::set-output name=version::$version"
|
|
||||||
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 }}
|
|
34
.github/workflows/remove-winutil.yaml
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
name: Remove winutil.ps1 if included in a Push
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-and-delete-file:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Check if winutil.ps1 exists
|
||||||
|
id: check_existence
|
||||||
|
run: |
|
||||||
|
if [ -f "winutil.ps1" ]; then
|
||||||
|
echo "winutil_exists=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "winutil_exists=false" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Delete winutil.ps1 if it exists
|
||||||
|
if: steps.check_existence.outputs.winutil_exists == 'true'
|
||||||
|
run: |
|
||||||
|
git config --global user.email "winutil-action@noreply.github.com"
|
||||||
|
git config --global user.name "winutil-action"
|
||||||
|
git rm winutil.ps1
|
||||||
|
git commit -m "Delete winutil.ps1 as it is not allowed"
|
||||||
|
git push origin HEAD:${{ github.ref }}
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
@ -8,9 +8,10 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: (github.event_name == 'schedule' && github.repository == 'ChrisTitusTech/winutil') || (github.event_name != 'schedule')
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout 🛎️
|
- name: Checkout 🛎️
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Generate Sponsors 💖
|
- name: Generate Sponsors 💖
|
||||||
uses: JamesIves/github-sponsors-readme-action@v1
|
uses: JamesIves/github-sponsors-readme-action@v1
|
4
.github/workflows/unittests.yaml
vendored
@ -8,7 +8,7 @@ jobs:
|
|||||||
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,7 +22,7 @@ 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: |
|
||||||
|
9
.gitignore
vendored
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
# Configuration folder
|
# Configuration folder
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
### Visual Studio ###
|
### Visual Studio ###
|
||||||
|
|
||||||
@ -10,6 +11,9 @@
|
|||||||
|
|
||||||
winutil.pdb
|
winutil.pdb
|
||||||
|
|
||||||
|
### Preprocessor Hashes ###
|
||||||
|
.preprocessor_hashes.json
|
||||||
|
|
||||||
### Windows ###
|
### Windows ###
|
||||||
|
|
||||||
# Folder config file
|
# Folder config file
|
||||||
@ -45,3 +49,8 @@ microwin.log
|
|||||||
True
|
True
|
||||||
test.ps1
|
test.ps1
|
||||||
winutil.ps1
|
winutil.ps1
|
||||||
|
|
||||||
|
# temporary excludes for docs
|
||||||
|
.github/site/
|
||||||
|
|
||||||
|
binary/
|
||||||
|
136
Compile.ps1
@ -1,13 +1,23 @@
|
|||||||
param (
|
param (
|
||||||
[switch]$Debug,
|
[switch]$Debug,
|
||||||
[switch]$Run
|
[switch]$Run,
|
||||||
|
[string]$Arguments
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ((Get-Item ".\winutil.ps1" -ErrorAction SilentlyContinue).IsReadOnly) {
|
||||||
|
Remove-Item ".\winutil.ps1" -Force
|
||||||
|
}
|
||||||
|
|
||||||
$OFS = "`r`n"
|
$OFS = "`r`n"
|
||||||
$scriptname = "winutil.ps1"
|
$scriptname = "winutil.ps1"
|
||||||
|
$workingdir = $PSScriptRoot
|
||||||
|
|
||||||
|
Push-Location
|
||||||
|
Set-Location $workingdir
|
||||||
|
|
||||||
# Variable to sync between runspaces
|
# Variable to sync between runspaces
|
||||||
$sync = [Hashtable]::Synchronized(@{})
|
$sync = [Hashtable]::Synchronized(@{})
|
||||||
$sync.PSScriptRoot = $PSScriptRoot
|
$sync.PSScriptRoot = $workingdir
|
||||||
$sync.configs = @{}
|
$sync.configs = @{}
|
||||||
|
|
||||||
function Update-Progress {
|
function Update-Progress {
|
||||||
@ -35,6 +45,16 @@ $header = @"
|
|||||||
"@
|
"@
|
||||||
|
|
||||||
|
|
||||||
|
Update-Progress "Pre-req: Running Preprocessor..." 0
|
||||||
|
|
||||||
|
# Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script
|
||||||
|
$preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1"
|
||||||
|
. $preprocessingFilePath
|
||||||
|
|
||||||
|
$excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe','.\.preprocessor_hashes.json')
|
||||||
|
$msg = "Pre-req: Code Formatting"
|
||||||
|
Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg
|
||||||
|
|
||||||
# Create the script in memory.
|
# Create the script in memory.
|
||||||
Update-Progress "Pre-req: Allocating Memory" 0
|
Update-Progress "Pre-req: Allocating Memory" 0
|
||||||
$script_content = [System.Collections.Generic.List[string]]::new()
|
$script_content = [System.Collections.Generic.List[string]]::new()
|
||||||
@ -43,101 +63,83 @@ Update-Progress "Adding: Header" 5
|
|||||||
$script_content.Add($header)
|
$script_content.Add($header)
|
||||||
|
|
||||||
Update-Progress "Adding: Version" 10
|
Update-Progress "Adding: Version" 10
|
||||||
$script_content.Add($(Get-Content .\scripts\start.ps1).replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)"))
|
$script_content.Add($(Get-Content "scripts\start.ps1").replace('#{replaceme}',"$(Get-Date -Format yy.MM.dd)"))
|
||||||
|
|
||||||
Update-Progress "Adding: Functions" 20
|
Update-Progress "Adding: Functions" 20
|
||||||
Get-ChildItem .\functions -Recurse -File | ForEach-Object {
|
Get-ChildItem "functions" -Recurse -File | ForEach-Object {
|
||||||
$script_content.Add($(Get-Content $psitem.FullName))
|
$script_content.Add($(Get-Content $psitem.FullName))
|
||||||
}
|
}
|
||||||
Update-Progress "Adding: Config *.json" 40
|
Update-Progress "Adding: Config *.json" 40
|
||||||
Get-ChildItem .\config | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
|
Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
|
||||||
|
$json = (Get-Content $psitem.FullName -Raw)
|
||||||
$json = (Get-Content $psitem.FullName).replace("'","''")
|
$jsonAsObject = $json | ConvertFrom-Json
|
||||||
|
|
||||||
# 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
|
# Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file
|
||||||
if ($psitem.Name -eq "applications.json") {
|
if ($psitem.Name -eq "applications.json") {
|
||||||
for ($i = 0; $i -lt $firstLevelJsonList.Count; $i += 1) {
|
foreach ($appEntryName in $jsonAsObject.PSObject.Properties.Name) {
|
||||||
$appEntryName = $firstLevelJsonList[$i]
|
|
||||||
$appEntryContent = $jsonAsObject.$appEntryName
|
$appEntryContent = $jsonAsObject.$appEntryName
|
||||||
# Remove the entire app entry, so we could add it later with a different name
|
|
||||||
$jsonAsObject.PSObject.Properties.Remove($appEntryName)
|
$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
|
$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
|
# Line 90 requires no whitespace inside the here-strings, to keep formatting of the JSON in the final script.
|
||||||
# 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 = @"
|
||||||
$json = ($jsonAsObject | convertto-json -Depth 3).replace('\r\n',"`r`n")
|
$($jsonAsObject | ConvertTo-Json -Depth 3)
|
||||||
|
"@
|
||||||
|
|
||||||
$sync.configs.$($psitem.BaseName) = $json | convertfrom-json
|
$sync.configs.$($psitem.BaseName) = $json | ConvertFrom-Json
|
||||||
$script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| convertfrom-json" ))
|
$script_content.Add($(Write-Output "`$sync.configs.$($psitem.BaseName) = @'`r`n$json`r`n'@ `| ConvertFrom-Json" ))
|
||||||
}
|
}
|
||||||
|
|
||||||
$xaml = (Get-Content .\xaml\inputXML.xaml).replace("'","''")
|
# Read the entire XAML file as a single string, preserving line breaks
|
||||||
|
$xaml = Get-Content "$workingdir\xaml\inputXML.xaml" -Raw
|
||||||
# Dot-source the Get-TabXaml function
|
|
||||||
. .\functions\private\Get-TabXaml.ps1
|
|
||||||
|
|
||||||
Update-Progress "Building: Xaml " 75
|
|
||||||
$appXamlContent = Get-TabXaml "applications" 5
|
|
||||||
$tweaksXamlContent = Get-TabXaml "tweaks"
|
|
||||||
$featuresXamlContent = Get-TabXaml "feature"
|
|
||||||
|
|
||||||
|
|
||||||
Update-Progress "Adding: Xaml " 90
|
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'"))
|
# Add the XAML content to $script_content using a here-string
|
||||||
|
$script_content.Add(@"
|
||||||
|
`$inputXML = @'
|
||||||
|
$xaml
|
||||||
|
'@
|
||||||
|
"@)
|
||||||
|
|
||||||
$script_content.Add($(Get-Content .\scripts\main.ps1))
|
$script_content.Add($(Get-Content "scripts\main.ps1"))
|
||||||
|
|
||||||
if ($Debug) {
|
if ($Debug) {
|
||||||
Update-Progress "Writing debug files" 95
|
Update-Progress "Writing debug files" 95
|
||||||
$appXamlContent | Out-File -FilePath ".\xaml\inputApp.xaml" -Encoding ascii
|
$appXamlContent | Out-File -FilePath "xaml\inputApp.xaml" -Encoding ascii
|
||||||
$tweaksXamlContent | Out-File -FilePath ".\xaml\inputTweaks.xaml" -Encoding ascii
|
$tweaksXamlContent | Out-File -FilePath "xaml\inputTweaks.xaml" -Encoding ascii
|
||||||
$featuresXamlContent | Out-File -FilePath ".\xaml\inputFeatures.xaml" -Encoding ascii
|
$featuresXamlContent | Out-File -FilePath "xaml\inputFeatures.xaml" -Encoding ascii
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Update-Progress "Removing temporary files" 99
|
Update-Progress "Removing temporary files" 99
|
||||||
Remove-Item ".\xaml\inputApp.xaml" -ErrorAction SilentlyContinue
|
Remove-Item "xaml\inputApp.xaml" -ErrorAction SilentlyContinue
|
||||||
Remove-Item ".\xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
|
Remove-Item "xaml\inputTweaks.xaml" -ErrorAction SilentlyContinue
|
||||||
Remove-Item ".\xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
|
Remove-Item "xaml\inputFeatures.xaml" -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
Set-Content -Path $scriptname -Value ($script_content -join "`r`n") -Encoding ascii
|
Set-Content -Path "$scriptname" -Value ($script_content -join "`r`n") -Encoding ascii
|
||||||
Write-Progress -Activity "Compiling" -Completed
|
Write-Progress -Activity "Compiling" -Completed
|
||||||
|
|
||||||
if ($run){
|
Update-Progress -Activity "Validating" -StatusMessage "Checking winutil.ps1 Syntax" -Percent 0
|
||||||
try {
|
try {
|
||||||
Start-Process -FilePath "pwsh" -ArgumentList ".\$scriptname"
|
Get-Command -Syntax .\winutil.ps1 | Out-Null
|
||||||
}
|
} catch {
|
||||||
catch {
|
Write-Warning "Syntax Validation for 'winutil.ps1' has failed"
|
||||||
Start-Process -FilePath "powershell" -ArgumentList ".\$scriptname"
|
Write-Host "$($Error[0])" -ForegroundColor Red
|
||||||
|
Pop-Location # Restore previous location before exiting...
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
Write-Progress -Activity "Validating" -Completed
|
||||||
|
|
||||||
|
if ($run) {
|
||||||
|
$script = "& '$workingdir\$scriptname' $Arguments"
|
||||||
|
|
||||||
|
$powershellcmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
|
||||||
|
$processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { $powershellcmd }
|
||||||
|
|
||||||
|
Start-Process $processCmd -ArgumentList "$powershellcmd -NoProfile -Command $script"
|
||||||
|
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
Pop-Location
|
||||||
|
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2022 Chris Titus
|
Copyright (c) 2022 CT Tech Group LLC
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
43
README.md
@ -3,28 +3,28 @@
|
|||||||
[](https://github.com/ChrisTitusTech/winutil/releases/latest)
|
[](https://github.com/ChrisTitusTech/winutil/releases/latest)
|
||||||

|

|
||||||
[](https://discord.gg/RUbZUZyByQ)
|
[](https://discord.gg/RUbZUZyByQ)
|
||||||
|
[](https://winutil.christitus.com/)
|
||||||
|
|
||||||
This utility is a compilation of Windows tasks I perform on each Windows system I use. It is meant to streamline *installs*, debloat with *tweaks*, troubleshoot with *config*, and fix Windows *updates*. I am extremely picky about any contributions to keep this project clean and efficient.
|
This utility is a compilation of Windows tasks I perform on each Windows system I use. It is meant to streamline *installs*, debloat with *tweaks*, troubleshoot with *config*, and fix Windows *updates*. I am extremely picky about any contributions to keep this project clean and efficient.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 💡 Usage
|
## 💡 Usage
|
||||||
|
|
||||||
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, run PowerShell as an administrator. Here are a few ways to do it:
|
||||||
|
|
||||||
1. **Right-Click Method:**
|
1. **Start menu Method:**
|
||||||
- Right-click on the start menu.
|
- Right-click on the start menu.
|
||||||
- Choose "Windows PowerShell (Admin)" (for Windows 10) or "Terminal (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.
|
||||||
- Type "PowerShell" or "Terminal" (for Windows 11).
|
- Type "PowerShell" or "Terminal" (for Windows 11).
|
||||||
- Press `Ctrl + Shift + Enter` to launch it with administrator privileges.
|
- Press `Ctrl + Shift + Enter` or Right-click and choose "Run as administrator" to launch it with administrator privileges.
|
||||||
|
|
||||||
|
|
||||||
### Launch Command
|
### Launch Command
|
||||||
|
|
||||||
#### Stable Branch
|
#### Stable Branch (Recommended)
|
||||||
|
|
||||||
```ps1
|
```ps1
|
||||||
irm "https://christitus.com/win" | iex
|
irm "https://christitus.com/win" | iex
|
||||||
@ -35,16 +35,41 @@ irm "https://christitus.com/win" | iex
|
|||||||
irm "https://christitus.com/windev" | iex
|
irm "https://christitus.com/windev" | iex
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have Issues, refer to [Known Issues](https://christitustech.github.io/winutil/KnownIssues/)
|
If you have Issues, refer to [Known Issues](https://winutil.christitus.com/knownissues/)
|
||||||
|
|
||||||
## 🎓 Documentation
|
## 🎓 Documentation
|
||||||
|
|
||||||
### [WinUtil Official Documentation](https://christitustech.github.io/winutil/)
|
> [!NOTE]
|
||||||
|
> To contribute to the documentation, please visit [WinUtil Docs Repo](https://github.com/Chris-Titus-Docs/winutil-docs) for more info.
|
||||||
|
|
||||||
|
### [WinUtil Official Documentation](https://winutil.christitus.com/)
|
||||||
|
|
||||||
### [YouTube Tutorial](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
|
### [YouTube Tutorial](https://www.youtube.com/watch?v=6UQZ5oQg8XA)
|
||||||
|
|
||||||
### [ChrisTitus.com Article](https://christitus.com/windows-tool/)
|
### [ChrisTitus.com Article](https://christitus.com/windows-tool/)
|
||||||
|
|
||||||
|
## 🛠️ Build & Develop
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Winutil is a relatively large script, so it's split into multiple files which're combined into a single `.ps1` file using a custom compiler. This makes maintaining the project a lot easiler.
|
||||||
|
|
||||||
|
Get a copy of the source code, this can be done using GitHub UI (`Code -> Download ZIP`), or by cloning (downloading) the repo using git.
|
||||||
|
|
||||||
|
If git is installed, run the following commands under a PowerShell window to clone and move into project's directory:
|
||||||
|
```ps1
|
||||||
|
git clone --depth 1 "https://github.com/ChrisTitusTech/winutil.git"
|
||||||
|
cd winutil
|
||||||
|
```
|
||||||
|
|
||||||
|
To build the project, run the Compile Script under a PowerShell window (admin permissions IS NOT required):
|
||||||
|
```ps1
|
||||||
|
.\Compile.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll see a new file named `winutil.ps1`, which's created by `Compile.ps1` script, now you can run it as admin and a new window will popup, enjoy your own compiled version of WinUtil :)
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> For more info on using WinUtil and how to develop for it, please consider reading [the Contribution Guidelines](https://winutil.christitus.com/contributing/), if you don't know where to start, or have questions, you can ask over on our [Discord Community Server](https://discord.gg/RUbZUZyByQ) and active project members will answer when they can.
|
||||||
|
|
||||||
## 💖 Support
|
## 💖 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 ⭐️!
|
||||||
@ -54,7 +79,7 @@ If you have Issues, refer to [Known Issues](https://christitustech.github.io/win
|
|||||||
|
|
||||||
These are the sponsors that help keep this project alive with monthly contributions.
|
These are the sponsors that help keep this project alive with monthly contributions.
|
||||||
|
|
||||||
<!-- sponsors --><a href="https://github.com/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/broganbranstetter"><img src="https://github.com/broganbranstetter.png" width="60px" alt="Brogan Branstetter" /></a><a href="https://github.com/zepled112"><img src="https://github.com/zepled112.png" width="60px" alt="wyatt" /></a><a href="https://github.com/TDWillingham"><img src="https://github.com/TDWillingham.png" width="60px" alt="MetalliDan28" /></a><a href="https://github.com/frankolivares"><img src="https://github.com/frankolivares.png" width="60px" alt="" /></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><!-- sponsors -->
|
<!-- sponsors --><a href="https://github.com/TriHydera"><img src="https://github.com/TriHydera.png" width="60px" alt="User avatar: TriHydera" /></a><a href="https://github.com/DelDongo"><img src="https://github.com/DelDongo.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/markamos"><img src="https://github.com/markamos.png" width="60px" alt="User avatar: Mark Amos" /></a><a href="https://github.com/dwelfusius"><img src="https://github.com/dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https://github.com/mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https://github.com/jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/robertsandrock"><img src="https://github.com/robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https://github.com/KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https://github.com/paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https://github.com/djones369.png" width="60px" alt="User avatar: Dave J. - WhamGeek" /></a><a href="https://github.com/anthonymendez"><img src="https://github.com/anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/FatBastard0"><img src="https://github.com/FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DursleyGuy"><img src="https://github.com/DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/realmuddy"><img src="https://github.com/realmuddy.png" width="60px" alt="User avatar: Phillip Waters" /></a><a href="https://github.com/quaszi"><img src="https://github.com/quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https://github.com/DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https://github.com/KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><a href="https://github.com/RoelCrabbe"><img src="https://github.com/RoelCrabbe.png" width="60px" alt="User avatar: Roel Crabbé" /></a><a href="https://github.com/Data-Syd"><img src="https://github.com/Data-Syd.png" width="60px" alt="User avatar: Data Syd" /></a><!-- sponsors -->
|
||||||
|
|
||||||
## 🏅 Thanks to all Contributors
|
## 🏅 Thanks to all Contributors
|
||||||
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
|
Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻.
|
||||||
|
16
Test-WingetInstall.ps1
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Import the function (adjust the path according to your setup)
|
||||||
|
. "./functions/private/Install-WinUtilWinget.ps1"
|
||||||
|
. "./functions/private/Test-WinUtilPackageManager.ps1"
|
||||||
|
|
||||||
|
# Set up Information stream to be visible
|
||||||
|
$InformationPreference = "Continue"
|
||||||
|
|
||||||
|
Write-Host "Starting Winget installation test..." -ForegroundColor Cyan
|
||||||
|
|
||||||
|
try {
|
||||||
|
Install-WinUtilWinget
|
||||||
|
} catch {
|
||||||
|
Write-Host "Error occurred during testing: $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
Write-Host "Stack Trace:" -ForegroundColor Red
|
||||||
|
$_.ScriptStackTrace
|
||||||
|
}
|
@ -85,15 +85,7 @@
|
|||||||
"content": "AnyDesk",
|
"content": "AnyDesk",
|
||||||
"description": "AnyDesk is a remote desktop software that enables users to access and control computers remotely. It is known for its fast connection and low latency.",
|
"description": "AnyDesk is a remote desktop software that enables users to access and control computers remotely. It is known for its fast connection and low latency.",
|
||||||
"link": "https://anydesk.com/",
|
"link": "https://anydesk.com/",
|
||||||
"winget": "AnyDeskSoftwareGmbH.AnyDesk"
|
"winget": "AnyDesk.AnyDesk"
|
||||||
},
|
|
||||||
"ATLauncher": {
|
|
||||||
"category": "Games",
|
|
||||||
"choco": "na",
|
|
||||||
"content": "ATLauncher",
|
|
||||||
"description": "ATLauncher is a Launcher for Minecraft which integrates multiple different ModPacks to allow you to download and install ModPacks easily and quickly.",
|
|
||||||
"link": "https://github.com/ATLauncher/ATLauncher",
|
|
||||||
"winget": "ATLauncher.ATLauncher"
|
|
||||||
},
|
},
|
||||||
"audacity": {
|
"audacity": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
@ -205,7 +197,7 @@
|
|||||||
"content": "Advanced Renamer",
|
"content": "Advanced Renamer",
|
||||||
"description": "Advanced Renamer is a program for renaming multiple files and folders at once. By configuring renaming methods the names can be manipulated in various ways.",
|
"description": "Advanced Renamer is a program for renaming multiple files and folders at once. By configuring renaming methods the names can be manipulated in various ways.",
|
||||||
"link": "https://www.advancedrenamer.com/",
|
"link": "https://www.advancedrenamer.com/",
|
||||||
"winget": "XP9MD3S1KFCPH1"
|
"winget": "HulubuluSoftware.AdvancedRenamer"
|
||||||
},
|
},
|
||||||
"calibre": {
|
"calibre": {
|
||||||
"category": "Document",
|
"category": "Document",
|
||||||
@ -255,14 +247,6 @@
|
|||||||
"link": "https://github.com/Hibbiki/chromium-win64",
|
"link": "https://github.com/Hibbiki/chromium-win64",
|
||||||
"winget": "Hibbiki.Chromium"
|
"winget": "Hibbiki.Chromium"
|
||||||
},
|
},
|
||||||
"arc": {
|
|
||||||
"category": "Browsers",
|
|
||||||
"choco": "na",
|
|
||||||
"content": "Arc",
|
|
||||||
"description": "Arc is a Chromium based browser, known for it's clean and modern design.",
|
|
||||||
"link": "https://arc.net/",
|
|
||||||
"winget": "TheBrowserCompany.Arc"
|
|
||||||
},
|
|
||||||
"clementine": {
|
"clementine": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "clementine",
|
"choco": "clementine",
|
||||||
@ -357,7 +341,7 @@
|
|||||||
"content": "Display Driver Uninstaller",
|
"content": "Display Driver Uninstaller",
|
||||||
"description": "Display Driver Uninstaller (DDU) is a tool for completely uninstalling graphics drivers from NVIDIA, AMD, and Intel. It is useful for troubleshooting graphics driver-related issues.",
|
"description": "Display Driver Uninstaller (DDU) is a tool for completely uninstalling graphics drivers from NVIDIA, AMD, and Intel. It is useful for troubleshooting graphics driver-related issues.",
|
||||||
"link": "https://www.wagnardsoft.com/display-driver-uninstaller-DDU-",
|
"link": "https://www.wagnardsoft.com/display-driver-uninstaller-DDU-",
|
||||||
"winget": "ddu"
|
"winget": "Wagnardsoft.DisplayDriverUninstaller"
|
||||||
},
|
},
|
||||||
"deluge": {
|
"deluge": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
@ -447,13 +431,21 @@
|
|||||||
"link": "https://dotnet.microsoft.com/download/dotnet/8.0",
|
"link": "https://dotnet.microsoft.com/download/dotnet/8.0",
|
||||||
"winget": "Microsoft.DotNet.DesktopRuntime.8"
|
"winget": "Microsoft.DotNet.DesktopRuntime.8"
|
||||||
},
|
},
|
||||||
|
"dotnet9": {
|
||||||
|
"category": "Microsoft Tools",
|
||||||
|
"choco": "dotnet-9.0-runtime",
|
||||||
|
"content": ".NET Desktop Runtime 9",
|
||||||
|
"description": ".NET Desktop Runtime 9 is a runtime environment required for running applications developed with .NET 9.",
|
||||||
|
"link": "https://dotnet.microsoft.com/download/dotnet/9.0",
|
||||||
|
"winget": "Microsoft.DotNet.DesktopRuntime.9"
|
||||||
|
},
|
||||||
"dmt": {
|
"dmt": {
|
||||||
"winget": "GNE.DualMonitorTools",
|
"winget": "GNE.DualMonitorTools",
|
||||||
"choco": "dual-monitor-tools",
|
"choco": "dual-monitor-tools",
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"content": "Dual Monitor Tools",
|
"content": "Dual Monitor Tools",
|
||||||
"link": "https://dualmonitortool.sourceforge.net/",
|
"link": "https://dualmonitortool.sourceforge.net/",
|
||||||
"description": "Dual Monitor Tools (DMT) is a FOSS app that customize handling multiple monitors and even lock the mouse on specific monitor. Useful for full screen games and apps that does not handle well a second monitor or helps the workflow."
|
"description": "Dual Monitor Tools (DMT) is a FOSS app that allows you to customize the handling of multiple monitors. Useful for fullscreen games and apps that handle a second monitor poorly and can improve your workflow."
|
||||||
},
|
},
|
||||||
"duplicati": {
|
"duplicati": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
@ -511,14 +503,6 @@
|
|||||||
"link": "https://www.epicgames.com/store/en-US/",
|
"link": "https://www.epicgames.com/store/en-US/",
|
||||||
"winget": "EpicGames.EpicGamesLauncher"
|
"winget": "EpicGames.EpicGamesLauncher"
|
||||||
},
|
},
|
||||||
"errorlookup": {
|
|
||||||
"category": "Utilities",
|
|
||||||
"choco": "na",
|
|
||||||
"content": "Windows Error Code Lookup",
|
|
||||||
"description": "ErrorLookup is a tool for looking up Windows error codes and their descriptions.",
|
|
||||||
"link": "https://github.com/HenryPP/ErrorLookup",
|
|
||||||
"winget": "Henry++.ErrorLookup"
|
|
||||||
},
|
|
||||||
"esearch": {
|
"esearch": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "everything",
|
"choco": "everything",
|
||||||
@ -535,14 +519,6 @@
|
|||||||
"link": "https://espanso.org/",
|
"link": "https://espanso.org/",
|
||||||
"winget": "Espanso.Espanso"
|
"winget": "Espanso.Espanso"
|
||||||
},
|
},
|
||||||
"etcher": {
|
|
||||||
"category": "Utilities",
|
|
||||||
"choco": "etcher",
|
|
||||||
"content": "Etcher USB Creator",
|
|
||||||
"description": "Etcher is a powerful tool for creating bootable USB drives with ease.",
|
|
||||||
"link": "https://www.balena.io/etcher/",
|
|
||||||
"winget": "Balena.Etcher"
|
|
||||||
},
|
|
||||||
"falkon": {
|
"falkon": {
|
||||||
"category": "Browsers",
|
"category": "Browsers",
|
||||||
"choco": "falkon",
|
"choco": "falkon",
|
||||||
@ -571,7 +547,7 @@
|
|||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "ffmpeg-full",
|
"choco": "ffmpeg-full",
|
||||||
"content": "FFmpeg (full)",
|
"content": "FFmpeg (full)",
|
||||||
"description": "FFmpeg is a powerful multimedia processing tool that enables users to convert, edit, and stream audio and video files with a vast range of codecs and formats.",
|
"description": "FFmpeg is a powerful multimedia processing tool that enables users to convert, edit, and stream audio and video files with a vast range of codecs and formats. | Note: FFmpeg can not be uninstalled using winget.",
|
||||||
"link": "https://ffmpeg.org/",
|
"link": "https://ffmpeg.org/",
|
||||||
"winget": "Gyan.FFmpeg"
|
"winget": "Gyan.FFmpeg"
|
||||||
},
|
},
|
||||||
@ -691,9 +667,9 @@
|
|||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "fxsound",
|
"choco": "fxsound",
|
||||||
"content": "FxSound",
|
"content": "FxSound",
|
||||||
"description": "FxSound is a cutting-edge audio enhancement software that elevates your listening experience across all media.",
|
"description": "FxSound is free open-source software to boost sound quality, volume, and bass. Including an equalizer, effects, and presets for customized audio.",
|
||||||
"link": "https://www.fxsound.com/",
|
"link": "https://www.fxsound.com/",
|
||||||
"winget": "FxSoundLLC.FxSound"
|
"winget": "FxSound.FxSound"
|
||||||
},
|
},
|
||||||
"fzf": {
|
"fzf": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
@ -717,7 +693,7 @@
|
|||||||
"content": "GIMP (Image Editor)",
|
"content": "GIMP (Image Editor)",
|
||||||
"description": "GIMP is a versatile open-source raster graphics editor used for tasks such as photo retouching, image editing, and image composition.",
|
"description": "GIMP is a versatile open-source raster graphics editor used for tasks such as photo retouching, image editing, and image composition.",
|
||||||
"link": "https://www.gimp.org/",
|
"link": "https://www.gimp.org/",
|
||||||
"winget": "GIMP.GIMP"
|
"winget": "GIMP.GIMP.3"
|
||||||
},
|
},
|
||||||
"git": {
|
"git": {
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
@ -727,6 +703,14 @@
|
|||||||
"link": "https://git-scm.com/",
|
"link": "https://git-scm.com/",
|
||||||
"winget": "Git.Git"
|
"winget": "Git.Git"
|
||||||
},
|
},
|
||||||
|
"gitbutler": {
|
||||||
|
"category": "Development",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Git Butler",
|
||||||
|
"description": "A Git client for simultaneous branches on top of your existing workflow.",
|
||||||
|
"link": "https://gitbutler.com/",
|
||||||
|
"winget": "GitButler.GitButler"
|
||||||
|
},
|
||||||
"gitextensions": {
|
"gitextensions": {
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"choco": "git;gitextensions",
|
"choco": "git;gitextensions",
|
||||||
@ -805,7 +789,7 @@
|
|||||||
"content": "Google Drive",
|
"content": "Google Drive",
|
||||||
"description": "File syncing across devices all tied to your google account",
|
"description": "File syncing across devices all tied to your google account",
|
||||||
"link": "https://www.google.com/drive/",
|
"link": "https://www.google.com/drive/",
|
||||||
"winget": "Google.Drive"
|
"winget": "Google.GoogleDrive"
|
||||||
},
|
},
|
||||||
"gpuz": {
|
"gpuz": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
@ -916,7 +900,7 @@
|
|||||||
"choco": "imgburn",
|
"choco": "imgburn",
|
||||||
"content": "ImgBurn",
|
"content": "ImgBurn",
|
||||||
"description": "ImgBurn is a lightweight CD, DVD, HD-DVD, and Blu-ray burning application with advanced features for creating and burning disc images.",
|
"description": "ImgBurn is a lightweight CD, DVD, HD-DVD, and Blu-ray burning application with advanced features for creating and burning disc images.",
|
||||||
"link": "http://www.imgburn.com/",
|
"link": "https://www.imgburn.com/",
|
||||||
"winget": "LIGHTNINGUK.ImgBurn"
|
"winget": "LIGHTNINGUK.ImgBurn"
|
||||||
},
|
},
|
||||||
"inkscape": {
|
"inkscape": {
|
||||||
@ -988,7 +972,7 @@
|
|||||||
"choco": "jdownloader",
|
"choco": "jdownloader",
|
||||||
"content": "JDownloader",
|
"content": "JDownloader",
|
||||||
"description": "JDownloader is a feature-rich download manager with support for various file hosting services.",
|
"description": "JDownloader is a feature-rich download manager with support for various file hosting services.",
|
||||||
"link": "http://jdownloader.org/",
|
"link": "https://jdownloader.org/",
|
||||||
"winget": "AppWork.JDownloader"
|
"winget": "AppWork.JDownloader"
|
||||||
},
|
},
|
||||||
"jellyfinmediaplayer": {
|
"jellyfinmediaplayer": {
|
||||||
@ -1215,12 +1199,12 @@
|
|||||||
"link": "https://motrix.app/",
|
"link": "https://motrix.app/",
|
||||||
"winget": "agalwood.Motrix"
|
"winget": "agalwood.Motrix"
|
||||||
},
|
},
|
||||||
"mpc": {
|
"mpchc": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
"choco": "mpc-hc",
|
"choco": "mpc-hc-clsid2",
|
||||||
"content": "Media Player Classic (Video Player)",
|
"content": "Media Player Classic - Home Cinema",
|
||||||
"description": "Media Player Classic is a lightweight, open-source media player that supports a wide range of audio and video formats. It includes features like customizable toolbars and support for subtitles.",
|
"description": "Media Player Classic - Home Cinema (MPC-HC) is a free and open-source video and audio player for Windows. MPC-HC is based on the original Guliverkli project and contains many additional features and bug fixes.",
|
||||||
"link": "https://mpc-hc.org/",
|
"link": "https://github.com/clsid2/mpc-hc/",
|
||||||
"winget": "clsid2.mpc-hc"
|
"winget": "clsid2.mpc-hc"
|
||||||
},
|
},
|
||||||
"mremoteng": {
|
"mremoteng": {
|
||||||
@ -1380,7 +1364,7 @@
|
|||||||
"choco": "na",
|
"choco": "na",
|
||||||
"content": "nGlide (3dfx compatibility)",
|
"content": "nGlide (3dfx compatibility)",
|
||||||
"description": "nGlide is a 3Dfx Voodoo Glide wrapper. It allows you to play games that use Glide API on modern graphics cards without the need for a 3Dfx Voodoo graphics card.",
|
"description": "nGlide is a 3Dfx Voodoo Glide wrapper. It allows you to play games that use Glide API on modern graphics cards without the need for a 3Dfx Voodoo graphics card.",
|
||||||
"link": "http://www.zeus-software.com/downloads/nglide",
|
"link": "https://www.zeus-software.com/downloads/nglide",
|
||||||
"winget": "ZeusSoftware.nGlide"
|
"winget": "ZeusSoftware.nGlide"
|
||||||
},
|
},
|
||||||
"nmap": {
|
"nmap": {
|
||||||
@ -1511,14 +1495,6 @@
|
|||||||
"link": "https://github.com/namazso/OpenHashTab/",
|
"link": "https://github.com/namazso/OpenHashTab/",
|
||||||
"winget": "namazso.OpenHashTab"
|
"winget": "namazso.OpenHashTab"
|
||||||
},
|
},
|
||||||
"openoffice": {
|
|
||||||
"category": "Document",
|
|
||||||
"choco": "openoffice",
|
|
||||||
"content": "Apache OpenOffice",
|
|
||||||
"description": "Apache OpenOffice is an open-source office software suite for word processing, spreadsheets, presentations, and more.",
|
|
||||||
"link": "https://www.openoffice.org/",
|
|
||||||
"winget": "Apache.OpenOffice"
|
|
||||||
},
|
|
||||||
"openrgb": {
|
"openrgb": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "openrgb",
|
"choco": "openrgb",
|
||||||
@ -1699,7 +1675,7 @@
|
|||||||
"category": "Games",
|
"category": "Games",
|
||||||
"choco": "prismlauncher",
|
"choco": "prismlauncher",
|
||||||
"content": "Prism Launcher",
|
"content": "Prism Launcher",
|
||||||
"description": "Prism Launcher is a game launcher and manager designed to provide a clean and intuitive interface for organizing and launching your games.",
|
"description": "Prism Launcher is an Open Source Minecraft launcher with the ability to manage multiple instances, accounts and mods.",
|
||||||
"link": "https://prismlauncher.org/",
|
"link": "https://prismlauncher.org/",
|
||||||
"winget": "PrismLauncher.PrismLauncher"
|
"winget": "PrismLauncher.PrismLauncher"
|
||||||
},
|
},
|
||||||
@ -1879,14 +1855,6 @@
|
|||||||
"link": "https://sagethumbs.en.lo4d.com/windows",
|
"link": "https://sagethumbs.en.lo4d.com/windows",
|
||||||
"winget": "CherubicSoftware.SageThumbs"
|
"winget": "CherubicSoftware.SageThumbs"
|
||||||
},
|
},
|
||||||
"samsungmagician": {
|
|
||||||
"category": "Utilities",
|
|
||||||
"choco": "samsung-magician",
|
|
||||||
"content": "Samsung Magician",
|
|
||||||
"description": "Samsung Magician is a utility for managing and optimizing Samsung SSDs.",
|
|
||||||
"link": "https://semiconductor.samsung.com/consumer-storage/magician/",
|
|
||||||
"winget": "Samsung.SamsungMagician"
|
|
||||||
},
|
|
||||||
"sandboxie": {
|
"sandboxie": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "sandboxie",
|
"choco": "sandboxie",
|
||||||
@ -1900,7 +1868,7 @@
|
|||||||
"choco": "sdio",
|
"choco": "sdio",
|
||||||
"content": "Snappy Driver Installer Origin",
|
"content": "Snappy Driver Installer Origin",
|
||||||
"description": "Snappy Driver Installer Origin is a free and open-source driver updater with a vast driver database for Windows.",
|
"description": "Snappy Driver Installer Origin is a free and open-source driver updater with a vast driver database for Windows.",
|
||||||
"link": "https://sourceforge.net/projects/snappy-driver-installer-origin",
|
"link": "https://www.glenn.delahoy.com/snappy-driver-installer-origin/",
|
||||||
"winget": "GlennDelahoy.SnappyDriverInstallerOrigin"
|
"winget": "GlennDelahoy.SnappyDriverInstallerOrigin"
|
||||||
},
|
},
|
||||||
"session": {
|
"session": {
|
||||||
@ -1967,14 +1935,6 @@
|
|||||||
"link": "https://github.com/henrypp/simplewall",
|
"link": "https://github.com/henrypp/simplewall",
|
||||||
"winget": "Henry++.simplewall"
|
"winget": "Henry++.simplewall"
|
||||||
},
|
},
|
||||||
"skype": {
|
|
||||||
"category": "Communications",
|
|
||||||
"choco": "skype",
|
|
||||||
"content": "Skype",
|
|
||||||
"description": "Skype is a widely used communication platform offering video calls, voice calls, and instant messaging services.",
|
|
||||||
"link": "https://www.skype.com/",
|
|
||||||
"winget": "Microsoft.Skype"
|
|
||||||
},
|
|
||||||
"slack": {
|
"slack": {
|
||||||
"category": "Communications",
|
"category": "Communications",
|
||||||
"choco": "slack",
|
"choco": "slack",
|
||||||
@ -1999,14 +1959,6 @@
|
|||||||
"link": "http://www.uderzo.it/main_products/space_sniffer/",
|
"link": "http://www.uderzo.it/main_products/space_sniffer/",
|
||||||
"winget": "UderzoSoftware.SpaceSniffer"
|
"winget": "UderzoSoftware.SpaceSniffer"
|
||||||
},
|
},
|
||||||
"spotube": {
|
|
||||||
"category": "Multimedia Tools",
|
|
||||||
"choco": "spotube",
|
|
||||||
"content": "Spotube",
|
|
||||||
"description": "Open source Spotify client that doesn't require Premium nor uses Electron! Available for both desktop & mobile! ",
|
|
||||||
"link": "https://github.com/KRTirtho/spotube",
|
|
||||||
"winget": "KRTirtho.Spotube"
|
|
||||||
},
|
|
||||||
"starship": {
|
"starship": {
|
||||||
"category": "Development",
|
"category": "Development",
|
||||||
"choco": "starship",
|
"choco": "starship",
|
||||||
@ -2204,7 +2156,7 @@
|
|||||||
"choco": "na",
|
"choco": "na",
|
||||||
"content": "Thorium Browser AVX2",
|
"content": "Thorium Browser AVX2",
|
||||||
"description": "Browser built for speed over vanilla chromium. It is built with AVX2 optimizations and is the fastest browser on the market.",
|
"description": "Browser built for speed over vanilla chromium. It is built with AVX2 optimizations and is the fastest browser on the market.",
|
||||||
"link": "http://thorium.rocks/",
|
"link": "https://thorium.rocks/",
|
||||||
"winget": "Alex313031.Thorium.AVX2"
|
"winget": "Alex313031.Thorium.AVX2"
|
||||||
},
|
},
|
||||||
"thunderbird": {
|
"thunderbird": {
|
||||||
@ -2341,7 +2293,7 @@
|
|||||||
"content": "Viber",
|
"content": "Viber",
|
||||||
"description": "Viber is a free messaging and calling app with features like group chats, video calls, and more.",
|
"description": "Viber is a free messaging and calling app with features like group chats, video calls, and more.",
|
||||||
"link": "https://www.viber.com/",
|
"link": "https://www.viber.com/",
|
||||||
"winget": "Viber.Viber"
|
"winget": "Rakuten.Viber"
|
||||||
},
|
},
|
||||||
"videomass": {
|
"videomass": {
|
||||||
"category": "Multimedia Tools",
|
"category": "Multimedia Tools",
|
||||||
@ -2458,10 +2410,10 @@
|
|||||||
"wingetui": {
|
"wingetui": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "wingetui",
|
"choco": "wingetui",
|
||||||
"content": "UnigetUI",
|
"content": "UniGetUI",
|
||||||
"description": "WingetUI is a graphical user interface for Microsoft's Windows Package Manager (winget).",
|
"description": "UniGetUI is a GUI for Winget, Chocolatey, and other Windows CLI package managers.",
|
||||||
"link": "https://www.marticliment.com/wingetui/",
|
"link": "https://www.marticliment.com/wingetui/",
|
||||||
"winget": "SomePythonThings.WingetUIStore"
|
"winget": "MartiCliment.UniGetUI"
|
||||||
},
|
},
|
||||||
"winmerge": {
|
"winmerge": {
|
||||||
"category": "Document",
|
"category": "Document",
|
||||||
@ -2863,14 +2815,6 @@
|
|||||||
"link": "https://www.kicad.org/",
|
"link": "https://www.kicad.org/",
|
||||||
"winget": "KiCad.KiCad"
|
"winget": "KiCad.KiCad"
|
||||||
},
|
},
|
||||||
"FormatFactory": {
|
|
||||||
"category": "Utilities",
|
|
||||||
"choco": "formatfactory",
|
|
||||||
"content": "Format Factory",
|
|
||||||
"description":"FormatFactory is an ad-supported freeware multimedia converter that can convert video, audio, and picture files. It is also capable of ripping DVDs and CDs to other file formats, as well as creating .iso images. It can also join multiple video files together into one.",
|
|
||||||
"link": "http://www.pcfreetime.com/formatfactory/",
|
|
||||||
"winget": "na"
|
|
||||||
},
|
|
||||||
"dropox": {
|
"dropox": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "na",
|
"choco": "na",
|
||||||
@ -2883,7 +2827,7 @@
|
|||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
"choco": "ofgb",
|
"choco": "ofgb",
|
||||||
"content": "OFGB (Oh Frick Go Back)",
|
"content": "OFGB (Oh Frick Go Back)",
|
||||||
"description":"GUI Tool To Removes Ads From Various Places Around Windows 11",
|
"description":"GUI Tool to remove ads from various places around Windows 11",
|
||||||
"link": "https://github.com/xM4ddy/OFGB",
|
"link": "https://github.com/xM4ddy/OFGB",
|
||||||
"winget": "xM4ddy.OFGB"
|
"winget": "xM4ddy.OFGB"
|
||||||
},
|
},
|
||||||
@ -2942,5 +2886,13 @@
|
|||||||
"description": "Fork - a fast and friendly git client.",
|
"description": "Fork - a fast and friendly git client.",
|
||||||
"link": "https://git-fork.com/",
|
"link": "https://git-fork.com/",
|
||||||
"winget": "Fork.Fork"
|
"winget": "Fork.Fork"
|
||||||
|
},
|
||||||
|
"ZenBrowser": {
|
||||||
|
"category": "Browsers",
|
||||||
|
"choco": "na",
|
||||||
|
"content": "Zen Browser",
|
||||||
|
"description": "The modern, privacy-focused, performance-driven browser built on Firefox",
|
||||||
|
"link": "https://zen-browser.app/",
|
||||||
|
"winget": "Zen-Team.Zen-Browser"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
62
config/appnavigation.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"WPFInstall": {
|
||||||
|
"Content": "Install/Upgrade Applications",
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "1",
|
||||||
|
"Description": "Install or upgrade the selected applications"
|
||||||
|
},
|
||||||
|
"WPFUninstall": {
|
||||||
|
"Content": "Uninstall Applications",
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "2",
|
||||||
|
"Description": "Uninstall the selected applications"
|
||||||
|
},
|
||||||
|
"WPFInstallUpgrade": {
|
||||||
|
"Content": "Upgrade all Applications",
|
||||||
|
"Category": "____Actions",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "3",
|
||||||
|
"Description": "Upgrade all applications to the latest version"
|
||||||
|
},
|
||||||
|
"WingetRadioButton": {
|
||||||
|
"Content": "Winget",
|
||||||
|
"Category": "__Package Manager",
|
||||||
|
"Type": "RadioButton",
|
||||||
|
"GroupName": "PackageManagerGroup",
|
||||||
|
"Checked": true,
|
||||||
|
"Order": "1",
|
||||||
|
"Description": "Use Winget for package management"
|
||||||
|
},
|
||||||
|
"ChocoRadioButton": {
|
||||||
|
"Content": "Chocolatey",
|
||||||
|
"Category": "__Package Manager",
|
||||||
|
"Type": "RadioButton",
|
||||||
|
"GroupName": "PackageManagerGroup",
|
||||||
|
"Checked": false,
|
||||||
|
"Order": "2",
|
||||||
|
"Description": "Use Chocolatey for package management"
|
||||||
|
},
|
||||||
|
"WPFClearInstallSelection": {
|
||||||
|
"Content": "Clear Selection",
|
||||||
|
"Category": "__Selection",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "1",
|
||||||
|
"Description": "Clear the selection of applications"
|
||||||
|
},
|
||||||
|
"WPFGetInstalled": {
|
||||||
|
"Content": "Get Installed",
|
||||||
|
"Category": "__Selection",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "2",
|
||||||
|
"Description": "Show installed applications"
|
||||||
|
},
|
||||||
|
"WPFselectedAppsButton": {
|
||||||
|
"Content": "Selected Apps: 0",
|
||||||
|
"Category": "__Selection",
|
||||||
|
"Type": "Button",
|
||||||
|
"Order": "3",
|
||||||
|
"Description": "Show the selected applications"
|
||||||
|
}
|
||||||
|
}
|
442
config/autounattend.xml
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
|
||||||
|
<!--https://schneegans.de/windows/unattend-generator/?LanguageMode=Unattended&UILanguage=en-US&Locale=en-US&Keyboard=00000409&GeoLocation=244&ProcessorArchitecture=amd64&BypassRequirementsCheck=true&BypassNetworkCheck=true&ComputerNameMode=Random&TimeZoneMode=Implicit&PartitionMode=Interactive&WindowsEditionMode=Unattended&WindowsEdition=pro&UserAccountMode=Unattended&AccountName0=User&AccountPassword0=&AccountGroup0=Administrators&AccountName1=&AccountName2=&AccountName3=&AccountName4=&AutoLogonMode=Own&PasswordExpirationMode=Unlimited&LockoutMode=Default&HideFiles=Hidden&DisableWidgets=true&ClassicContextMenu=true&DisableFastStartup=true&EnableLongPaths=true&DisableAppSuggestions=true&PreventDeviceEncryption=true&WifiMode=Skip&ExpressSettings=DisableAll&Remove3DViewer=true&RemoveBingSearch=true&RemoveCamera=true&RemoveClipchamp=true&RemoveClock=true&RemoveCopilot=true&RemoveCortana=true&RemoveDevHome=true&RemoveFamily=true&RemoveFeedbackHub=true&RemoveGetHelp=true&RemoveInternetExplorer=true&RemoveMailCalendar=true&RemoveMaps=true&RemoveMathInputPanel=true&RemoveZuneVideo=true&RemoveNews=true&RemoveNotepad=true&RemoveOffice365=true&RemoveOneDrive=true&RemoveOneNote=true&RemoveOpenSSHClient=true&RemoveOutlook=true&RemovePaint3D=true&RemovePeople=true&RemovePowerAutomate=true&RemoveQuickAssist=true&RemoveSkype=true&RemoveSolitaire=true&RemoveStepsRecorder=true&RemoveStickyNotes=true&RemoveTeams=true&RemoveGetStarted=true&RemoveToDo=true&RemoveVoiceRecorder=true&RemoveWeather=true&RemoveWindowsMediaPlayer=true&RemoveZuneMusic=true&RemoveWordPad=true&WdacMode=Skip-->
|
||||||
|
<settings pass="offlineServicing"></settings>
|
||||||
|
<settings pass="windowsPE">
|
||||||
|
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
<SetupUILanguage>
|
||||||
|
<UILanguage>en-US</UILanguage>
|
||||||
|
</SetupUILanguage>
|
||||||
|
<InputLocale>0409:00000409</InputLocale>
|
||||||
|
<SystemLocale>en-US</SystemLocale>
|
||||||
|
<UILanguage>en-US</UILanguage>
|
||||||
|
<UserLocale>en-US</UserLocale>
|
||||||
|
</component>
|
||||||
|
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
<UserData>
|
||||||
|
<ProductKey>
|
||||||
|
<Key>VK7JG-NPHTM-C97JM-9MPGT-3V66T</Key>
|
||||||
|
</ProductKey>
|
||||||
|
<AcceptEula>true</AcceptEula>
|
||||||
|
</UserData>
|
||||||
|
<RunSynchronous>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v BypassTPMCheck /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v BypassSecureBootCheck /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\Setup\LabConfig" /v BypassRAMCheck /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
</RunSynchronous>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
<settings pass="generalize"></settings>
|
||||||
|
<settings pass="specialize">
|
||||||
|
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
<RunSynchronous>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "UninstallCopilot" /t REG_SZ /d "powershell.exe -NoProfile -Command \"Get-AppxPackage -Name 'Microsoft.Windows.Ai.Copilot.Provider' | Remove-AppxPackage;\"" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>4</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot" /v TurnOffWindowsCopilot /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>5</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>6</Order>
|
||||||
|
<Path>reg.exe delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>7</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>8</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Notepad" /v ShowStoreBanner /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>9</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>10</Order>
|
||||||
|
<Path>cmd.exe /c "del "C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk""</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>11</Order>
|
||||||
|
<Path>cmd.exe /c "del "C:\Windows\System32\OneDriveSetup.exe""</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>12</Order>
|
||||||
|
<Path>cmd.exe /c "del "C:\Windows\SysWOW64\OneDriveSetup.exe""</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>13</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>14</Order>
|
||||||
|
<Path>reg.exe delete "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Run" /v OneDriveSetup /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>15</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>16</Order>
|
||||||
|
<Path>reg.exe delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>17</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v ConfigureChatAutoInstall /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>18</Order>
|
||||||
|
<Path>powershell.exe -NoProfile -Command "$xml = [xml]::new(); $xml.Load('C:\Windows\Panther\unattend.xml'); $sb = [scriptblock]::Create( $xml.unattend.Extensions.ExtractScript ); Invoke-Command -ScriptBlock $sb -ArgumentList $xml;"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>19</Order>
|
||||||
|
<Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\Microwin-RemovePackages.ps1' -Raw | Invoke-Expression;"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>20</Order>
|
||||||
|
<Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\remove-caps.ps1' -Raw | Invoke-Expression;"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>21</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>22</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_ProviderSet /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>23</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_WinningProvider /t REG_SZ /d B5292708-1619-419B-9923-E5D9F3925E71 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>24</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>25</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins_LastWrite /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>26</Order>
|
||||||
|
<Path>net.exe accounts /maxpwage:UNLIMITED</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>27</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>28</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>29</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>30</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>31</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "ContentDeliveryAllowed" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>32</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "FeatureManagementEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>33</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OEMPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>34</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>35</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEverEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>36</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>37</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SoftLandingEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>38</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContentEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>39</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-310093Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>40</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338387Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>41</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338388Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>42</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338389Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>43</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>44</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353698Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>45</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SystemPaneSuggestionsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>46</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>47</Order>
|
||||||
|
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>48</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\BitLocker" /v "PreventDeviceEncryption" /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>49</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>50</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "ClassicContextMenu" /t REG_SZ /d "reg.exe add \"HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32\" /ve /f" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>51</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
</RunSynchronous>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
<settings pass="auditSystem"></settings>
|
||||||
|
<settings pass="auditUser"></settings>
|
||||||
|
<settings pass="oobeSystem">
|
||||||
|
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
<InputLocale>0409:00000409</InputLocale>
|
||||||
|
<SystemLocale>en-US</SystemLocale>
|
||||||
|
<UILanguage>en-US</UILanguage>
|
||||||
|
<UserLocale>en-US</UserLocale>
|
||||||
|
</component>
|
||||||
|
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
<UserAccounts>
|
||||||
|
<LocalAccounts>
|
||||||
|
<LocalAccount wcm:action="add">
|
||||||
|
<Name>User</Name>
|
||||||
|
<Group>Administrators</Group>
|
||||||
|
<Password>
|
||||||
|
<Value></Value>
|
||||||
|
<PlainText>true</PlainText>
|
||||||
|
</Password>
|
||||||
|
</LocalAccount>
|
||||||
|
</LocalAccounts>
|
||||||
|
</UserAccounts>
|
||||||
|
<AutoLogon>
|
||||||
|
<Username>User</Username>
|
||||||
|
<Enabled>true</Enabled>
|
||||||
|
<LogonCount>1</LogonCount>
|
||||||
|
<Password>
|
||||||
|
<Value></Value>
|
||||||
|
<PlainText>true</PlainText>
|
||||||
|
</Password>
|
||||||
|
</AutoLogon>
|
||||||
|
<OOBE>
|
||||||
|
<ProtectYourPC>3</ProtectYourPC>
|
||||||
|
<HideEULAPage>true</HideEULAPage>
|
||||||
|
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||||
|
</OOBE>
|
||||||
|
<FirstLogonCommands>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
</SynchronousCommand>
|
||||||
|
</FirstLogonCommands>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
<Extensions xmlns="https://schneegans.de/windows/unattend-generator/">
|
||||||
|
<ExtractScript>
|
||||||
|
param(
|
||||||
|
[xml]$Document
|
||||||
|
);
|
||||||
|
|
||||||
|
$scriptsDir = 'C:\Windows\Setup\Scripts\';
|
||||||
|
foreach( $file in $Document.unattend.Extensions.File ) {
|
||||||
|
$path = [System.Environment]::ExpandEnvironmentVariables(
|
||||||
|
$file.GetAttribute( 'path' )
|
||||||
|
);
|
||||||
|
if( $path.StartsWith( $scriptsDir ) ) {
|
||||||
|
mkdir -Path $scriptsDir -ErrorAction 'SilentlyContinue';
|
||||||
|
}
|
||||||
|
$encoding = switch( [System.IO.Path]::GetExtension( $path ) ) {
|
||||||
|
{ $_ -in '.ps1', '.xml' } { [System.Text.Encoding]::UTF8; }
|
||||||
|
{ $_ -in '.reg', '.vbs', '.js' } { [System.Text.UnicodeEncoding]::new( $false, $true ); }
|
||||||
|
default { [System.Text.Encoding]::Default; }
|
||||||
|
};
|
||||||
|
[System.IO.File]::WriteAllBytes( $path, ( $encoding.GetPreamble() + $encoding.GetBytes( $file.InnerText.Trim() ) ) );
|
||||||
|
}
|
||||||
|
</ExtractScript>
|
||||||
|
<File path="C:\Windows\Temp\Microwin-RemovePackages.ps1">
|
||||||
|
$selectors = @(
|
||||||
|
'Microsoft.Microsoft3DViewer';
|
||||||
|
'Microsoft.BingSearch';
|
||||||
|
'Microsoft.WindowsCamera';
|
||||||
|
'Clipchamp.Clipchamp';
|
||||||
|
'Microsoft.WindowsAlarms';
|
||||||
|
'Microsoft.549981C3F5F10';
|
||||||
|
'Microsoft.Windows.DevHome';
|
||||||
|
'MicrosoftCorporationII.MicrosoftFamily';
|
||||||
|
'Microsoft.WindowsFeedbackHub';
|
||||||
|
'Microsoft.GetHelp';
|
||||||
|
'Microsoft.Getstarted';
|
||||||
|
'microsoft.windowscommunicationsapps';
|
||||||
|
'Microsoft.WindowsMaps';
|
||||||
|
'Microsoft.BingNews';
|
||||||
|
'Microsoft.WindowsNotepad';
|
||||||
|
'Microsoft.MicrosoftOfficeHub';
|
||||||
|
'Microsoft.Office.OneNote';
|
||||||
|
'Microsoft.OutlookForWindows';
|
||||||
|
'Microsoft.MSPaint';
|
||||||
|
'Microsoft.People';
|
||||||
|
'Microsoft.PowerAutomateDesktop';
|
||||||
|
'MicrosoftCorporationII.QuickAssist';
|
||||||
|
'Microsoft.SkypeApp';
|
||||||
|
'Microsoft.MicrosoftSolitaireCollection';
|
||||||
|
'Microsoft.MicrosoftStickyNotes';
|
||||||
|
'MSTeams';
|
||||||
|
'Microsoft.Todos';
|
||||||
|
'Microsoft.WindowsSoundRecorder';
|
||||||
|
'Microsoft.BingWeather';
|
||||||
|
'Microsoft.ZuneMusic';
|
||||||
|
'Microsoft.ZuneVideo';
|
||||||
|
);
|
||||||
|
$getCommand = { Get-AppxProvisionedPackage -Online; };
|
||||||
|
$filterCommand = { $_.DisplayName -eq $selector; };
|
||||||
|
$removeCommand = {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter( Mandatory, ValueFromPipeline )]
|
||||||
|
$InputObject
|
||||||
|
);
|
||||||
|
process {
|
||||||
|
$InputObject | Remove-AppxProvisionedPackage -AllUsers -Online -ErrorAction 'Continue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$type = 'Package';
|
||||||
|
$logfile = 'C:\Windows\Temp\Microwin-RemovePackages.log';
|
||||||
|
& {
|
||||||
|
$installed = & $getCommand;
|
||||||
|
foreach( $selector in $selectors ) {
|
||||||
|
$result = [ordered] @{
|
||||||
|
Selector = $selector;
|
||||||
|
};
|
||||||
|
$found = $installed | Where-Object -FilterScript $filterCommand;
|
||||||
|
if( $found ) {
|
||||||
|
$result.Output = $found | & $removeCommand;
|
||||||
|
if( $? ) {
|
||||||
|
$result.Message = "$type removed.";
|
||||||
|
} else {
|
||||||
|
$result.Message = "$type not removed.";
|
||||||
|
$result.Error = $Error[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result.Message = "$type not installed.";
|
||||||
|
}
|
||||||
|
$result | ConvertTo-Json -Depth 3 -Compress;
|
||||||
|
}
|
||||||
|
} *>&1 >> $logfile;
|
||||||
|
</File>
|
||||||
|
<File path="C:\Windows\Temp\remove-caps.ps1">
|
||||||
|
$selectors = @(
|
||||||
|
'Browser.InternetExplorer';
|
||||||
|
'MathRecognizer';
|
||||||
|
'OpenSSH.Client';
|
||||||
|
'App.Support.QuickAssist';
|
||||||
|
'App.StepsRecorder';
|
||||||
|
'Media.WindowsMediaPlayer';
|
||||||
|
'Microsoft.Windows.WordPad';
|
||||||
|
);
|
||||||
|
$getCommand = { Get-WindowsCapability -Online; };
|
||||||
|
$filterCommand = { ($_.Name -split '~')[0] -eq $selector; };
|
||||||
|
$removeCommand = {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter( Mandatory, ValueFromPipeline )]
|
||||||
|
$InputObject
|
||||||
|
);
|
||||||
|
process {
|
||||||
|
$InputObject | Remove-WindowsCapability -Online -ErrorAction 'Continue';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$type = 'Capability';
|
||||||
|
$logfile = 'C:\Windows\Temp\remove-caps.log';
|
||||||
|
& {
|
||||||
|
$installed = & $getCommand;
|
||||||
|
foreach( $selector in $selectors ) {
|
||||||
|
$result = [ordered] @{
|
||||||
|
Selector = $selector;
|
||||||
|
};
|
||||||
|
$found = $installed | Where-Object -FilterScript $filterCommand;
|
||||||
|
if( $found ) {
|
||||||
|
$result.Output = $found | & $removeCommand;
|
||||||
|
if( $? ) {
|
||||||
|
$result.Message = "$type removed.";
|
||||||
|
} else {
|
||||||
|
$result.Message = "$type not removed.";
|
||||||
|
$result.Error = $Error[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result.Message = "$type not installed.";
|
||||||
|
}
|
||||||
|
$result | ConvertTo-Json -Depth 3 -Compress;
|
||||||
|
}
|
||||||
|
} *>&1 >> $logfile;
|
||||||
|
</File>
|
||||||
|
<File path="C:\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml"><![CDATA[
|
||||||
|
<LayoutModificationTemplate Version="1" xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification">
|
||||||
|
<LayoutOptions StartTileGroupCellWidth="6" />
|
||||||
|
<DefaultLayoutOverride>
|
||||||
|
<StartLayoutCollection>
|
||||||
|
<StartLayout GroupCellWidth="6" xmlns="http://schemas.microsoft.com/Start/2014/FullDefaultLayout" />
|
||||||
|
</StartLayoutCollection>
|
||||||
|
</DefaultLayoutOverride>
|
||||||
|
</LayoutModificationTemplate>
|
||||||
|
]]></File>
|
||||||
|
</Extensions>
|
||||||
|
</unattend>
|
@ -46,5 +46,23 @@
|
|||||||
"Secondary": "94.140.15.16",
|
"Secondary": "94.140.15.16",
|
||||||
"Primary6": "2a10:50c0::bad1:ff",
|
"Primary6": "2a10:50c0::bad1:ff",
|
||||||
"Secondary6": "2a10:50c0::bad2:ff"
|
"Secondary6": "2a10:50c0::bad2:ff"
|
||||||
|
},
|
||||||
|
"dns0.eu_Open":{
|
||||||
|
"Primary": "193.110.81.254",
|
||||||
|
"Secondary": "185.253.5.254",
|
||||||
|
"Primary6": "2a0f:fc80::ffff",
|
||||||
|
"Secondary6": "2a0f:fc81::ffff"
|
||||||
|
},
|
||||||
|
"dns0.eu_ZERO":{
|
||||||
|
"Primary": "193.110.81.9",
|
||||||
|
"Secondary": "185.253.5.9",
|
||||||
|
"Primary6": "2a0f:fc80::9",
|
||||||
|
"Secondary6": "2a0f:fc81::9"
|
||||||
|
},
|
||||||
|
"dns0.eu_KIDS":{
|
||||||
|
"Primary": "193.110.81.1",
|
||||||
|
"Secondary": "185.253.5.1",
|
||||||
|
"Primary6": "2a0f:fc80::1",
|
||||||
|
"Secondary6": "2a0f:fc81::1"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,9 +9,8 @@
|
|||||||
"NetFx4-AdvSrvs",
|
"NetFx4-AdvSrvs",
|
||||||
"NetFx3"
|
"NetFx3"
|
||||||
],
|
],
|
||||||
"InvokeScript": [
|
"InvokeScript": [],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/dotnet"
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"WPFFeatureshyperv": {
|
"WPFFeatureshyperv": {
|
||||||
"Content": "HyperV Virtualization",
|
"Content": "HyperV Virtualization",
|
||||||
@ -31,7 +30,8 @@
|
|||||||
],
|
],
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /set hypervisorschedulertype classic' -Wait"
|
"Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /set hypervisorschedulertype classic' -Wait"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/hyperv"
|
||||||
},
|
},
|
||||||
"WPFFeatureslegacymedia": {
|
"WPFFeatureslegacymedia": {
|
||||||
"Content": "Legacy Media (WMP, DirectPlay)",
|
"Content": "Legacy Media (WMP, DirectPlay)",
|
||||||
@ -45,9 +45,8 @@
|
|||||||
"DirectPlay",
|
"DirectPlay",
|
||||||
"LegacyComponents"
|
"LegacyComponents"
|
||||||
],
|
],
|
||||||
"InvokeScript": [
|
"InvokeScript": [],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/legacymedia"
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"WPFFeaturewsl": {
|
"WPFFeaturewsl": {
|
||||||
"Content": "Windows Subsystem for Linux",
|
"Content": "Windows Subsystem for Linux",
|
||||||
@ -59,9 +58,8 @@
|
|||||||
"VirtualMachinePlatform",
|
"VirtualMachinePlatform",
|
||||||
"Microsoft-Windows-Subsystem-Linux"
|
"Microsoft-Windows-Subsystem-Linux"
|
||||||
],
|
],
|
||||||
"InvokeScript": [
|
"InvokeScript": [],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/wsl"
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"WPFFeaturenfs": {
|
"WPFFeaturenfs": {
|
||||||
"Content": "NFS - Network File System",
|
"Content": "NFS - Network File System",
|
||||||
@ -80,7 +78,8 @@
|
|||||||
"Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\ClientForNFS\\CurrentVersion\\Default' -Name 'AnonymousGID' -Type DWord -Value 0",
|
"Set-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\ClientForNFS\\CurrentVersion\\Default' -Name 'AnonymousGID' -Type DWord -Value 0",
|
||||||
"nfsadmin client start",
|
"nfsadmin client start",
|
||||||
"nfsadmin client localhost config fileaccess=755 SecFlavors=+sys -krb5 -krb5i"
|
"nfsadmin client localhost config fileaccess=755 SecFlavors=+sys -krb5 -krb5i"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/nfs"
|
||||||
},
|
},
|
||||||
"WPFFeatureEnableSearchSuggestions": {
|
"WPFFeatureEnableSearchSuggestions": {
|
||||||
"Content": "Enable Search Box Web Suggestions in Registry(explorer restart)",
|
"Content": "Enable Search Box Web Suggestions in Registry(explorer restart)",
|
||||||
@ -88,8 +87,7 @@
|
|||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a015_",
|
"Order": "a015_",
|
||||||
"feature": [
|
"feature": [],
|
||||||
],
|
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
If (!(Test-Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer')) {
|
If (!(Test-Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer')) {
|
||||||
@ -98,7 +96,8 @@
|
|||||||
New-ItemProperty -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Name 'DisableSearchBoxSuggestions' -Type DWord -Value 0 -Force
|
New-ItemProperty -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Name 'DisableSearchBoxSuggestions' -Type DWord -Value 0 -Force
|
||||||
Stop-Process -name explorer -force
|
Stop-Process -name explorer -force
|
||||||
"
|
"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/enablesearchsuggestions"
|
||||||
},
|
},
|
||||||
"WPFFeatureDisableSearchSuggestions": {
|
"WPFFeatureDisableSearchSuggestions": {
|
||||||
"Content": "Disable Search Box Web Suggestions in Registry(explorer restart)",
|
"Content": "Disable Search Box Web Suggestions in Registry(explorer restart)",
|
||||||
@ -106,8 +105,7 @@
|
|||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a016_",
|
"Order": "a016_",
|
||||||
"feature": [
|
"feature": [],
|
||||||
],
|
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
If (!(Test-Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer')) {
|
If (!(Test-Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer')) {
|
||||||
@ -116,7 +114,8 @@
|
|||||||
New-ItemProperty -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Name 'DisableSearchBoxSuggestions' -Type DWord -Value 1 -Force
|
New-ItemProperty -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' -Name 'DisableSearchBoxSuggestions' -Type DWord -Value 1 -Force
|
||||||
Stop-Process -name explorer -force
|
Stop-Process -name explorer -force
|
||||||
"
|
"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/disablesearchsuggestions"
|
||||||
},
|
},
|
||||||
"WPFFeatureRegBackup": {
|
"WPFFeatureRegBackup": {
|
||||||
"Content": "Enable Daily Registry Backup Task 12.30am",
|
"Content": "Enable Daily Registry Backup Task 12.30am",
|
||||||
@ -124,8 +123,7 @@
|
|||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a017_",
|
"Order": "a017_",
|
||||||
"feature": [
|
"feature": [],
|
||||||
],
|
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager' -Name 'EnablePeriodicBackup' -Type DWord -Value 1 -Force
|
New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager' -Name 'EnablePeriodicBackup' -Type DWord -Value 1 -Force
|
||||||
@ -134,7 +132,8 @@
|
|||||||
$trigger = New-ScheduledTaskTrigger -Daily -At 00:30
|
$trigger = New-ScheduledTaskTrigger -Daily -At 00:30
|
||||||
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName 'AutoRegBackup' -Description 'Create System Registry Backups' -User 'System'
|
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName 'AutoRegBackup' -Description 'Create System Registry Backups' -User 'System'
|
||||||
"
|
"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/regbackup"
|
||||||
},
|
},
|
||||||
"WPFFeatureEnableLegacyRecovery": {
|
"WPFFeatureEnableLegacyRecovery": {
|
||||||
"Content": "Enable Legacy F8 Boot Recovery",
|
"Content": "Enable Legacy F8 Boot Recovery",
|
||||||
@ -142,8 +141,7 @@
|
|||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a018_",
|
"Order": "a018_",
|
||||||
"feature": [
|
"feature": [],
|
||||||
],
|
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
If (!(Test-Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood')) {
|
If (!(Test-Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood')) {
|
||||||
@ -152,7 +150,8 @@
|
|||||||
New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Name 'Enabled' -Type DWord -Value 1 -Force
|
New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Name 'Enabled' -Type DWord -Value 1 -Force
|
||||||
Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Legacy' -Wait
|
Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Legacy' -Wait
|
||||||
"
|
"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/enablelegacyrecovery"
|
||||||
},
|
},
|
||||||
"WPFFeatureDisableLegacyRecovery": {
|
"WPFFeatureDisableLegacyRecovery": {
|
||||||
"Content": "Disable Legacy F8 Boot Recovery",
|
"Content": "Disable Legacy F8 Boot Recovery",
|
||||||
@ -160,8 +159,7 @@
|
|||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a019_",
|
"Order": "a019_",
|
||||||
"feature": [
|
"feature": [],
|
||||||
],
|
|
||||||
"InvokeScript": [
|
"InvokeScript": [
|
||||||
"
|
"
|
||||||
If (!(Test-Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood')) {
|
If (!(Test-Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood')) {
|
||||||
@ -170,14 +168,16 @@
|
|||||||
New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Name 'Enabled' -Type DWord -Value 0 -Force
|
New-ItemProperty -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\\LastKnownGood' -Name 'Enabled' -Type DWord -Value 0 -Force
|
||||||
Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Standard' -Wait
|
Start-Process -FilePath cmd.exe -ArgumentList '/c bcdedit /Set {Current} BootMenuPolicy Standard' -Wait
|
||||||
"
|
"
|
||||||
]
|
],
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/disablelegacyrecovery"
|
||||||
},
|
},
|
||||||
"WPFFeaturesandbox": {
|
"WPFFeaturesSandbox": {
|
||||||
"Content": "Windows Sandbox",
|
"Content": "Windows Sandbox",
|
||||||
"category": "Features",
|
"category": "Features",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a021_",
|
"Order": "a021_",
|
||||||
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation."
|
"Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/sandbox"
|
||||||
},
|
},
|
||||||
"WPFFeatureInstall": {
|
"WPFFeatureInstall": {
|
||||||
"Content": "Install Features",
|
"Content": "Install Features",
|
||||||
@ -185,7 +185,8 @@
|
|||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a060_",
|
"Order": "a060_",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/features/install"
|
||||||
},
|
},
|
||||||
"WPFPanelAutologin": {
|
"WPFPanelAutologin": {
|
||||||
"Content": "Set Up Autologin",
|
"Content": "Set Up Autologin",
|
||||||
@ -193,7 +194,8 @@
|
|||||||
"Order": "a040_",
|
"Order": "a040_",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/fixes/autologin"
|
||||||
},
|
},
|
||||||
"WPFFixesUpdate": {
|
"WPFFixesUpdate": {
|
||||||
"Content": "Reset Windows Update",
|
"Content": "Reset Windows Update",
|
||||||
@ -201,7 +203,8 @@
|
|||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a041_",
|
"Order": "a041_",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/fixes/update"
|
||||||
},
|
},
|
||||||
"WPFFixesNetwork": {
|
"WPFFixesNetwork": {
|
||||||
"Content": "Reset Network",
|
"Content": "Reset Network",
|
||||||
@ -209,7 +212,8 @@
|
|||||||
"Order": "a042_",
|
"Order": "a042_",
|
||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/fixes/network"
|
||||||
},
|
},
|
||||||
"WPFPanelDISM": {
|
"WPFPanelDISM": {
|
||||||
"Content": "System Corruption Scan",
|
"Content": "System Corruption Scan",
|
||||||
@ -217,7 +221,8 @@
|
|||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a043_",
|
"Order": "a043_",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/fixes/dism"
|
||||||
},
|
},
|
||||||
"WPFFixesWinget": {
|
"WPFFixesWinget": {
|
||||||
"Content": "WinGet Reinstall",
|
"Content": "WinGet Reinstall",
|
||||||
@ -225,7 +230,8 @@
|
|||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a044_",
|
"Order": "a044_",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/fixes/winget"
|
||||||
},
|
},
|
||||||
"WPFRunAdobeCCCleanerTool": {
|
"WPFRunAdobeCCCleanerTool": {
|
||||||
"Content": "Remove Adobe Creative Cloud",
|
"Content": "Remove Adobe Creative Cloud",
|
||||||
@ -233,55 +239,110 @@
|
|||||||
"panel": "1",
|
"panel": "1",
|
||||||
"Order": "a045_",
|
"Order": "a045_",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/fixes/runadobecccleanertool"
|
||||||
},
|
},
|
||||||
"WPFPanelnetwork": {
|
"WPFPanelnetwork": {
|
||||||
"Content": "Network Connections",
|
"Content": "Network Connections",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
|
||||||
},
|
},
|
||||||
"WPFPanelcontrol": {
|
"WPFPanelcontrol": {
|
||||||
"Content": "Control Panel",
|
"Content": "Control Panel",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
|
||||||
|
},
|
||||||
|
"WPFPanelcomputer": {
|
||||||
|
"Content": "Computer Management",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
|
"panel": "2",
|
||||||
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer"
|
||||||
},
|
},
|
||||||
"WPFPanelpower": {
|
"WPFPanelpower": {
|
||||||
"Content": "Power Panel",
|
"Content": "Power Panel",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
|
||||||
},
|
},
|
||||||
"WPFPanelregion": {
|
"WPFPanelregion": {
|
||||||
"Content": "Region",
|
"Content": "Region",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
|
||||||
},
|
},
|
||||||
"WPFPanelsound": {
|
"WPFPanelsound": {
|
||||||
"Content": "Sound Settings",
|
"Content": "Sound Settings",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
|
||||||
|
},
|
||||||
|
"WPFPanelprinter": {
|
||||||
|
"Content": "Printer Panel",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
|
"panel": "2",
|
||||||
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
|
||||||
},
|
},
|
||||||
"WPFPanelsystem": {
|
"WPFPanelsystem": {
|
||||||
"Content": "System Properties",
|
"Content": "System Properties",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
|
||||||
},
|
},
|
||||||
"WPFPaneluser": {
|
"WPFPaneluser": {
|
||||||
"Content": "User Accounts",
|
"Content": "User Accounts",
|
||||||
"category": "Legacy Windows Panels",
|
"category": "Legacy Windows Panels",
|
||||||
"panel": "2",
|
"panel": "2",
|
||||||
"Type": "Button",
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300",
|
||||||
|
"link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/user"
|
||||||
|
},
|
||||||
|
"WPFPanelGodMode": {
|
||||||
|
"Content": "God Mode",
|
||||||
|
"category": "Legacy Windows Panels",
|
||||||
|
"panel": "2",
|
||||||
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
|
},
|
||||||
|
"WPFWinUtilInstallPSProfile": {
|
||||||
|
"Content": "Install CTT PowerShell Profile",
|
||||||
|
"category": "Powershell Profile",
|
||||||
|
"panel": "2",
|
||||||
|
"Order": "a083_",
|
||||||
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
|
},
|
||||||
|
"WPFWinUtilUninstallPSProfile": {
|
||||||
|
"Content": "Uninstall CTT PowerShell Profile",
|
||||||
|
"category": "Powershell Profile",
|
||||||
|
"panel": "2",
|
||||||
|
"Order": "a084_",
|
||||||
|
"Type": "Button",
|
||||||
|
"ButtonWidth": "300"
|
||||||
|
},
|
||||||
|
"WPFWinUtilSSHServer": {
|
||||||
|
"Content": "Enable OpenSSH Server",
|
||||||
|
"category": "Remote Access",
|
||||||
|
"panel": "2",
|
||||||
|
"Order": "a084_",
|
||||||
|
"Type": "Button",
|
||||||
"ButtonWidth": "300"
|
"ButtonWidth": "300"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
"Standard": [
|
"Standard": [
|
||||||
"WPFTweaksAH",
|
"WPFTweaksAH",
|
||||||
"WPFTweaksConsumerFeatures",
|
"WPFTweaksConsumerFeatures",
|
||||||
|
"WPFTweaksDisableExplorerAutoDiscovery",
|
||||||
"WPFTweaksDVR",
|
"WPFTweaksDVR",
|
||||||
"WPFTweaksHiber",
|
|
||||||
"WPFTweaksHome",
|
"WPFTweaksHome",
|
||||||
"WPFTweaksLoc",
|
"WPFTweaksLoc",
|
||||||
"WPFTweaksServices",
|
"WPFTweaksServices",
|
||||||
@ -14,11 +14,11 @@
|
|||||||
"WPFTweaksDeleteTempFiles",
|
"WPFTweaksDeleteTempFiles",
|
||||||
"WPFTweaksEndTaskOnTaskbar",
|
"WPFTweaksEndTaskOnTaskbar",
|
||||||
"WPFTweaksRestorePoint",
|
"WPFTweaksRestorePoint",
|
||||||
"WPFTweaksTeredo",
|
|
||||||
"WPFTweaksPowershell7Tele"
|
"WPFTweaksPowershell7Tele"
|
||||||
],
|
],
|
||||||
"Minimal": [
|
"Minimal": [
|
||||||
"WPFTweaksConsumerFeatures",
|
"WPFTweaksConsumerFeatures",
|
||||||
|
"WPFTweaksDisableExplorerAutoDiscovery",
|
||||||
"WPFTweaksHome",
|
"WPFTweaksHome",
|
||||||
"WPFTweaksServices",
|
"WPFTweaksServices",
|
||||||
"WPFTweaksTele"
|
"WPFTweaksTele"
|
||||||
|
@ -1,208 +1,126 @@
|
|||||||
{
|
{
|
||||||
"Classic": {
|
"shared":{
|
||||||
|
"AppEntryWidth": "130",
|
||||||
|
"AppEntryFontSize": "11",
|
||||||
|
"AppEntryMargin": "1,1,1,1",
|
||||||
|
"AppEntryBorderTickness": "0",
|
||||||
"CustomDialogFontSize": "12",
|
"CustomDialogFontSize": "12",
|
||||||
"CustomDialogFontSizeHeader": "14",
|
"CustomDialogFontSizeHeader": "14",
|
||||||
"CustomDialogIconSize": "25",
|
"CustomDialogLogoSize": "25",
|
||||||
"CustomDialogWidth": "400",
|
"CustomDialogWidth": "400",
|
||||||
"CustomDialogHeight": "200",
|
"CustomDialogHeight": "200",
|
||||||
|
|
||||||
"FontSize": "12",
|
"FontSize": "12",
|
||||||
"FontFamily": "Arial",
|
"FontFamily": "Arial",
|
||||||
"FontSizeHeading": "14",
|
"HeaderFontSize": "16",
|
||||||
"HeaderFontFamily": "Consolas, Monaco",
|
"HeaderFontFamily": "Consolas, Monaco",
|
||||||
|
"CheckBoxBulletDecoratorSize": "14",
|
||||||
"CheckBoxBulletDecoratorFontSize": "14",
|
|
||||||
"CheckBoxMargin": "15,0,0,2",
|
"CheckBoxMargin": "15,0,0,2",
|
||||||
|
"TabContentMargin": "5",
|
||||||
"TabButtonFontSize": "14",
|
"TabButtonFontSize": "14",
|
||||||
"TabButtonWidth": "100",
|
"TabButtonWidth": "110",
|
||||||
"TabButtonHeight": "25",
|
"TabButtonHeight": "26",
|
||||||
"TabRowHeightInPixels": "50",
|
"TabRowHeightInPixels": "50",
|
||||||
|
"ToolTipWidth": "300",
|
||||||
"IconFontSize": "14",
|
"IconFontSize": "14",
|
||||||
"IconButtonSize": "35",
|
"IconButtonSize": "35",
|
||||||
"WinUtilIconSize": "Auto",
|
|
||||||
"SettingsIconFontSize": "18",
|
"SettingsIconFontSize": "18",
|
||||||
|
"CloseIconFontSize": "18",
|
||||||
"MicroWinLogoSize": "10",
|
"MicroWinLogoSize": "10",
|
||||||
|
"MicrowinCheckBoxMargin": "-10,5,0,0",
|
||||||
"ComboBoxBackgroundColor": "#FFFFFF",
|
"GroupBorderBackgroundColor": "#232629",
|
||||||
"LabelboxForegroundColor": "#000000",
|
|
||||||
"MainForegroundColor": "#000000",
|
|
||||||
"MainBackgroundColor": "#FFFFFF",
|
|
||||||
"LabelBackgroundColor": "#FAFAFA",
|
|
||||||
"LinkForegroundColor": "#000000",
|
|
||||||
"LinkHoverForegroundColor": "#000000",
|
|
||||||
"GroupBorderBackgroundColor": "#000000",
|
|
||||||
"ComboBoxForegroundColor": "#000000",
|
|
||||||
|
|
||||||
"ButtonFontSize": "12",
|
"ButtonFontSize": "12",
|
||||||
"ButtonFontFamily": "Arial",
|
"ButtonFontFamily": "Arial",
|
||||||
"ButtonWidth": "200",
|
"ButtonWidth": "200",
|
||||||
"ButtonHeight": "25",
|
"ButtonHeight": "25",
|
||||||
"ConfigTabButtonFontSize": "16",
|
"ConfigUpdateButtonFontSize": "14",
|
||||||
|
|
||||||
"SearchBarWidth": "200",
|
"SearchBarWidth": "200",
|
||||||
"SearchBarHeight": "25",
|
"SearchBarHeight": "26",
|
||||||
"SearchBarTextBoxFontSize": "16",
|
"SearchBarTextBoxFontSize": "12",
|
||||||
"SearchBarClearButtonFontSize": "14",
|
"SearchBarClearButtonFontSize": "14",
|
||||||
|
"CheckboxMouseOverColor": "#999999",
|
||||||
|
"ButtonBorderThickness": "1",
|
||||||
|
"ButtonMargin": "1",
|
||||||
|
"ButtonCornerRadius": "2"
|
||||||
|
},
|
||||||
|
"Light": {
|
||||||
|
"AppInstallUnselectedColor": "#F7F7F7",
|
||||||
|
"AppInstallHighlightedColor": "#CFCFCF",
|
||||||
|
"AppInstallSelectedColor": "#C2C2C2",
|
||||||
|
"AppInstallOverlayBackgroundColor":"#6A6D72",
|
||||||
|
"ComboBoxForegroundColor": "#232629",
|
||||||
|
"ComboBoxBackgroundColor": "#F7F7F7",
|
||||||
|
"LabelboxForegroundColor": "#232629",
|
||||||
|
"MainForegroundColor": "#232629",
|
||||||
|
"MainBackgroundColor": "#F7F7F7",
|
||||||
|
"LabelBackgroundColor": "#F7F7F7",
|
||||||
|
"LinkForegroundColor": "#484848",
|
||||||
|
"LinkHoverForegroundColor": "#232629",
|
||||||
|
"ScrollBarBackgroundColor": "#4A4D52",
|
||||||
|
"ScrollBarHoverColor": "#5A5D62",
|
||||||
|
"ScrollBarDraggingColor": "#6A6D72",
|
||||||
|
|
||||||
"ButtonInstallBackgroundColor": "#FFFFFF",
|
"MicrowinBusyColor": "#2e77ff",
|
||||||
"ButtonTweaksBackgroundColor": "#FFFFFF",
|
"ProgressBarForegroundColor": "#2e77ff",
|
||||||
"ButtonConfigBackgroundColor": "#FFFFFF",
|
"ProgressBarBackgroundColor": "Transparent",
|
||||||
"ButtonUpdatesBackgroundColor": "#FFFFFF",
|
"ProgressBarTextColor": "#232629",
|
||||||
"ButtonInstallForegroundColor": "#000000",
|
"ButtonInstallBackgroundColor": "#F7F7F7",
|
||||||
"ButtonTweaksForegroundColor": "#000000",
|
"ButtonTweaksBackgroundColor": "#F7F7F7",
|
||||||
"ButtonConfigForegroundColor": "#000000",
|
"ButtonConfigBackgroundColor": "#F7F7F7",
|
||||||
"ButtonUpdatesForegroundColor": "#000000",
|
"ButtonUpdatesBackgroundColor": "#F7F7F7",
|
||||||
|
"ButtonInstallForegroundColor": "#232629",
|
||||||
|
"ButtonTweaksForegroundColor": "#232629",
|
||||||
|
"ButtonConfigForegroundColor": "#232629",
|
||||||
|
"ButtonUpdatesForegroundColor": "#232629",
|
||||||
"ButtonBackgroundColor": "#F5F5F5",
|
"ButtonBackgroundColor": "#F5F5F5",
|
||||||
"ButtonBackgroundPressedColor": "#1A1A1A",
|
"ButtonBackgroundPressedColor": "#1A1A1A",
|
||||||
"CheckboxMouseOverColor": "#999999",
|
|
||||||
"ButtonBackgroundMouseoverColor": "#C2C2C2",
|
"ButtonBackgroundMouseoverColor": "#C2C2C2",
|
||||||
"ButtonBackgroundSelectedColor": "#F0F0F0",
|
"ButtonBackgroundSelectedColor": "#F0F0F0",
|
||||||
"ButtonForegroundColor": "#000000",
|
"ButtonForegroundColor": "#232629",
|
||||||
"ToggleButtonOnColor": "#2e77ff",
|
"ToggleButtonOnColor": "#2e77ff",
|
||||||
|
"ToggleButtonOffColor": "#707070",
|
||||||
|
"ToolTipBackgroundColor": "#F7F7F7",
|
||||||
|
"BorderColor": "#232629",
|
||||||
|
"BorderOpacity": "0.2"
|
||||||
|
|
||||||
"ButtonBorderThickness": "1",
|
|
||||||
"ButtonMargin": "1",
|
|
||||||
"ButtonCornerRadius": "2",
|
|
||||||
"BorderColor": "#000000",
|
|
||||||
"BorderOpacity": "0.2",
|
|
||||||
"ShadowPulse": "Forever"
|
|
||||||
},
|
|
||||||
"Matrix": {
|
|
||||||
"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": "#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": {
|
"Dark": {
|
||||||
"CustomDialogFontSize": "12",
|
"AppInstallUnselectedColor": "#232629",
|
||||||
"CustomDialogFontSizeHeader": "14",
|
"AppInstallHighlightedColor": "#3C3C3C",
|
||||||
"CustomDialogIconSize": "25",
|
"AppInstallSelectedColor": "#4C4C4C",
|
||||||
"CustomDialogWidth": "400",
|
"AppInstallOverlayBackgroundColor":"#2E3135",
|
||||||
"CustomDialogHeight": "200",
|
"ComboBoxForegroundColor": "#F7F7F7",
|
||||||
|
"ComboBoxBackgroundColor": "#1E3747",
|
||||||
"FontSize": "12",
|
"LabelboxForegroundColor": "#0567ff",
|
||||||
"FontFamily": "Arial",
|
"MainForegroundColor": "#F7F7F7",
|
||||||
"FontSizeHeading": "14",
|
"MainBackgroundColor": "#232629",
|
||||||
"HeaderFontFamily": "Consolas, Monaco",
|
"LabelBackgroundColor": "#232629",
|
||||||
|
|
||||||
"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",
|
"LinkForegroundColor": "#add8e6",
|
||||||
"LinkHoverForegroundColor": "#FFFFFF",
|
"LinkHoverForegroundColor": "#F7F7F7",
|
||||||
"ComboBoxForegroundColor": "#FFEE58",
|
"ScrollBarBackgroundColor": "#2E3135",
|
||||||
|
"ScrollBarHoverColor": "#3B4252",
|
||||||
"ButtonFontSize": "12",
|
"ScrollBarDraggingColor": "#5E81AC",
|
||||||
"ButtonFontFamily": "Arial",
|
|
||||||
"ButtonWidth": "200",
|
|
||||||
"ButtonHeight": "25",
|
|
||||||
"ConfigTabButtonFontSize": "16",
|
|
||||||
|
|
||||||
"SearchBarWidth": "200",
|
|
||||||
"SearchBarHeight": "25",
|
|
||||||
"SearchBarTextBoxFontSize": "16",
|
|
||||||
"SearchBarClearButtonFontSize": "14",
|
|
||||||
|
|
||||||
|
"MicrowinBusyColor": "#2e77ff",
|
||||||
|
"ProgressBarForegroundColor": "#222222",
|
||||||
|
"ProgressBarBackgroundColor": "Transparent",
|
||||||
|
"ProgressBarTextColor": "#232629",
|
||||||
"ButtonInstallBackgroundColor": "#222222",
|
"ButtonInstallBackgroundColor": "#222222",
|
||||||
"ButtonTweaksBackgroundColor": "#333333",
|
"ButtonTweaksBackgroundColor": "#333333",
|
||||||
"ButtonConfigBackgroundColor": "#444444",
|
"ButtonConfigBackgroundColor": "#444444",
|
||||||
"ButtonUpdatesBackgroundColor": "#555555",
|
"ButtonUpdatesBackgroundColor": "#555555",
|
||||||
"ButtonInstallForegroundColor": "#FFFFFF",
|
"ButtonInstallForegroundColor": "#F7F7F7",
|
||||||
"ButtonTweaksForegroundColor": "#FFFFFF",
|
"ButtonTweaksForegroundColor": "#F7F7F7",
|
||||||
"ButtonConfigForegroundColor": "#FFFFFF",
|
"ButtonConfigForegroundColor": "#F7F7F7",
|
||||||
"ButtonUpdatesForegroundColor": "#FFFFFF",
|
"ButtonUpdatesForegroundColor": "#F7F7F7",
|
||||||
"ButtonBackgroundColor": "#000019",
|
"ButtonBackgroundColor": "#1E3747",
|
||||||
"ButtonBackgroundPressedColor": "#9CCC65",
|
"ButtonBackgroundPressedColor": "#F7F7F7",
|
||||||
"ButtonBackgroundMouseoverColor": "#FF5733",
|
"ButtonBackgroundMouseoverColor": "#3B4252",
|
||||||
"ButtonBackgroundSelectedColor": "#FF5733",
|
"ButtonBackgroundSelectedColor": "#5E81AC",
|
||||||
"ButtonForegroundColor": "#9CCC65",
|
"ButtonForegroundColor": "#F7F7F7",
|
||||||
"ToggleButtonOnColor": "#2e77ff",
|
"ToggleButtonOnColor": "#2e77ff",
|
||||||
|
"ToggleButtonOffColor": "#707070",
|
||||||
"ButtonBorderThickness": "1",
|
"ToolTipBackgroundColor": "#2F373D",
|
||||||
"ButtonMargin": "1",
|
"BorderColor": "#2F373D",
|
||||||
"ButtonCornerRadius": "2",
|
"BorderOpacity": "0.2"
|
||||||
"BorderColor": "#FFAC1C",
|
|
||||||
"BorderOpacity": "0.2",
|
|
||||||
"ShadowPulse": "Forever"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1173
config/tweaks.json
@ -1,177 +0,0 @@
|
|||||||
## Known Issues and Fixes
|
|
||||||
|
|
||||||
### 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:
|
|
||||||
|
|
||||||
| `1.1.1.1` | `1.0.0.1` | or | `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.
|
|
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 138 KiB |
Before Width: | Height: | Size: 303 KiB |
Before Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 339 KiB |
@ -1,57 +0,0 @@
|
|||||||
# How to Contribute?
|
|
||||||
|
|
||||||
## 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]
|
|
||||||
> Do not use a code formatter, massive amounts of line changes, and 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 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 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
|
|
||||||
|
|
||||||
### 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
|
|
||||||
* While you can make your changes directly through the Web, we recommend cloning the repo to your device to test your fork easily.
|
|
||||||
* Using the application GitHub Desktop (available in WinUtil) you can easily manage your repos locally. You can do it using other tools like git-cli (available in WinUtil), we recommend GitHub Desktop for ease of use.
|
|
||||||
* Install GitHub Desktop if not already installed
|
|
||||||
* Log in using the same GitHub account u 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 prefered text editor.
|
|
||||||
|
|
||||||
|
|
||||||
### Testing your changes
|
|
||||||
* To test to see if your changes work as intended run following commands in a powershell teminal:
|
|
||||||
|
|
||||||
* Change the directory where you are running the commands to the forked project.
|
|
||||||
* `cd {path to the folder with the compile.ps1}`
|
|
||||||
* Run 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.
|
|
||||||
|
|
||||||
### Commiting the changes
|
|
||||||
* Commit your changes once you are fine 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 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 in 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. As all new changes go into the /windev build to make sure everything is working ok before going fully public.
|
|
||||||
* Congrats you just submitted your first PR. Thank you so much for contributing to WinUtil.
|
|
@ -1,4 +0,0 @@
|
|||||||
# 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.
|
|
@ -1,12 +0,0 @@
|
|||||||
# Welcome to Chris Titus WinUtil Official Documentation!
|
|
||||||
|
|
||||||
[](https://discord.gg/RUbZUZyByQ)
|
|
||||||
|
|
||||||
## Running
|
|
||||||
|
|
||||||
There are 4 ways to run WinUtil. The 4 ways goes as follows:
|
|
||||||
|
|
||||||
* `irm christitus.com/win | iex` - Runs WinUtil from ChrisTitus's website using the latest Full Releases.
|
|
||||||
* `irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex` - Runs WinUtil from github using the latest Full Release.
|
|
||||||
* `irm christitus.com/windev | iex` - Runs WinUtil from ChrisTitus website using the latest Pre-Release.
|
|
||||||
* `irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/windev.ps1 | iex` - Runs WinUtil from github using the latest Pre-Release.
|
|
@ -1,3 +0,0 @@
|
|||||||
# Update Log
|
|
||||||
|
|
||||||
#
|
|
@ -1,159 +0,0 @@
|
|||||||
# User Guide
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
* short one
|
|
||||||
|
|
||||||
|
|
||||||
## Walkthrough
|
|
||||||
|
|
||||||
### Program
|
|
||||||
|
|
||||||
#### Installation & Updates
|
|
||||||
* To install programs select the programs you wish to install or update like the picture below.
|
|
||||||

|
|
||||||
* Once you have selected the programs you wish to install click the select Install/Upgrade Selected button as seen below.
|
|
||||||

|
|
||||||
|
|
||||||
#### Upgrade All
|
|
||||||
* Press the button to upgrade all installed programs that are supported by WinGet, there is no selection needed.
|
|
||||||
|
|
||||||
#### Uninstall
|
|
||||||
* To uninstall programs select the programs you wish to uninstall like the picture below.
|
|
||||||

|
|
||||||
* Once you have selected the programs you wish to uninstall click the select Uninstall Selected button as seen below.
|
|
||||||

|
|
||||||
|
|
||||||
#### Get Installed
|
|
||||||
* Checks for installed programs that are supported by WinGet and selects them in the Utility.
|
|
||||||
|
|
||||||
#### Clear Selection
|
|
||||||
* Clears ur current selection so no program is checked.
|
|
||||||
|
|
||||||
### Tweaks
|
|
||||||
|
|
||||||
#### Tweaks Addition
|
|
||||||
* To enable tweaks on your system select Tweaks at the top next to Install.
|
|
||||||
* Then you can select what tweaks you want adding to your system. We do have some presets you can select from at the top you can see this in the picture below.
|
|
||||||

|
|
||||||
* After you have chosen your tweaks click the Run Tweaks button at the bottom of the screen.
|
|
||||||
|
|
||||||
#### Tweaks Removal
|
|
||||||
* To disable tweaks on your system select Tweaks at the top next to Install.
|
|
||||||
* Then you can select what tweaks you want removing from your system.
|
|
||||||
* After you have chosen your tweaks you want to remove click the Undo Selected Tweaks button at the bottom of the screen.
|
|
||||||
|
|
||||||
#### Essential Tweaks
|
|
||||||
* The Tweaks under the Essential
|
|
||||||
|
|
||||||
#### Advanced Tweaks - CAUTION
|
|
||||||
|
|
||||||
#### O&O Shutup
|
|
||||||
|
|
||||||
#### DNS
|
|
||||||
|
|
||||||
#### Customize Preferences
|
|
||||||
|
|
||||||
#### Performance Plans
|
|
||||||
|
|
||||||
#### Shortcuts
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### Config
|
|
||||||
|
|
||||||
#### Features
|
|
||||||
* Install the most used Windows Features by checking the checkbox and clicking "Install Features" to install them
|
|
||||||
|
|
||||||
#### 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
|
|
||||||
|
|
||||||
### Updates | Not working rn
|
|
||||||
|
|
||||||
### 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!
|
|
||||||
|
|
||||||
**NOTE:** 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 CTT GitHub repo** will grab a OSCDIMG executable from the GitHub repository instead of a Chocolatey package
|
|
||||||
|
|
||||||
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 on 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 were permanent ones or had 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 case 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. On that regard, don't install AVs with bad reputation 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 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 of 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
|
|
||||||
|
|
||||||
Ventoy is a solution that lets you boot to any ISO file stored in 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 chose Export, chose file file and location, this will export the setting file.
|
|
||||||

|
|
||||||
* Copy this file to a USB or somewhere you can use after Windows installation.
|
|
||||||
* Use Microwin tab to create a custom Windows image.
|
|
||||||
* Install the Windows image.
|
|
||||||
* In the new Windows, Open PowerShell in the admin mode and run command to automatically apply tweaks and install apps from the config file.
|
|
||||||
* ``` iex "& { $(irm christitus.com/win) } -Config [path-to-your-config] -Run" ```
|
|
||||||
* Have a cup of coffee! Come back when it's done.
|
|
236
edgeremoval.bat
@ -1,236 +0,0 @@
|
|||||||
@(set "0=%~f0"^)#) & powershell -nop -c iex([io.file]::ReadAllText($env:0)) & exit /b
|
|
||||||
#:: made by AveYo source: https://raw.githubusercontent.com/AveYo/fox/main/Edge_Removal.bat
|
|
||||||
sp 'HKCU:\Volatile Environment' 'Edge_Removal' @'
|
|
||||||
|
|
||||||
$also_remove_webview = 0
|
|
||||||
|
|
||||||
$host.ui.RawUI.WindowTitle = 'Edge Removal - AveYo, 2023.09.09'
|
|
||||||
$remove_win32 = @("Microsoft Edge","Microsoft Edge Update"); $remove_appx = @("MicrosoftEdge"); $skip = @() # @("DevTools")
|
|
||||||
if ($also_remove_webview -eq 1) {$remove_win32 += "Microsoft EdgeWebView"; $remove_appx += "WebExperience","Win32WebViewHost"}
|
|
||||||
|
|
||||||
## 1 bonus! enter into powershell console: firefox / edge / webview to install a browser / reinstall edge or webview after removal
|
|
||||||
function global:firefox { $url = 'https://download.mozilla.org/?product=firefox-stub'
|
|
||||||
$setup = "$((new-object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path)\Firefox Installer.exe"
|
|
||||||
write-host $url; Invoke-WebRequest $url -OutFile $setup; start $setup
|
|
||||||
}
|
|
||||||
function global:edge { $url = 'https://go.microsoft.com/fwlink/?linkid=2108834&Channel=Stable&language=en'
|
|
||||||
$setup = "$((new-object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path)\MicrosoftEdgeSetup.exe"
|
|
||||||
write-host $url; Invoke-WebRequest $url -OutFile $setup; prepare_edge; start $setup
|
|
||||||
}
|
|
||||||
function global:webview { $url = 'https://go.microsoft.com/fwlink/p/?LinkId=2124703'
|
|
||||||
$setup = "$((new-object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path)\MicrosoftEdgeWebview2Setup.exe"
|
|
||||||
write-host $url; Invoke-WebRequest $url -OutFile $setup; prepare_webview; start $setup
|
|
||||||
}
|
|
||||||
## helper for set-itemproperty remove-itemproperty new-item remove-item with auto test-path
|
|
||||||
function global:sp_test_path { if (test-path $args[0]) {Microsoft.PowerShell.Management\Set-ItemProperty @args} else {
|
|
||||||
Microsoft.PowerShell.Management\New-Item $args[0] -force -ea 0 >''; Microsoft.PowerShell.Management\Set-ItemProperty @args} }
|
|
||||||
function global:rp_test_path { if (test-path $args[0]) {Microsoft.PowerShell.Management\Remove-ItemProperty @args} }
|
|
||||||
function global:ni_test_path { if (-not (test-path $args[0])) {Microsoft.PowerShell.Management\New-Item @args} }
|
|
||||||
function global:ri_test_path { if (test-path $args[0]) {Microsoft.PowerShell.Management\Remove-Item @args} }
|
|
||||||
foreach ($f in 'sp','rp','ni','ri') {set-alias -Name $f -Value "${f}_test_path" -Scope Local -Option AllScope -force -ea 0}
|
|
||||||
## helper for edge reinstall - remove bundled OpenWebSearch redirector and edgeupdate policies
|
|
||||||
function global:prepare_edge {
|
|
||||||
foreach ($f in 'ni','ri','sp','rp') {set-alias -Name $f -Value "${f}_test_path" -Scope Local -Option AllScope -force -ea 0}
|
|
||||||
$MS=($env:ProgramFiles,${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem]+'\Microsoft\Edge\Application\msedge.exe'
|
|
||||||
ri "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\msedge.exe" -recurse -force -ea 0
|
|
||||||
ri "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ie_to_edge_stub.exe" -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
|
|
||||||
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
|
|
||||||
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
|
|
||||||
foreach ($p in 'HKLM:\SOFTWARE\Policies','HKLM:\SOFTWARE','HKLM:\SOFTWARE\WOW6432Node') {
|
|
||||||
rp "$p\Microsoft\EdgeUpdate" 'InstallDefault' -force -ea 0
|
|
||||||
rp "$p\Microsoft\EdgeUpdate" 'Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}' -force -ea 0
|
|
||||||
rp "$p\Microsoft\EdgeUpdate" 'Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' -force -ea 0
|
|
||||||
}
|
|
||||||
$edgeupdate='Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}'
|
|
||||||
$webvupdate='Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'
|
|
||||||
$on_actions='on-os-upgrade','on-logon','on-logon-autolaunch','on-logon-startup-boost'
|
|
||||||
foreach ($p in 'HKLM:\SOFTWARE','HKLM:\SOFTWARE\Wow6432Node') { foreach ($launch in $on_actions) {
|
|
||||||
ri "$p\$edgeupdate\Commands\$launch" -force -ea 0; ri "$p\$webvupdate\Commands\$launch" -force -ea 0
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
## helper for webview reinstall - restore webexperience (widgets) if available
|
|
||||||
function global:prepare_webview {
|
|
||||||
$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: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}
|
|
||||||
}
|
|
||||||
|
|
||||||
## 2 enable admin privileges
|
|
||||||
$D1=[uri].module.gettype('System.Diagnostics.Process')."GetM`ethods"(42) |where {$_.Name -eq 'SetPrivilege'} #`:no-ev-warn
|
|
||||||
'SeSecurityPrivilege','SeTakeOwnershipPrivilege','SeBackupPrivilege','SeRestorePrivilege'|foreach {$D1.Invoke($null, @("$_",2))}
|
|
||||||
|
|
||||||
## 3 shut edge & webview clone stuff down and gather install paths
|
|
||||||
$shut = 'explorer','Widgets','widgetservice','msedgewebview2','MicrosoftEdge*','chredge','msedge','edge'
|
|
||||||
$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}
|
|
||||||
prepare_edge
|
|
||||||
## clear win32 uninstall block
|
|
||||||
foreach ($hk in 'HKCU:','HKLM:') { foreach ($wow in '','\Wow6432Node') { foreach ($i in $remove_win32) {
|
|
||||||
rp "$hk\SOFTWARE${wow}\Microsoft\Windows\CurrentVersion\Uninstall\$i" 'NoRemove' -force -ea 0
|
|
||||||
ni "$hk\SOFTWARE${wow}\Microsoft\EdgeUpdateDev" -force >''
|
|
||||||
sp "$hk\SOFTWARE${wow}\Microsoft\EdgeUpdateDev" 'AllowUninstall' 1 -type Dword -force
|
|
||||||
}}}
|
|
||||||
## find all Edge setup.exe and gather BHO paths for OpenWebSearch / MSEdgeRedirect usage
|
|
||||||
$edges = @(); $bho = @(); 'LocalApplicationData','ProgramFilesX86','ProgramFiles' |foreach {
|
|
||||||
$folder = [Environment]::GetFolderPath($_); $bho += dir "$folder\Microsoft\Edge*\ie_to_edge_stub.exe" -rec -ea 0
|
|
||||||
if ($also_remove_webview -eq 1) {$edges += dir "$folder\Microsoft\Edge*\setup.exe" -rec -ea 0 |where {$_ -like '*EdgeWebView*'}}
|
|
||||||
$edges += dir "$folder\Microsoft\Edge*\setup.exe" -rec -ea 0 |where {$_ -notlike '*EdgeWebView*'}
|
|
||||||
}
|
|
||||||
## use dedicated C:\Scripts path to save OpenWebSearch (due to Sigma rules FUD)
|
|
||||||
$DIR = "$env:SystemDrive\Scripts"; mkdir $DIR -ea 0 >''
|
|
||||||
## export OpenWebSearch innovative redirector - used by MSEdgeRedirect as well
|
|
||||||
foreach ($b in $bho) { if (test-path $b) { try {copy $b "$DIR\ie_to_edge_stub.exe" -force -ea 0} catch{} } }
|
|
||||||
|
|
||||||
## 4 remove found *Edge* appx packages with unblock tricks
|
|
||||||
$provisioned = get-appxprovisionedpackage -online; $appxpackage = get-appxpackage -allusers; $eol = @()
|
|
||||||
$store = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx\AppxAllUserStore'
|
|
||||||
$users = @('S-1-5-18'); if (test-path $store) {$users += $((dir $store -ea 0 |where {$_ -like '*S-1-5-21*'}).PSChildName)}
|
|
||||||
foreach ($choice in $remove_appx) { if ('' -eq $choice.Trim()) {continue}
|
|
||||||
foreach ($appx in $($provisioned |where {$_.PackageName -like "*$choice*"})) {
|
|
||||||
$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
|
|
||||||
ni "$store\Deprovisioned\$PackageFamilyName" -force >''; $PackageFamilyName
|
|
||||||
foreach ($sid in $users) {ni "$store\EndOfLife\$sid\$PackageName" -force >''} ; $eol += $PackageName
|
|
||||||
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 >''
|
|
||||||
remove-appxprovisionedpackage -packagename $PackageName -online -allusers >''
|
|
||||||
}
|
|
||||||
foreach ($appx in $($appxpackage |where {$_.PackageFullName -like "*$choice*"})) {
|
|
||||||
$next = !1; foreach ($no in $skip) {if ($appx.PackageFullName -like "*$no*") {$next = !0}} ; if ($next) {continue}
|
|
||||||
$PackageFullName = $appx.PackageFullName;
|
|
||||||
ni "$store\Deprovisioned\$appx.PackageFamilyName" -force >''; $PackageFullName
|
|
||||||
foreach ($sid in $users) {ni "$store\EndOfLife\$sid\$PackageFullName" -force >''} ; $eol += $PackageFullName
|
|
||||||
dism /online /set-nonremovableapppolicy /packagefamily:$PackageFamilyName /nonremovable:0 >''
|
|
||||||
remove-appxpackage -package $PackageFullName -allusers >''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## 5 run found *Edge* setup.exe with uninstall args and wait in-between
|
|
||||||
foreach ($setup in $edges) { if (test-path $setup) {
|
|
||||||
if ($setup -like '*EdgeWebView*') {$target = "--msedgewebview"} else {$target = "--msedge"}
|
|
||||||
$removal = "--uninstall $target --system-level --verbose-logging --force-uninstall"
|
|
||||||
try {write-host $setup $removal; start -wait $setup -args $removal} catch {}
|
|
||||||
do {sleep 3} while ((get-process -name 'setup','MicrosoftEdge*' -ea 0).Path -like '*\Microsoft\Edge*')
|
|
||||||
}}
|
|
||||||
|
|
||||||
## 6 extra cleanup
|
|
||||||
foreach ($PF in $env:ProgramFiles,${env:ProgramFiles(x86)}) { if (test-path "$PF\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe") {
|
|
||||||
write-host "$PF\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe /uninstall"
|
|
||||||
start -wait "$PF\Microsoft\EdgeUpdate\MicrosoftEdgeUpdate.exe" -args '/uninstall'
|
|
||||||
do {sleep 3} while ((get-process -name 'setup','MicrosoftEdge*' -ea 0).Path -like '*\Microsoft\Edge*')
|
|
||||||
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 "$PF\Microsoft\EdgeUpdate" -rec -force -ea 0; Unregister-ScheduledTask -TaskName MicrosoftEdgeUpdate* -Confirm:$false -ea 0
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
$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\Microsoft Edge.lnk" -force
|
|
||||||
|
|
||||||
## 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 >''} }
|
|
||||||
|
|
||||||
## set (almost) useless policies to prevent unsolicited reinstalls
|
|
||||||
foreach ($p in 'HKLM:\SOFTWARE\Policies','HKLM:\SOFTWARE','HKLM:\SOFTWARE\WOW6432Node') {
|
|
||||||
ni "$p\Microsoft\EdgeUpdate" -force >''
|
|
||||||
sp "$p\Microsoft\EdgeUpdate" 'InstallDefault' 0 -type Dword -force
|
|
||||||
sp "$p\Microsoft\EdgeUpdate" 'Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}' 0 -type Dword -force
|
|
||||||
sp "$p\Microsoft\EdgeUpdate" 'Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}' 1 -type Dword -force
|
|
||||||
sp "$p\Microsoft\EdgeUpdate" 'DoNotUpdateToEdgeWithChromium' 1 -type Dword -force
|
|
||||||
}
|
|
||||||
$edgeupdate='Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}'
|
|
||||||
$webvupdate='Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'
|
|
||||||
$on_actions='on-os-upgrade','on-logon','on-logon-autolaunch','on-logon-startup-boost'
|
|
||||||
foreach ($p in 'HKLM:\SOFTWARE','HKLM:\SOFTWARE\Wow6432Node') { foreach ($launch in $on_actions) {
|
|
||||||
ni "$p\$edgeupdate\Commands\$launch" -force >''; sp "$p\$edgeupdate\Commands\$launch" 'CommandLine' 'systray.exe' -force
|
|
||||||
ni "$p\$webvupdate\Commands\$launch" -force >''; sp "$p\$webvupdate\Commands\$launch" 'CommandLine' 'systray.exe' -force
|
|
||||||
}}
|
|
||||||
|
|
||||||
## 7 add bundled OpenWebSearch script to redirect microsoft-edge: anti-competitive links to the default browser
|
|
||||||
$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" # AveYo: minimize prompt - see Terminal issue #13914
|
|
||||||
ni "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" -force >''
|
|
||||||
sp "HKLM:\SOFTWARE\Classes\microsoft-edge" '(Default)' 'URL:microsoft-edge' -force
|
|
||||||
sp "HKLM:\SOFTWARE\Classes\microsoft-edge" 'URL Protocol' '' -force
|
|
||||||
sp "HKLM:\SOFTWARE\Classes\microsoft-edge" 'NoOpenWith' '' -force
|
|
||||||
sp "HKLM:\SOFTWARE\Classes\microsoft-edge\shell\open\command" '(Default)' "`"$DIR\ie_to_edge_stub.exe`" %1" -force
|
|
||||||
ni "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" -force >''
|
|
||||||
sp "HKLM:\SOFTWARE\Classes\MSEdgeHTM" 'NoOpenWith' '' -force
|
|
||||||
sp "HKLM:\SOFTWARE\Classes\MSEdgeHTM\shell\open\command" '(Default)' "`"$DIR\ie_to_edge_stub.exe`" %1" -force
|
|
||||||
ni "$IFEO\ie_to_edge_stub.exe\0" -force >''
|
|
||||||
sp "$IFEO\ie_to_edge_stub.exe" 'UseFilter' 1 -type Dword -force
|
|
||||||
sp "$IFEO\ie_to_edge_stub.exe\0" 'FilterFullPath' "$DIR\ie_to_edge_stub.exe" -force
|
|
||||||
sp "$IFEO\ie_to_edge_stub.exe\0" 'Debugger' "$CMD $DIR\OpenWebSearch.cmd" -force
|
|
||||||
ni "$IFEO\msedge.exe\0" -force >''
|
|
||||||
sp "$IFEO\msedge.exe" 'UseFilter' 1 -type Dword -force
|
|
||||||
sp "$IFEO\msedge.exe\0" 'FilterFullPath' "$MSEP\msedge.exe" -force
|
|
||||||
sp "$IFEO\msedge.exe\0" 'Debugger' "$CMD $DIR\OpenWebSearch.cmd" -force
|
|
||||||
|
|
||||||
$OpenWebSearch = @$
|
|
||||||
@title OpenWebSearch Redux & echo off & set ?= open start menu web search, widgets links or help in your chosen browser - by AveYo
|
|
||||||
for /f %%E in ('"prompt $E$S& for %%e in (1) do rem"') do echo;%%E[2t 2>nul & rem AveYo: minimize prompt
|
|
||||||
call :reg_var "HKCU\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice" ProgID ProgID
|
|
||||||
if /i "%ProgID%" equ "MSEdgeHTM" echo;Default browser is set to Edge! Change it or remove OpenWebSearch script. & pause & exit /b
|
|
||||||
call :reg_var "HKCR\%ProgID%\shell\open\command" "" Browser
|
|
||||||
set Choice=& for %%. in (%Browser%) do if not defined Choice set "Choice=%%~."
|
|
||||||
call :reg_var "HKCR\MSEdgeMHT\shell\open\command" "" FallBack
|
|
||||||
set "Edge=" & for %%. in (%FallBack%) do if not defined Edge set "Edge=%%~."
|
|
||||||
set "URI=" & set "URL=" & set "NOOP=" & set "PassTrough=%Edge:msedge=edge%"
|
|
||||||
set "CLI=%CMDCMDLINE:"=``% "
|
|
||||||
if defined CLI set "CLI=%CLI:*ie_to_edge_stub.exe`` =%"
|
|
||||||
if defined CLI set "CLI=%CLI:*ie_to_edge_stub.exe =%"
|
|
||||||
if defined CLI set "CLI=%CLI:*msedge.exe`` =%"
|
|
||||||
if defined CLI set "CLI=%CLI:*msedge.exe =%"
|
|
||||||
set "FIX=%CLI:~-1%"
|
|
||||||
if defined CLI if "%FIX%"==" " set "CLI=%CLI:~0,-1%"
|
|
||||||
if defined CLI set "RED=%CLI:microsoft-edge=%"
|
|
||||||
if defined CLI set "URL=%CLI:http=%"
|
|
||||||
if defined CLI set "ARG=%CLI:``="%"
|
|
||||||
if "%CLI%" equ "%RED%" (set NOOP=1) else if "%CLI%" equ "%URL%" (set NOOP=1)
|
|
||||||
if defined NOOP if exist "%PassTrough%" start "" "%PassTrough%" %ARG%
|
|
||||||
if defined NOOP exit /b
|
|
||||||
set "URL=%CLI:*microsoft-edge=%"
|
|
||||||
set "URL=http%URL:*http=%"
|
|
||||||
set "FIX=%URL:~-2%"
|
|
||||||
if defined URL if "%FIX%"=="``" set "URL=%URL:~0,-2%"
|
|
||||||
call :dec_url
|
|
||||||
start "" "%Choice%" "%URL%"
|
|
||||||
exit
|
|
||||||
|
|
||||||
:reg_var [USAGE] call :reg_var "HKCU\Volatile Environment" value-or-"" variable [extra options]
|
|
||||||
set {var}=& set {reg}=reg query "%~1" /v %2 /z /se "," /f /e& if %2=="" set {reg}=reg query "%~1" /ve /z /se "," /f /e
|
|
||||||
for /f "skip=2 tokens=* delims=" %%V in ('%{reg}% %4 %5 %6 %7 %8 %9 2^>nul') do if not defined {var} set "{var}=%%V"
|
|
||||||
if not defined {var} (set {reg}=& set "%~3="& exit /b) else if %2=="" set "{var}=%{var}:*) =%"& rem AveYo: v3
|
|
||||||
if not defined {var} (set {reg}=& set "%~3="& exit /b) else set {reg}=& set "%~3=%{var}:*) =%"& set {var}=& exit /b
|
|
||||||
|
|
||||||
:dec_url brute url percent decoding by AveYo
|
|
||||||
set ".=%URL:!=}%"&setlocal enabledelayedexpansion& rem brute url percent decoding
|
|
||||||
set ".=!.:%%={!" &set ".=!.:{3A=:!" &set ".=!.:{2F=/!" &set ".=!.:{3F=?!" &set ".=!.:{23=#!" &set ".=!.:{5B=[!" &set ".=!.:{5D=]!"
|
|
||||||
set ".=!.:{40=@!"&set ".=!.:{21=}!" &set ".=!.:{24=$!" &set ".=!.:{26=&!" &set ".=!.:{27='!" &set ".=!.:{28=(!" &set ".=!.:{29=)!"
|
|
||||||
set ".=!.:{2A=*!"&set ".=!.:{2B=+!" &set ".=!.:{2C=,!" &set ".=!.:{3B=;!" &set ".=!.:{3D==!" &set ".=!.:{25=%%!"&set ".=!.:{20= !"
|
|
||||||
set ".=!.:{=%%!" &rem set ",=!.:%%=!" & if "!,!" neq "!.!" endlocal& set "URL=%.:}=!%" & call :dec_url
|
|
||||||
endlocal& set "URL=%.:}=!%" & exit /b
|
|
||||||
rem done
|
|
||||||
|
|
||||||
$@
|
|
||||||
[io.file]::WriteAllText("$DIR\OpenWebSearch.cmd", $OpenWebSearch)
|
|
||||||
|
|
||||||
## 8 done
|
|
||||||
$done = gp 'Registry::HKEY_Users\S-1-5-21*\Volatile*' Edge_Removal -ea 0; if ($done) {rp $done.PSPath Edge_Removal -force -ea 0}
|
|
||||||
if ((get-process -name 'explorer' -ea 0) -eq $null) {start explorer}
|
|
||||||
|
|
||||||
## 9 bonus enter into powershell console: firefox / edge / webview to install a browser / reinstall edge or webview after removal
|
|
||||||
${.} = [char]27; $firefox = "${.}[38;2;255;165;0m firefox"; $edge = "${.}[94m edge${.}[97m"; $webview = "${.}[94mwebview ${.}[97m"
|
|
||||||
write-host "`n${.}[40;32m EDGE REMOVED! ${.}[97m -GET-ANOTHER-BROWSER? ENTER:$firefox ${.}[97m -REINSTALL? ENTER:$edge / $webview"
|
|
||||||
|
|
||||||
## 0 ask to run script as admin
|
|
||||||
'@.replace("$@","'@").replace("@$","@'") -force -ea 0; $code='gp ''Registry::HKEY_Users\S-1-5-21*\Volatile*'' Edge_Removal -ea 0'
|
|
||||||
start powershell -args "-nop -noe -c & {iex(($code)[0].Edge_Removal)}" -verb runas
|
|
||||||
$_Press_Enter
|
|
||||||
#::
|
|
253
edgeremoval.ps1
@ -1,253 +0,0 @@
|
|||||||
# Script Metadata
|
|
||||||
# Created by AveYo, source: https://raw.githubusercontent.com/AveYo/fox/main/Edge_Removal.bat
|
|
||||||
# Powershell Conversion and Refactor done by Chris Titus Tech
|
|
||||||
|
|
||||||
# Initial Configuration
|
|
||||||
$host.ui.RawUI.WindowTitle = 'Edge Removal - Chris Titus Tech 2023.05.10'
|
|
||||||
$remove_win32 = @("Microsoft Edge", "Microsoft Edge Update")
|
|
||||||
$remove_appx = @("MicrosoftEdge")
|
|
||||||
$skip = @() # Optional: @("DevTools")
|
|
||||||
|
|
||||||
$also_remove_webview = 0
|
|
||||||
if ($also_remove_webview -eq 1) {
|
|
||||||
$remove_win32 += "Microsoft EdgeWebView"
|
|
||||||
$remove_appx += "WebExperience", "Win32WebViewHost"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Administrative Privileges Check
|
|
||||||
$privileges = @(
|
|
||||||
'SeSecurityPrivilege',
|
|
||||||
'SeTakeOwnershipPrivilege',
|
|
||||||
'SeBackupPrivilege',
|
|
||||||
'SeRestorePrivilege'
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach ($privilege in $privileges) {
|
|
||||||
[System.Diagnostics.Process]::SetPrivilege($privilege, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Edge Removal Procedures
|
|
||||||
$processesToShutdown = @(
|
|
||||||
'explorer', 'Widgets', 'widgetservice', 'msedgewebview2', 'MicrosoftEdge*', 'chredge',
|
|
||||||
'msedge', 'edge', 'msteams', 'msfamily', 'WebViewHost', 'Clipchamp'
|
|
||||||
)
|
|
||||||
|
|
||||||
Stop-Process -Name "explorer" -Force -ErrorAction SilentlyContinue
|
|
||||||
$processesToShutdown | ForEach-Object {
|
|
||||||
Stop-Process -Name $_ -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
$MS = ($env:ProgramFiles, ${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem] + '\Microsoft\Edge\Application\msedge.exe'
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
$registryPaths = @('HKLM:\SOFTWARE\Policies', 'HKLM:\SOFTWARE', 'HKLM:\SOFTWARE\WOW6432Node')
|
|
||||||
$edgeProperties = @('InstallDefault', 'Install{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}', 'Install{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}')
|
|
||||||
foreach ($path in $registryPaths) {
|
|
||||||
foreach ($prop in $edgeProperties) {
|
|
||||||
Remove-ItemProperty -Path "$path\Microsoft\EdgeUpdate" -Name $prop -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$edgeupdate = 'Microsoft\EdgeUpdate\Clients\{56EB18F8-B008-4CBD-B6D2-8C97FE7E9062}'
|
|
||||||
$webvupdate = 'Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}'
|
|
||||||
$on_actions = @('on-os-upgrade', 'on-logon', 'on-logon-autolaunch', 'on-logon-startup-boost')
|
|
||||||
$registryBases = @('HKLM:\SOFTWARE', 'HKLM:\SOFTWARE\Wow6432Node')
|
|
||||||
foreach ($base in $registryBases) {
|
|
||||||
foreach ($launch in $on_actions) {
|
|
||||||
Remove-Item -Path "$base\$edgeupdate\Commands\$launch" -Force -ErrorAction SilentlyContinue
|
|
||||||
Remove-Item -Path "$base\$webvupdate\Commands\$launch" -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$registryPaths = @('HKCU:', 'HKLM:')
|
|
||||||
$nodes = @('', '\Wow6432Node')
|
|
||||||
foreach ($regPath in $registryPaths) {
|
|
||||||
foreach ($node in $nodes) {
|
|
||||||
foreach ($i in $remove_win32) {
|
|
||||||
Remove-ItemProperty -Path "$regPath\SOFTWARE${node}\Microsoft\Windows\CurrentVersion\Uninstall\$i" -Name 'NoRemove' -Force -ErrorAction SilentlyContinue
|
|
||||||
New-Item -Path "$regPath\SOFTWARE${node}\Microsoft\EdgeUpdateDev" -Force | Out-Null
|
|
||||||
Set-ItemProperty -Path "$regPath\SOFTWARE${node}\Microsoft\EdgeUpdateDev" -Name 'AllowUninstall' -Value 1 -Type Dword -Force
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$foldersToSearch = @('LocalApplicationData', 'ProgramFilesX86', 'ProgramFiles') | ForEach-Object {
|
|
||||||
[Environment]::GetFolderPath($_)
|
|
||||||
}
|
|
||||||
|
|
||||||
$edges = @()
|
|
||||||
$bhoFiles = @()
|
|
||||||
|
|
||||||
foreach ($folder in $foldersToSearch) {
|
|
||||||
$bhoFiles += Get-ChildItem -Path "$folder\Microsoft\Edge*\ie_to_edge_stub.exe" -Recurse -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
$edges += Get-ChildItem -Path "$folder\Microsoft\Edge*\setup.exe" -Recurse -ErrorAction SilentlyContinue |
|
|
||||||
Where-Object { $_.FullName -notlike '*EdgeWebView*' }
|
|
||||||
}
|
|
||||||
|
|
||||||
$destinationDir = "$env:SystemDrive\Scripts"
|
|
||||||
New-Item -Path $destinationDir -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
|
|
||||||
|
|
||||||
foreach ($bhoFile in $bhoFiles) {
|
|
||||||
if (Test-Path $bhoFile) {
|
|
||||||
try {
|
|
||||||
Copy-Item -Path $bhoFile -Destination "$destinationDir\ie_to_edge_stub.exe" -Force
|
|
||||||
} catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## Work on Appx Removals
|
|
||||||
$provisioned = Get-AppxProvisionedPackage -Online
|
|
||||||
$appxpackage = Get-AppxPackage -AllUsers
|
|
||||||
$eol = @()
|
|
||||||
|
|
||||||
$store = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Store'
|
|
||||||
$storeP = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Store\InstalledApplications'
|
|
||||||
foreach ($app in $appxpackage) {
|
|
||||||
$name = $app.Name
|
|
||||||
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") {
|
|
||||||
$eol += $name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$eolApps = $provisioned | Where-Object { $eol -contains $_.DisplayName }
|
|
||||||
|
|
||||||
foreach ($edge in $eolApps) {
|
|
||||||
$edgeName = $edge.DisplayName
|
|
||||||
if (-not ($skip -contains $edgeName)) {
|
|
||||||
try {
|
|
||||||
Remove-AppxProvisionedPackage -Online -PackageName $edgeName -ErrorAction SilentlyContinue
|
|
||||||
} catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($edge in $appxpackage) {
|
|
||||||
$edgeName = $edge.Name
|
|
||||||
if ($eol -contains $edgeName) {
|
|
||||||
if (-not ($skip -contains $edgeName)) {
|
|
||||||
try {
|
|
||||||
Remove-AppxPackage -Package $edgeName -AllUsers -ErrorAction SilentlyContinue
|
|
||||||
} catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## Redirect shortcuts
|
|
||||||
$shortcut_path = "$env:Public\Desktop"
|
|
||||||
$shortcut_file = 'Microsoft Edge.lnk'
|
|
||||||
$full_path = Join-Path -Path $shortcut_path -ChildPath $shortcut_file
|
|
||||||
|
|
||||||
if (Test-Path $full_path) {
|
|
||||||
Remove-Item -Path $full_path -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
$shortcut_path = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs"
|
|
||||||
$shortcut_file = 'Microsoft Edge.lnk'
|
|
||||||
$full_path = Join-Path -Path $shortcut_path -ChildPath $shortcut_file
|
|
||||||
|
|
||||||
if (Test-Path $full_path) {
|
|
||||||
Remove-Item -Path $full_path -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
$edgePolicy = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge'
|
|
||||||
if (-not (Test-Path $edgePolicy)) {
|
|
||||||
New-Item -Path $edgePolicy -Force | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
$edgePrefs = @{
|
|
||||||
'Dword' = @{
|
|
||||||
'BrowserReplacementEnabled' = 1
|
|
||||||
'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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to remove registry entries related to Microsoft Edge
|
|
||||||
function Remove-EdgeRegistryEntries {
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Create new registry entries
|
|
||||||
$EdgeExecutablePath = ($env:ProgramFiles, ${env:ProgramFiles(x86)})[[Environment]::Is64BitOperatingSystem] + '\Microsoft\Edge\Application\msedge.exe'
|
|
||||||
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 "`"$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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to remove Microsoft Edge AppX packages
|
|
||||||
function Remove-EdgeAppxPackages {
|
|
||||||
$EdgeRemovalOptions.RemoveAppx | ForEach-Object {
|
|
||||||
# Remove provisioned packages
|
|
||||||
Get-AppxProvisionedPackage -Online | Where-Object { $_.PackageName -like "*$_*" -and $EdgeRemovalOptions.Skip -notcontains $_.PackageName } | Remove-AppxProvisionedPackage -Online -AllUsers -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
# Remove installed packages
|
|
||||||
Get-AppxPackage -AllUsers | Where-Object { $_.PackageFullName -like "*$_*" -and $EdgeRemovalOptions.Skip -notcontains $_.PackageFullName } | Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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: $_"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Execute the main function
|
|
||||||
Remove-MicrosoftEdge
|
|
497
functions/microwin/Invoke-Microwin.ps1
Normal file
@ -0,0 +1,497 @@
|
|||||||
|
function Invoke-Microwin {
|
||||||
|
<#
|
||||||
|
.DESCRIPTION
|
||||||
|
Invoke MicroWin routines...
|
||||||
|
#>
|
||||||
|
|
||||||
|
|
||||||
|
if($sync.ProcessRunning) {
|
||||||
|
$msg = "GetIso process is currently running."
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define the constants for Windows API
|
||||||
|
Add-Type @"
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
public class PowerManagement {
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
|
||||||
|
|
||||||
|
[FlagsAttribute]
|
||||||
|
public enum EXECUTION_STATE : uint {
|
||||||
|
ES_SYSTEM_REQUIRED = 0x00000001,
|
||||||
|
ES_DISPLAY_REQUIRED = 0x00000002,
|
||||||
|
ES_CONTINUOUS = 0x80000000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
# Prevent the machine from sleeping
|
||||||
|
[PowerManagement]::SetThreadExecutionState([PowerManagement]::EXECUTION_STATE::ES_CONTINUOUS -bor [PowerManagement]::EXECUTION_STATE::ES_SYSTEM_REQUIRED -bor [PowerManagement]::EXECUTION_STATE::ES_DISPLAY_REQUIRED)
|
||||||
|
|
||||||
|
# Ask the user where to save the file
|
||||||
|
$SaveDialog = New-Object System.Windows.Forms.SaveFileDialog
|
||||||
|
$SaveDialog.InitialDirectory = [Environment]::GetFolderPath('Desktop')
|
||||||
|
$SaveDialog.Filter = "ISO images (*.iso)|*.iso"
|
||||||
|
$SaveDialog.ShowDialog() | Out-Null
|
||||||
|
|
||||||
|
if ($SaveDialog.FileName -eq "") {
|
||||||
|
$msg = "No file name for the target image was specified"
|
||||||
|
Write-Host $msg
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Busy..." -interactive $false
|
||||||
|
|
||||||
|
Write-Host "Target ISO location: $($SaveDialog.FileName)"
|
||||||
|
|
||||||
|
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
|
||||||
|
Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)"
|
||||||
|
|
||||||
|
$copyToUSB = $sync.WPFMicrowinCopyToUsb.IsChecked
|
||||||
|
$injectDrivers = $sync.MicrowinInjectDrivers.IsChecked
|
||||||
|
$importDrivers = $sync.MicrowinImportDrivers.IsChecked
|
||||||
|
|
||||||
|
$importVirtIO = $sync.MicrowinCopyVirtIO.IsChecked
|
||||||
|
|
||||||
|
$mountDir = $sync.MicrowinMountDir.Text
|
||||||
|
$scratchDir = $sync.MicrowinScratchDir.Text
|
||||||
|
|
||||||
|
# Detect if the Windows image is an ESD file and convert it to WIM
|
||||||
|
if (-not (Test-Path -Path "$mountDir\sources\install.wim" -PathType Leaf) -and (Test-Path -Path "$mountDir\sources\install.esd" -PathType Leaf)) {
|
||||||
|
Write-Host "Exporting Windows image to a WIM file, keeping the index we want to work on. This can take several minutes, depending on the performance of your computer..."
|
||||||
|
Export-WindowsImage -SourceImagePath $mountDir\sources\install.esd -SourceIndex $index -DestinationImagePath $mountDir\sources\install.wim -CompressionType "Max"
|
||||||
|
if ($?) {
|
||||||
|
Remove-Item -Path "$mountDir\sources\install.esd" -Force
|
||||||
|
# Since we've already exported the image index we wanted, switch to the first one
|
||||||
|
$index = 1
|
||||||
|
} else {
|
||||||
|
$msg = "The export process has failed and MicroWin processing cannot continue"
|
||||||
|
Write-Host $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$imgVersion = (Get-WindowsImage -ImagePath $mountDir\sources\install.wim -Index $index).Version
|
||||||
|
Write-Host "The Windows Image Build Version is: $imgVersion"
|
||||||
|
|
||||||
|
# Detect image version to avoid performing MicroWin processing on Windows 8 and earlier
|
||||||
|
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,10240,0))) -eq $false) {
|
||||||
|
$msg = "This image is not compatible with MicroWin processing. Make sure it isn't a Windows 8 or earlier image."
|
||||||
|
$dlg_msg = $msg + "`n`nIf you want more information, the version of the image selected is $($imgVersion)`n`nIf an image has been incorrectly marked as incompatible, report an issue to the developers."
|
||||||
|
Write-Host $msg
|
||||||
|
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect whether the image to process contains Windows 10 and show warning
|
||||||
|
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
|
||||||
|
$msg = "Windows 10 has been detected in the image you want to process. While you can continue, Windows 10 is not a recommended target for MicroWin, and you may not get the full experience."
|
||||||
|
$dlg_msg = $msg
|
||||||
|
Write-Host $msg
|
||||||
|
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
|
||||||
|
}
|
||||||
|
|
||||||
|
$mountDirExists = Test-Path $mountDir
|
||||||
|
$scratchDirExists = Test-Path $scratchDir
|
||||||
|
if (-not $mountDirExists -or -not $scratchDirExists) {
|
||||||
|
$msg = "Required directories '$mountDirExists' '$scratchDirExists' and do not exist."
|
||||||
|
Write-Error $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Write-Host "Mounting Windows image. This may take a while."
|
||||||
|
Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir"
|
||||||
|
if ($?) {
|
||||||
|
Write-Host "The Windows image has been mounted successfully. Continuing processing..."
|
||||||
|
} else {
|
||||||
|
$msg = "Could not mount image. Exiting..."
|
||||||
|
Write-Host $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($importDrivers) {
|
||||||
|
Write-Host "Exporting drivers from active installation..."
|
||||||
|
if (Test-Path "$env:TEMP\DRV_EXPORT") {
|
||||||
|
Remove-Item "$env:TEMP\DRV_EXPORT" -Recurse -Force
|
||||||
|
}
|
||||||
|
if (($injectDrivers -and (Test-Path "$($sync.MicrowinDriverLocation.Text)"))) {
|
||||||
|
Write-Host "Using specified driver source..."
|
||||||
|
dism /english /online /export-driver /destination="$($sync.MicrowinDriverLocation.Text)" | Out-Host
|
||||||
|
if ($?) {
|
||||||
|
# Don't add exported drivers yet, that is run later
|
||||||
|
Write-Host "Drivers have been exported successfully."
|
||||||
|
} else {
|
||||||
|
Write-Host "Failed to export drivers."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
New-Item -Path "$env:TEMP\DRV_EXPORT" -ItemType Directory -Force
|
||||||
|
dism /english /online /export-driver /destination="$env:TEMP\DRV_EXPORT" | Out-Host
|
||||||
|
if ($?) {
|
||||||
|
Write-Host "Adding exported drivers..."
|
||||||
|
dism /english /image="$scratchDir" /add-driver /driver="$env:TEMP\DRV_EXPORT" /recurse | Out-Host
|
||||||
|
} else {
|
||||||
|
Write-Host "Failed to export drivers. Continuing without importing them..."
|
||||||
|
}
|
||||||
|
if (Test-Path "$env:TEMP\DRV_EXPORT") {
|
||||||
|
Remove-Item "$env:TEMP\DRV_EXPORT" -Recurse -Force
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($injectDrivers) {
|
||||||
|
$driverPath = $sync.MicrowinDriverLocation.Text
|
||||||
|
if (Test-Path $driverPath) {
|
||||||
|
Write-Host "Adding Windows Drivers image($scratchDir) drivers($driverPath) "
|
||||||
|
dism /English /image:$scratchDir /add-driver /driver:$driverPath /recurse | Out-Host
|
||||||
|
} else {
|
||||||
|
Write-Host "Path to drivers is invalid continuing without driver injection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($importVirtIO) {
|
||||||
|
Write-Host "Copying VirtIO drivers..."
|
||||||
|
Microwin-CopyVirtIO
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Remove Features from the image"
|
||||||
|
Microwin-RemoveFeatures -UseCmdlets $true
|
||||||
|
Write-Host "Removing features complete!"
|
||||||
|
Write-Host "Removing OS packages"
|
||||||
|
Microwin-RemovePackages -UseCmdlets $true
|
||||||
|
Write-Host "Removing Appx Bloat"
|
||||||
|
Microwin-RemoveProvisionedPackages -UseCmdlets $true
|
||||||
|
|
||||||
|
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
|
||||||
|
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
|
||||||
|
try {
|
||||||
|
if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf) {
|
||||||
|
# Found the culprit. Do the following:
|
||||||
|
# 1. Take ownership of the file, from TrustedInstaller to Administrators
|
||||||
|
takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A
|
||||||
|
# 2. Set ACLs so that we can write to it
|
||||||
|
icacls "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /grant "$(Microwin-GetLocalizedUsers -admins $true):(M)" | Out-Host
|
||||||
|
# 3. Open the file and do the modification
|
||||||
|
$appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml"
|
||||||
|
$originalLine = $appxManifest[13]
|
||||||
|
$dependency = "`n <PackageDependency Name=`"Microsoft.WindowsAppRuntime.CBS`" MinVersion=`"1.0.0.0`" Publisher=`"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US`" />"
|
||||||
|
$appxManifest[13] = "$originalLine$dependency"
|
||||||
|
Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
# Fall back to what we used to do: delayed disablement
|
||||||
|
Enable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName "Recall"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe"
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Mail" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Internet Explorer" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Internet Explorer" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\GameBarPresenceWriter"
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDriveSetup.exe"
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDrive.ico"
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*narratorquickstart*" -Directory
|
||||||
|
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
|
||||||
|
Write-Host "Removal complete!"
|
||||||
|
|
||||||
|
Write-Host "Create unattend.xml"
|
||||||
|
|
||||||
|
if ($sync.MicrowinUserName.Text -eq "")
|
||||||
|
{
|
||||||
|
Microwin-NewUnattend -userName "User"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($sync.MicrowinUserPassword.Password -eq "")
|
||||||
|
{
|
||||||
|
Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)" -userPassword "$($sync.MicrowinUserPassword.Password)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Host "Done Create unattend.xml"
|
||||||
|
Write-Host "Copy unattend.xml file into the ISO"
|
||||||
|
New-Item -ItemType Directory -Force -Path "$($scratchDir)\Windows\Panther"
|
||||||
|
Copy-Item "$env:temp\unattend.xml" "$($scratchDir)\Windows\Panther\unattend.xml" -force
|
||||||
|
New-Item -ItemType Directory -Force -Path "$($scratchDir)\Windows\System32\Sysprep"
|
||||||
|
Copy-Item "$env:temp\unattend.xml" "$($scratchDir)\Windows\System32\Sysprep\unattend.xml" -force
|
||||||
|
Copy-Item "$env:temp\unattend.xml" "$($scratchDir)\unattend.xml" -force
|
||||||
|
Write-Host "Done Copy unattend.xml"
|
||||||
|
|
||||||
|
Write-Host "Create FirstRun"
|
||||||
|
Microwin-NewFirstRun
|
||||||
|
Write-Host "Done create FirstRun"
|
||||||
|
Write-Host "Copy FirstRun.ps1 into the ISO"
|
||||||
|
Copy-Item "$env:temp\FirstStartup.ps1" "$($scratchDir)\Windows\FirstStartup.ps1" -force
|
||||||
|
Write-Host "Done copy FirstRun.ps1"
|
||||||
|
|
||||||
|
Write-Host "Copy link to winutil.ps1 into the ISO"
|
||||||
|
$desktopDir = "$($scratchDir)\Windows\Users\Default\Desktop"
|
||||||
|
New-Item -ItemType Directory -Force -Path "$desktopDir"
|
||||||
|
dism /English /image:$($scratchDir) /set-profilepath:"$($scratchDir)\Windows\Users\Default"
|
||||||
|
|
||||||
|
Write-Host "Copy checkinstall.cmd into the ISO"
|
||||||
|
Microwin-NewCheckInstall
|
||||||
|
Copy-Item "$env:temp\checkinstall.cmd" "$($scratchDir)\Windows\checkinstall.cmd" -force
|
||||||
|
Write-Host "Done copy checkinstall.cmd"
|
||||||
|
|
||||||
|
Write-Host "Creating a directory that allows to bypass Wifi setup"
|
||||||
|
New-Item -ItemType Directory -Force -Path "$($scratchDir)\Windows\System32\OOBE\BYPASSNRO"
|
||||||
|
|
||||||
|
Write-Host "Loading registry"
|
||||||
|
reg load HKLM\zCOMPONENTS "$($scratchDir)\Windows\System32\config\COMPONENTS"
|
||||||
|
reg load HKLM\zDEFAULT "$($scratchDir)\Windows\System32\config\default"
|
||||||
|
reg load HKLM\zNTUSER "$($scratchDir)\Users\Default\ntuser.dat"
|
||||||
|
reg load HKLM\zSOFTWARE "$($scratchDir)\Windows\System32\config\SOFTWARE"
|
||||||
|
reg load HKLM\zSYSTEM "$($scratchDir)\Windows\System32\config\SYSTEM"
|
||||||
|
|
||||||
|
Write-Host "Disabling Teams"
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v "ConfigureChatAutoInstall" /t REG_DWORD /d 0 /f >$null 2>&1
|
||||||
|
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat" /v ChatIcon /t REG_DWORD /d 2 /f >$null 2>&1
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "TaskbarMn" /t REG_DWORD /d 0 /f >$null 2>&1
|
||||||
|
reg query "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v "ConfigureChatAutoInstall" >$null 2>&1
|
||||||
|
# Write-Host Error code $LASTEXITCODE
|
||||||
|
Write-Host "Done disabling Teams"
|
||||||
|
|
||||||
|
Write-Host "Fix Windows Volume Mixer Issue"
|
||||||
|
reg add "HKLM\zNTUSER\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore" /f
|
||||||
|
|
||||||
|
Write-Host "Bypassing system requirements (system image)"
|
||||||
|
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassCPUCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassRAMCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassSecureBootCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassStorageCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
|
||||||
|
|
||||||
|
# Prevent Windows Update Installing so called Expedited Apps - 24H2 and newer
|
||||||
|
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
|
||||||
|
@(
|
||||||
|
'EdgeUpdate',
|
||||||
|
'DevHomeUpdate',
|
||||||
|
'OutlookUpdate',
|
||||||
|
'CrossDeviceUpdate'
|
||||||
|
) | ForEach-Object {
|
||||||
|
Write-Host "Removing Windows Expedited App: $_"
|
||||||
|
|
||||||
|
# Copied here After Installation (Online)
|
||||||
|
# reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null
|
||||||
|
|
||||||
|
# When in Offline Image
|
||||||
|
reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f
|
||||||
|
Write-Host "Setting all services to start manually"
|
||||||
|
reg add "HKLM\zSOFTWARE\CurrentControlSet\Services" /v Start /t REG_DWORD /d 3 /f
|
||||||
|
# Write-Host $LASTEXITCODE
|
||||||
|
|
||||||
|
Write-Host "Enabling Local Accounts on OOBE"
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v "BypassNRO" /t REG_DWORD /d "1" /f
|
||||||
|
|
||||||
|
Write-Host "Disabling Sponsored Apps"
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OemPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start" /v "ConfigureStartPins" /t REG_SZ /d '{\"pinnedList\": [{}]}' /f
|
||||||
|
Write-Host "Done removing Sponsored Apps"
|
||||||
|
|
||||||
|
Write-Host "Disabling Reserved Storage"
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager" /v "ShippedWithReserves" /t REG_DWORD /d 0 /f
|
||||||
|
|
||||||
|
Write-Host "Changing theme to dark. This only works on Activated Windows"
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "AppsUseLightTheme" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "SystemUsesLightTheme" /t REG_DWORD /d 0 /f
|
||||||
|
|
||||||
|
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
|
||||||
|
# We're dealing with Windows 10. Configure sane desktop settings. NOTE: even though stuff to disable News and Interests is there,
|
||||||
|
# it doesn't seem to work, and I don't want to waste more time dealing with an operating system that will lose support in a year (2025)
|
||||||
|
|
||||||
|
# I invite anyone to work on improving stuff for News and Interests, but that won't be me!
|
||||||
|
|
||||||
|
Write-Host "Disabling Search Highlights..."
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds\DSB" /v "ShowDynamicContent" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Dsh" /v "AllowNewsAndInterests" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "TraySearchBoxVisible" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Feeds" /v "EnableFeeds" /t REG_DWORD /d 0 /f
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Error "An unexpected error occurred: $_"
|
||||||
|
} finally {
|
||||||
|
Write-Host "Unmounting Registry..."
|
||||||
|
reg unload HKLM\zCOMPONENTS
|
||||||
|
reg unload HKLM\zDEFAULT
|
||||||
|
reg unload HKLM\zNTUSER
|
||||||
|
reg unload HKLM\zSOFTWARE
|
||||||
|
reg unload HKLM\zSYSTEM
|
||||||
|
|
||||||
|
Write-Host "Cleaning up image..."
|
||||||
|
dism /English /image:$scratchDir /Cleanup-Image /StartComponentCleanup /ResetBase
|
||||||
|
Write-Host "Cleanup complete."
|
||||||
|
|
||||||
|
Write-Host "Unmounting image..."
|
||||||
|
Dismount-WindowsImage -Path "$scratchDir" -Save
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Write-Host "Exporting image into $mountDir\sources\install2.wim"
|
||||||
|
Export-WindowsImage -SourceImagePath "$mountDir\sources\install.wim" -SourceIndex $index -DestinationImagePath "$mountDir\sources\install2.wim" -CompressionType "Max"
|
||||||
|
Write-Host "Remove old '$mountDir\sources\install.wim' and rename $mountDir\sources\install2.wim"
|
||||||
|
Remove-Item "$mountDir\sources\install.wim"
|
||||||
|
Rename-Item "$mountDir\sources\install2.wim" "$mountDir\sources\install.wim"
|
||||||
|
|
||||||
|
if (-not (Test-Path -Path "$mountDir\sources\install.wim")) {
|
||||||
|
$msg = "Something went wrong. Please report this bug to the devs."
|
||||||
|
Write-Error "$($msg) '$($mountDir)\sources\install.wim' doesn't exist"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Write-Host "Windows image completed. Continuing with boot.wim."
|
||||||
|
|
||||||
|
# Next step boot image
|
||||||
|
Write-Host "Mounting boot image $mountDir\sources\boot.wim into $scratchDir"
|
||||||
|
Mount-WindowsImage -ImagePath "$mountDir\sources\boot.wim" -Index 2 -Path "$scratchDir"
|
||||||
|
|
||||||
|
if ($injectDrivers) {
|
||||||
|
$driverPath = $sync.MicrowinDriverLocation.Text
|
||||||
|
if (Test-Path $driverPath) {
|
||||||
|
Write-Host "Adding Windows Drivers image($scratchDir) drivers($driverPath) "
|
||||||
|
dism /English /image:$scratchDir /add-driver /driver:$driverPath /recurse | Out-Host
|
||||||
|
} else {
|
||||||
|
Write-Host "Path to drivers is invalid continuing without driver injection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Loading registry..."
|
||||||
|
reg load HKLM\zCOMPONENTS "$($scratchDir)\Windows\System32\config\COMPONENTS" >$null
|
||||||
|
reg load HKLM\zDEFAULT "$($scratchDir)\Windows\System32\config\default" >$null
|
||||||
|
reg load HKLM\zNTUSER "$($scratchDir)\Users\Default\ntuser.dat" >$null
|
||||||
|
reg load HKLM\zSOFTWARE "$($scratchDir)\Windows\System32\config\SOFTWARE" >$null
|
||||||
|
reg load HKLM\zSYSTEM "$($scratchDir)\Windows\System32\config\SYSTEM" >$null
|
||||||
|
Write-Host "Bypassing system requirements on the setup image"
|
||||||
|
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassCPUCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassRAMCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassSecureBootCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassStorageCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /t REG_DWORD /d 1 /f
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
|
||||||
|
# Fix Computer Restarted Unexpectedly Error on New Bare Metal Install
|
||||||
|
reg add "HKLM\zSYSTEM\Setup\Status\ChildCompletion" /v "setup.exe" /t REG_DWORD /d 3 /f
|
||||||
|
} catch {
|
||||||
|
Write-Error "An unexpected error occurred: $_"
|
||||||
|
} finally {
|
||||||
|
Write-Host "Unmounting Registry..."
|
||||||
|
reg unload HKLM\zCOMPONENTS
|
||||||
|
reg unload HKLM\zDEFAULT
|
||||||
|
reg unload HKLM\zNTUSER
|
||||||
|
reg unload HKLM\zSOFTWARE
|
||||||
|
reg unload HKLM\zSYSTEM
|
||||||
|
|
||||||
|
Write-Host "Unmounting image..."
|
||||||
|
Dismount-WindowsImage -Path "$scratchDir" -Save
|
||||||
|
|
||||||
|
Write-Host "Creating ISO image"
|
||||||
|
|
||||||
|
# if we downloaded oscdimg from github it will be in the temp directory so use it
|
||||||
|
# if it is not in temp it is part of ADK and is in global PATH so just set it to oscdimg.exe
|
||||||
|
$oscdimgPath = Join-Path $env:TEMP 'oscdimg.exe'
|
||||||
|
$oscdImgFound = Test-Path $oscdimgPath -PathType Leaf
|
||||||
|
if (!$oscdImgFound) {
|
||||||
|
$oscdimgPath = "oscdimg.exe"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "[INFO] Using oscdimg.exe from: $oscdimgPath"
|
||||||
|
|
||||||
|
$oscdimgProc = Start-Process -FilePath "$oscdimgPath" -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b`"$mountDir\boot\etfsboot.com`"#pEF,e,b`"$mountDir\efi\microsoft\boot\efisys.bin`" `"$mountDir`" `"$($SaveDialog.FileName)`"" -Wait -PassThru -NoNewWindow
|
||||||
|
|
||||||
|
$LASTEXITCODE = $oscdimgProc.ExitCode
|
||||||
|
|
||||||
|
Write-Host "OSCDIMG Error Level : $($oscdimgProc.ExitCode)"
|
||||||
|
|
||||||
|
if ($copyToUSB) {
|
||||||
|
Write-Host "Copying target ISO to the USB drive"
|
||||||
|
Microwin-CopyToUSB("$($SaveDialog.FileName)")
|
||||||
|
if ($?) { Write-Host "Done Copying target ISO to USB drive!" } else { Write-Host "ISO copy failed." }
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host " _____ "
|
||||||
|
Write-Host "(____ \ "
|
||||||
|
Write-Host " _ \ \ ___ ____ ____ "
|
||||||
|
Write-Host "| | | / _ \| _ \ / _ ) "
|
||||||
|
Write-Host "| |__/ / |_| | | | ( (/ / "
|
||||||
|
Write-Host "|_____/ \___/|_| |_|\____) "
|
||||||
|
|
||||||
|
# Check if the ISO was successfully created - CTT edit
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "`n`nPerforming Cleanup..."
|
||||||
|
Remove-Item -Recurse -Force "$($scratchDir)"
|
||||||
|
Remove-Item -Recurse -Force "$($mountDir)"
|
||||||
|
$msg = "Done. ISO image is located here: $($SaveDialog.FileName)"
|
||||||
|
Write-Host $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
|
||||||
|
Invoke-MicrowinBusyInfo -action "done" -message "Finished!"
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information)
|
||||||
|
} else {
|
||||||
|
Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed."
|
||||||
|
try {
|
||||||
|
# This creates a new Win32 exception from which we can extract a message in the system language.
|
||||||
|
# Now, this will NOT throw an exception
|
||||||
|
$exitCode = New-Object System.ComponentModel.Win32Exception($LASTEXITCODE)
|
||||||
|
Write-Host "Reason: $($exitCode.Message)"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $exitCode.Message
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
} catch {
|
||||||
|
# Could not get error description from Windows APIs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Toggle-MicrowinPanel 1
|
||||||
|
|
||||||
|
#$sync.MicrowinFinalIsoLocation.Text = "$env:temp\microwin.iso"
|
||||||
|
$sync.MicrowinFinalIsoLocation.Text = "$($SaveDialog.FileName)"
|
||||||
|
# Allow the machine to sleep again (optional)
|
||||||
|
[PowerManagement]::SetThreadExecutionState(0)
|
||||||
|
$sync.ProcessRunning = $false
|
||||||
|
}
|
||||||
|
}
|
65
functions/microwin/Invoke-MicrowinBusyInfo.ps1
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
function Invoke-MicrowinBusyInfo {
|
||||||
|
<#
|
||||||
|
.DESCRIPTION
|
||||||
|
Function to display the busy info for the Microwin process
|
||||||
|
#>
|
||||||
|
[CmdletBinding(DefaultParameterSetName='done')]
|
||||||
|
param(
|
||||||
|
[Parameter(ParameterSetName='wip', Mandatory, Position = 0)]
|
||||||
|
[Parameter(ParameterSetName='warning', Mandatory, Position = 0)]
|
||||||
|
[Parameter(ParameterSetName='done', Mandatory, Position = 0)]
|
||||||
|
[Parameter(ParameterSetName='hide', Mandatory, Position = 0)]
|
||||||
|
[ValidateSet('wip', 'warning', 'done', 'hide')]
|
||||||
|
[string]$action,
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName='wip', Mandatory, Position = 1)]
|
||||||
|
[Parameter(ParameterSetName='warning', Mandatory, Position = 1)]
|
||||||
|
[Parameter(ParameterSetName='done', Mandatory, Position = 1)]
|
||||||
|
[string]$message,
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName='wip', Position = 2)] [bool]$interactive = $false
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ($action) {
|
||||||
|
"wip" {
|
||||||
|
$sync.form.Dispatcher.BeginInvoke([action]{
|
||||||
|
$sync.MicrowinBusyIndicator.Visibility="Visible"
|
||||||
|
$finalMessage = ""
|
||||||
|
if ($interactive -eq $false) {
|
||||||
|
$finalMessage += "Please wait. "
|
||||||
|
}
|
||||||
|
$finalMessage += $message
|
||||||
|
$sync.BusyText.Text = $finalMessage
|
||||||
|
$sync.BusyIcon.Foreground="#FFA500"
|
||||||
|
$sync.BusyText.Foreground="#FFA500"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"warning" {
|
||||||
|
$sync.form.Dispatcher.BeginInvoke([action]{
|
||||||
|
$sync.MicrowinBusyIndicator.Visibility="Visible"
|
||||||
|
$sync.BusyText.Text=$message
|
||||||
|
$sync.BusyText.Foreground="#FF0000"
|
||||||
|
$sync.BusyIcon.Foreground="#FF0000"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"done" {
|
||||||
|
$sync.form.Dispatcher.BeginInvoke([action]{
|
||||||
|
$sync.MicrowinBusyIndicator.Visibility="Visible"
|
||||||
|
$sync.BusyText.Text=$message
|
||||||
|
$sync.BusyText.Foreground="#00FF00"
|
||||||
|
$sync.BusyIcon.Foreground="#00FF00"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"hide" {
|
||||||
|
$sync.form.Dispatcher.BeginInvoke([action]{
|
||||||
|
$sync.MicrowinBusyIndicator.Visibility="Hidden"
|
||||||
|
$sync.BusyText.Foreground=$sync.Form.Resources.MicrowinBusyColor
|
||||||
|
$sync.BusyIcon.Foreground=$sync.Form.Resources.MicrowinBusyColor
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Force the UI to process pending messages
|
||||||
|
[System.Windows.Forms.Application]::DoEvents()
|
||||||
|
Start-Sleep -Milliseconds 50
|
||||||
|
}
|
339
functions/microwin/Invoke-MicrowinGetIso.ps1
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
function Invoke-MicrowinGetIso {
|
||||||
|
<#
|
||||||
|
.DESCRIPTION
|
||||||
|
Function to get the path to Iso file for MicroWin, unpack that isom=, read basic information and populate the UI Options
|
||||||
|
#>
|
||||||
|
|
||||||
|
Write-Host "Invoking WPFGetIso"
|
||||||
|
|
||||||
|
if($sync.ProcessRunning) {
|
||||||
|
$msg = "GetIso process is currently running."
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Provide immediate feedback to user
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Initializing MicroWin process..." -interactive $false
|
||||||
|
|
||||||
|
Write-Host " _ __ __ _ "
|
||||||
|
Write-Host " /\/\ (_) ___ _ __ ___ / / /\ \ \(_) _ __ "
|
||||||
|
Write-Host " / \ | | / __|| '__| / _ \ \ \/ \/ /| || '_ \ "
|
||||||
|
Write-Host "/ /\/\ \| || (__ | | | (_) | \ /\ / | || | | | "
|
||||||
|
Write-Host "\/ \/|_| \___||_| \___/ \/ \/ |_||_| |_| "
|
||||||
|
|
||||||
|
if ($sync["ISOmanual"].IsChecked) {
|
||||||
|
# Open file dialog to let user choose the ISO file
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Please select an ISO file..." -interactive $true
|
||||||
|
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
|
||||||
|
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
|
||||||
|
$openFileDialog.initialDirectory = $initialDirectory
|
||||||
|
$openFileDialog.filter = "ISO files (*.iso)| *.iso"
|
||||||
|
$openFileDialog.ShowDialog() | Out-Null
|
||||||
|
$filePath = $openFileDialog.FileName
|
||||||
|
|
||||||
|
if ([string]::IsNullOrEmpty($filePath)) {
|
||||||
|
Write-Host "No ISO is chosen"
|
||||||
|
Invoke-MicrowinBusyInfo -action "hide" -message " "
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ($sync["ISOdownloader"].IsChecked) {
|
||||||
|
# Create folder browsers for user-specified locations
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Please select download location..." -interactive $true
|
||||||
|
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
|
||||||
|
$isoDownloaderFBD = New-Object System.Windows.Forms.FolderBrowserDialog
|
||||||
|
$isoDownloaderFBD.Description = "Please specify the path to download the ISO file to:"
|
||||||
|
$isoDownloaderFBD.ShowNewFolderButton = $true
|
||||||
|
if ($isoDownloaderFBD.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK)
|
||||||
|
{
|
||||||
|
Invoke-MicrowinBusyInfo -action "hide" -message " "
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Preparing to download ISO..." -interactive $false
|
||||||
|
|
||||||
|
# Grab the location of the selected path
|
||||||
|
$targetFolder = $isoDownloaderFBD.SelectedPath
|
||||||
|
|
||||||
|
# Auto download newest ISO
|
||||||
|
# Credit: https://github.com/pbatard/Fido
|
||||||
|
$fidopath = "$env:temp\Fido.ps1"
|
||||||
|
$originalLocation = $PSScriptRoot
|
||||||
|
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Downloading Fido script..." -interactive $false
|
||||||
|
Invoke-WebRequest "https://github.com/pbatard/Fido/raw/master/Fido.ps1" -OutFile $fidopath
|
||||||
|
|
||||||
|
Set-Location -Path $env:temp
|
||||||
|
# Detect if the first option ("System language") has been selected and get a Fido-approved language from the current culture
|
||||||
|
$lang = if ($sync["ISOLanguage"].SelectedIndex -eq 0) {
|
||||||
|
Microwin-GetLangFromCulture -langName (Get-Culture).Name
|
||||||
|
} else {
|
||||||
|
$sync["ISOLanguage"].SelectedItem
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Downloading Windows ISO... (This may take a long time)" -interactive $false
|
||||||
|
& $fidopath -Win 'Windows 11' -Rel $sync["ISORelease"].SelectedItem -Arch "x64" -Lang $lang -Ed "Windows 11 Home/Pro/Edu"
|
||||||
|
if (-not $?)
|
||||||
|
{
|
||||||
|
Write-Host "Could not download the ISO file. Look at the output of the console for more information."
|
||||||
|
$msg = "The ISO file could not be downloaded"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Set-Location $originalLocation
|
||||||
|
# Use the FullName property to only grab the file names. Using this property is necessary as, without it, you're passing the usual output of Get-ChildItem
|
||||||
|
# to the variable, and let's be honest, that does NOT exist in the file system
|
||||||
|
$filePath = (Get-ChildItem -Path "$env:temp" -Filter "Win11*.iso").FullName | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||||
|
$fileName = [IO.Path]::GetFileName("$filePath")
|
||||||
|
|
||||||
|
if (($targetFolder -ne "") -and (Test-Path "$targetFolder"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
# "Let it download to $env:TEMP and then we **move** it to the file path." - CodingWonders
|
||||||
|
$destinationFilePath = "$targetFolder\$fileName"
|
||||||
|
Write-Host "Moving ISO file. Please wait..."
|
||||||
|
Move-Item -Path "$filePath" -Destination "$destinationFilePath" -Force
|
||||||
|
$filePath = $destinationFilePath
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
$msg = "Unable to move the ISO file to the location you specified. The downloaded ISO is in the `"$env:TEMP`" folder"
|
||||||
|
Write-Host $msg
|
||||||
|
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "File path $($filePath)"
|
||||||
|
if (-not (Test-Path -Path "$filePath" -PathType Leaf)) {
|
||||||
|
$msg = "File you've chosen doesn't exist"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo"
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Checking system requirements..." -interactive $false
|
||||||
|
|
||||||
|
$oscdimgPath = Join-Path $env:TEMP 'oscdimg.exe'
|
||||||
|
$oscdImgFound = [bool] (Get-Command -ErrorAction Ignore -Type Application oscdimg.exe) -or (Test-Path $oscdimgPath -PathType Leaf)
|
||||||
|
Write-Host "oscdimg.exe on system: $oscdImgFound"
|
||||||
|
|
||||||
|
if (!$oscdImgFound) {
|
||||||
|
$downloadFromGitHub = $sync.WPFMicrowinDownloadFromGitHub.IsChecked
|
||||||
|
|
||||||
|
if (!$downloadFromGitHub) {
|
||||||
|
# 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
|
||||||
|
[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
|
||||||
|
# Install Choco if not already present
|
||||||
|
Install-WinUtilChoco
|
||||||
|
$chocoFound = [bool] (Get-Command -ErrorAction Ignore -Type Application choco)
|
||||||
|
Write-Host "choco on system: $chocoFound"
|
||||||
|
if (!$chocoFound) {
|
||||||
|
[System.Windows.MessageBox]::Show("choco.exe is not found on the system, you need choco to download oscdimg.exe")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Start-Process -Verb runas -FilePath powershell.exe -ArgumentList "choco install windows-adk-oscdimg"
|
||||||
|
$msg = "oscdimg is installed, now close, reopen PowerShell terminal and re-launch winutil.ps1"
|
||||||
|
Invoke-MicrowinBusyInfo -action "done" -message $msg # We set it to done because it immediately returns from this function
|
||||||
|
[System.Windows.MessageBox]::Show($msg)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
[System.Windows.MessageBox]::Show("oscdimge.exe is not found on the system, winutil will now attempt do download and install it from github. This might take a long time.")
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Downloading oscdimg.exe..." -interactive $false
|
||||||
|
Microwin-GetOscdimg -oscdimgPath $oscdimgPath
|
||||||
|
$oscdImgFound = Test-Path $oscdimgPath -PathType Leaf
|
||||||
|
if (!$oscdImgFound) {
|
||||||
|
$msg = "oscdimg was not downloaded can not proceed"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
Write-Host "oscdimg.exe was successfully downloaded from github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Checking disk space..." -interactive $false
|
||||||
|
|
||||||
|
# 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
|
||||||
|
$msg = "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."
|
||||||
|
Write-Host $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
Write-Host "You have enough space for this operation."
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Mounting ISO file..." -interactive $false
|
||||||
|
Write-Host "Mounting Iso. Please wait."
|
||||||
|
$mountedISO = Mount-DiskImage -PassThru "$filePath"
|
||||||
|
Write-Host "Done mounting Iso `"$($mountedISO.ImagePath)`""
|
||||||
|
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
|
||||||
|
Write-Host "Iso mounted to '$driveLetter'"
|
||||||
|
} catch {
|
||||||
|
# @ChrisTitusTech please copy this wiki and change the link below to your copy of the wiki
|
||||||
|
$msg = "Failed to mount the image. Error: $($_.Exception.Message)"
|
||||||
|
Write-Error $msg
|
||||||
|
Write-Error "This is NOT winutil's problem, your ISO might be corrupt, or there is a problem on the system"
|
||||||
|
Write-Host "Please refer to this wiki for more details: https://christitustech.github.io/winutil/KnownIssues/#troubleshoot-errors-during-microwin-usage" -ForegroundColor Red
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# storing off values in hidden fields for further steps
|
||||||
|
# there is probably a better way of doing this, I don't have time to figure this out
|
||||||
|
$sync.MicrowinIsoDrive.Text = $driveLetter
|
||||||
|
|
||||||
|
$mountedISOPath = (Split-Path -Path "$filePath")
|
||||||
|
if ($sync.MicrowinScratchDirBox.Text.Trim() -eq "Scratch") {
|
||||||
|
$sync.MicrowinScratchDirBox.Text =""
|
||||||
|
}
|
||||||
|
|
||||||
|
$UseISOScratchDir = $sync.WPFMicrowinISOScratchDir.IsChecked
|
||||||
|
|
||||||
|
if ($UseISOScratchDir) {
|
||||||
|
$sync.MicrowinScratchDirBox.Text=$mountedISOPath
|
||||||
|
}
|
||||||
|
|
||||||
|
if( -Not $sync.MicrowinScratchDirBox.Text.EndsWith('\') -And $sync.MicrowinScratchDirBox.Text.Length -gt 1) {
|
||||||
|
|
||||||
|
$sync.MicrowinScratchDirBox.Text = Join-Path $sync.MicrowinScratchDirBox.Text.Trim() '\'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||||
|
$randomNumber = Get-Random -Minimum 1 -Maximum 9999
|
||||||
|
$randomMicrowin = "Microwin_${timestamp}_${randomNumber}"
|
||||||
|
$randomMicrowinScratch = "MicrowinScratch_${timestamp}_${randomNumber}"
|
||||||
|
$sync.BusyText.Text=" - Mounting"
|
||||||
|
Write-Host "Mounting Iso. Please wait."
|
||||||
|
if ($sync.MicrowinScratchDirBox.Text -eq "") {
|
||||||
|
$mountDir = Join-Path $env:TEMP $randomMicrowin
|
||||||
|
$scratchDir = Join-Path $env:TEMP $randomMicrowinScratch
|
||||||
|
} else {
|
||||||
|
$scratchDir = $sync.MicrowinScratchDirBox.Text+"Scratch"
|
||||||
|
$mountDir = $sync.MicrowinScratchDirBox.Text+"micro"
|
||||||
|
}
|
||||||
|
|
||||||
|
$sync.MicrowinMountDir.Text = $mountDir
|
||||||
|
$sync.MicrowinScratchDir.Text = $scratchDir
|
||||||
|
Write-Host "Done setting up mount dir and scratch dirs"
|
||||||
|
Write-Host "Scratch dir is $scratchDir"
|
||||||
|
Write-Host "Image dir is $mountDir"
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
#$data = @($driveLetter, $filePath)
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Creating directories..." -interactive $false
|
||||||
|
New-Item -ItemType Directory -Force -Path "$($mountDir)" | Out-Null
|
||||||
|
New-Item -ItemType Directory -Force -Path "$($scratchDir)" | Out-Null
|
||||||
|
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Copying Windows files... (This may take several minutes)" -interactive $false
|
||||||
|
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.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null
|
||||||
|
$totalTime = Measure-Command {
|
||||||
|
Copy-Files "$($driveLetter):" "$mountDir" -Recurse -Force
|
||||||
|
# Force UI update during long operation
|
||||||
|
[System.Windows.Forms.Application]::DoEvents()
|
||||||
|
}
|
||||||
|
Write-Host "Copy complete! Total Time: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds"
|
||||||
|
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Processing Windows image..." -interactive $false
|
||||||
|
$wimFile = "$mountDir\sources\install.wim"
|
||||||
|
Write-Host "Getting image information $wimFile"
|
||||||
|
|
||||||
|
if ((-not (Test-Path -Path "$wimFile" -PathType Leaf)) -and (-not (Test-Path -Path "$($wimFile.Replace(".wim", ".esd").Trim())" -PathType Leaf))) {
|
||||||
|
$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."
|
||||||
|
Write-Host "$($msg) Only use 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/"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message $msg
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
|
||||||
|
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()
|
||||||
|
Get-WindowsImage -ImagePath $wimFile | ForEach-Object {
|
||||||
|
$imageIdx = $_.ImageIndex
|
||||||
|
$imageName = $_.ImageName
|
||||||
|
$sync.MicrowinWindowsFlavors.Items.Add("$imageIdx : $imageName")
|
||||||
|
}
|
||||||
|
[System.Windows.Forms.Application]::DoEvents()
|
||||||
|
|
||||||
|
$sync.MicrowinWindowsFlavors.SelectedIndex = 0
|
||||||
|
Write-Host "Finding suitable Pro edition. This can take some time. Do note that this is an automatic process that might not select the edition you want."
|
||||||
|
Invoke-MicrowinBusyInfo -action "wip" -message "Finding suitable Pro edition..." -interactive $false
|
||||||
|
|
||||||
|
Get-WindowsImage -ImagePath $wimFile | ForEach-Object {
|
||||||
|
if ((Get-WindowsImage -ImagePath $wimFile -Index $_.ImageIndex).EditionId -eq "Professional") {
|
||||||
|
# We have found the Pro edition
|
||||||
|
$sync.MicrowinWindowsFlavors.SelectedIndex = $_.ImageIndex - 1
|
||||||
|
}
|
||||||
|
# Allow UI updates during this loop
|
||||||
|
[System.Windows.Forms.Application]::DoEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
|
||||||
|
Write-Host "Selected value '$($sync.MicrowinWindowsFlavors.SelectedValue)'....."
|
||||||
|
|
||||||
|
Toggle-MicrowinPanel 2
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
Write-Host "Dismounting bad image..."
|
||||||
|
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
|
||||||
|
Remove-Item -Recurse -Force "$($scratchDir)"
|
||||||
|
Remove-Item -Recurse -Force "$($mountDir)"
|
||||||
|
Invoke-MicrowinBusyInfo -action "warning" -message "Failed to read and unpack ISO"
|
||||||
|
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Done reading and unpacking ISO"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "*********************************"
|
||||||
|
Write-Host "Check the UI for further steps!!!"
|
||||||
|
|
||||||
|
Invoke-MicrowinBusyInfo -action "done" -message "Done! Proceed with customization."
|
||||||
|
$sync.ProcessRunning = $false
|
||||||
|
Set-WinUtilTaskbaritem -state "None" -overlay "checkmark"
|
||||||
|
}
|
10
functions/microwin/Microwin-Classes.ps1
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class ErroredPackage {
|
||||||
|
[string]$PackageName
|
||||||
|
[string]$ErrorMessage
|
||||||
|
ErroredPackage() { $this.Init(@{} )}
|
||||||
|
# Constructor for packages that have errored out
|
||||||
|
ErroredPackage([string]$pkgName, [string]$reason) {
|
||||||
|
$this.PackageName = $pkgName
|
||||||
|
$this.ErrorMessage = $reason
|
||||||
|
}
|
||||||
|
}
|
71
functions/microwin/Microwin-CopyToUSB.ps1
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
function Microwin-CopyToUSB([string]$fileToCopy) {
|
||||||
|
foreach ($volume in Get-Volume) {
|
||||||
|
if ($volume -and $volume.FileSystemLabel -ieq "ventoy") {
|
||||||
|
$destinationPath = "$($volume.DriveLetter):\"
|
||||||
|
#Copy-Item -Path $fileToCopy -Destination $destinationPath -Force
|
||||||
|
# Get the total size of the file
|
||||||
|
$totalSize = (Get-Item "$fileToCopy").length
|
||||||
|
|
||||||
|
Copy-Item -Path "$fileToCopy" -Destination "$destinationPath" -Verbose -Force -Recurse -Container -PassThru |
|
||||||
|
ForEach-Object {
|
||||||
|
# Calculate the percentage completed
|
||||||
|
$completed = ($_.BytesTransferred / $totalSize) * 100
|
||||||
|
|
||||||
|
# Display the progress bar
|
||||||
|
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.DriveLetter)"
|
||||||
|
|
||||||
|
# Detect if config files are present, move them if they are, and configure the Ventoy drive to not bypass the requirements
|
||||||
|
$customVentoyConfig = @'
|
||||||
|
{
|
||||||
|
"control":[
|
||||||
|
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
|
||||||
|
{ "VTOY_WIN11_BYPASS_NRO": "0" }
|
||||||
|
],
|
||||||
|
"control_legacy":[
|
||||||
|
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
|
||||||
|
{ "VTOY_WIN11_BYPASS_NRO": "0" }
|
||||||
|
],
|
||||||
|
"control_uefi":[
|
||||||
|
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
|
||||||
|
{ "VTOY_WIN11_BYPASS_NRO": "0" }
|
||||||
|
],
|
||||||
|
"control_ia32":[
|
||||||
|
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
|
||||||
|
{ "VTOY_WIN11_BYPASS_NRO": "0" }
|
||||||
|
],
|
||||||
|
"control_aa64":[
|
||||||
|
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
|
||||||
|
{ "VTOY_WIN11_BYPASS_NRO": "0" }
|
||||||
|
],
|
||||||
|
"control_mips":[
|
||||||
|
{ "VTOY_WIN11_BYPASS_CHECK": "0" },
|
||||||
|
{ "VTOY_WIN11_BYPASS_NRO": "0" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
'@
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Host "Writing custom Ventoy configuration. Please wait..."
|
||||||
|
if (Test-Path -Path "$($volume.DriveLetter):\ventoy\ventoy.json" -PathType Leaf) {
|
||||||
|
Write-Host "A Ventoy configuration file exists. Moving it..."
|
||||||
|
Move-Item -Path "$($volume.DriveLetter):\ventoy\ventoy.json" -Destination "$($volume.DriveLetter):\ventoy\ventoy.json.old" -Force
|
||||||
|
Write-Host "Existing Ventoy configuration has been moved to `"ventoy.json.old`". Feel free to put your config back into the `"ventoy.json`" file."
|
||||||
|
}
|
||||||
|
if (-not (Test-Path -Path "$($volume.DriveLetter):\ventoy")) {
|
||||||
|
New-Item -Path "$($volume.DriveLetter):\ventoy" -ItemType Directory -Force | Out-Null
|
||||||
|
}
|
||||||
|
$customVentoyConfig | Out-File -FilePath "$($volume.DriveLetter):\ventoy\ventoy.json" -Encoding utf8 -Force
|
||||||
|
Write-Host "The Ventoy drive has been successfully configured."
|
||||||
|
} catch {
|
||||||
|
Write-Host "Could not configure Ventoy drive. Error: $($_.Exception.Message)`n"
|
||||||
|
Write-Host "Be sure to add the following configuration to the Ventoy drive by either creating a `"ventoy.json`" file in the `"ventoy`" directory (create it if it doesn't exist) or by editing an existing one: `n`n$customVentoyConfig`n"
|
||||||
|
Write-Host "Failure to do this will cause conflicts with your target ISO file."
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Host "Ventoy USB Key is not inserted"
|
||||||
|
}
|
40
functions/microwin/Microwin-CopyVirtIO.ps1
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
function Microwin-CopyVirtIO {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Downloads and copies the VirtIO Guest Tools drivers to the target MicroWin ISO
|
||||||
|
.NOTES
|
||||||
|
A network connection must be available and the servers of Fedora People must be up. Automatic driver installation will not be added yet - I want this implementation to be reliable.
|
||||||
|
#>
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Host "Checking existing files..."
|
||||||
|
if (Test-Path -Path "$($env:TEMP)\virtio.iso" -PathType Leaf) {
|
||||||
|
Write-Host "VirtIO ISO has been detected. Deleting..."
|
||||||
|
Remove-Item -Path "$($env:TEMP)\virtio.iso" -Force
|
||||||
|
}
|
||||||
|
Write-Host "Getting latest VirtIO drivers. Please wait. This can take some time, depending on your network connection speed and the speed of the servers..."
|
||||||
|
Start-BitsTransfer -Source "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" -Destination "$($env:TEMP)\virtio.iso" -DisplayName "Downloading VirtIO drivers..."
|
||||||
|
# Do everything else if the VirtIO ISO exists
|
||||||
|
if (Test-Path -Path "$($env:TEMP)\virtio.iso" -PathType Leaf) {
|
||||||
|
Write-Host "Mounting ISO. Please wait."
|
||||||
|
$virtIO_ISO = Mount-DiskImage -PassThru "$($env:TEMP)\virtio.iso"
|
||||||
|
$driveLetter = (Get-Volume -DiskImage $virtIO_ISO).DriveLetter
|
||||||
|
# Create new directory for VirtIO on ISO
|
||||||
|
New-Item -Path "$mountDir\VirtIO" -ItemType Directory | Out-Null
|
||||||
|
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" "$mountDir\VirtIO" -Recurse -Force }
|
||||||
|
Write-Host "VirtIO contents have been successfully copied. Time taken: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds`n"
|
||||||
|
Get-Volume $driveLetter | Get-DiskImage | Dismount-DiskImage
|
||||||
|
Remove-Item -Path "$($env:TEMP)\virtio.iso" -Force -ErrorAction SilentlyContinue
|
||||||
|
Write-Host "To proceed with installation of the MicroWin image in QEMU/Proxmox VE:"
|
||||||
|
Write-Host "1. Proceed with Setup until you reach the disk selection screen, in which you won't see any drives"
|
||||||
|
Write-Host "2. Click `"Load Driver`" and click Browse"
|
||||||
|
Write-Host "3. In the folder selection dialog, point to this path:`n`n `"D:\VirtIO\vioscsi\w11\amd64`" (replace amd64 with ARM64 if you are using Windows on ARM, and `"D:`" with the drive letter of the ISO)`n"
|
||||||
|
Write-Host "4. Select all drivers that will appear in the list box and click OK"
|
||||||
|
} else {
|
||||||
|
throw "Could not download VirtIO drivers"
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "We could not download and/or prepare the VirtIO drivers. Error information: $_`n"
|
||||||
|
Write-Host "You will need to download these drivers manually. Location: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso"
|
||||||
|
}
|
||||||
|
}
|
49
functions/microwin/Microwin-GetLangFromCulture.ps1
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
function Microwin-GetLangFromCulture {
|
||||||
|
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory, Position = 0)] [string]$langName
|
||||||
|
)
|
||||||
|
|
||||||
|
switch -Wildcard ($langName)
|
||||||
|
{
|
||||||
|
"ar*" { return "Arabic" }
|
||||||
|
"pt-BR" { return "Brazilian Portuguese" }
|
||||||
|
"bg*" { return "Bulgarian" }
|
||||||
|
{($_ -eq "zh-CH") -or ($_ -like "zh-Hans*") -or ($_ -eq "zh-SG") -or ($_ -eq "zh-CHS")} { return "Chinese (Simplified)" }
|
||||||
|
{($_ -eq "zh") -or ($_ -eq "zh-Hant") -or ($_ -eq "zh-HK") -or ($_ -eq "zh-MO") -or ($_ -eq "zh-TW") -or ($_ -eq "zh-CHT")} { return "Chinese (Traditional)" }
|
||||||
|
"hr*" { return "Croatian" }
|
||||||
|
"cs*" { return "Czech" }
|
||||||
|
"da*" { return "Danish" }
|
||||||
|
"nl*" { return "Dutch" }
|
||||||
|
"en-US" { return "English" }
|
||||||
|
{($_ -like "en*") -and ($_ -ne "en-US")} { return "English International" }
|
||||||
|
"et*" { return "Estonian" }
|
||||||
|
"fi*" { return "Finnish" }
|
||||||
|
{($_ -like "fr*") -and ($_ -ne "fr-CA")} { return "French" }
|
||||||
|
"fr-CA" { return "French Canadian" }
|
||||||
|
"de*" { return "German" }
|
||||||
|
"el*" { return "Greek" }
|
||||||
|
"he*" { return "Hebrew" }
|
||||||
|
"hu*" { return "Hungarian" }
|
||||||
|
"it*" { return "Italian" }
|
||||||
|
"ja*" { return "Japanese" }
|
||||||
|
"ko*" { return "Korean" }
|
||||||
|
"lv*" { return "Latvian" }
|
||||||
|
"lt*" { return "Lituanian" }
|
||||||
|
"nb*" { return "Norwegian" }
|
||||||
|
"pl*" { return "Polish" }
|
||||||
|
{($_ -like "pt*") -and ($_ -ne "pt-BR")} { return "Portuguese" }
|
||||||
|
"ro*" { return "Romanian" }
|
||||||
|
"ru*" { return "Russian" }
|
||||||
|
"sr-Latn*" { return "Serbian Latin" }
|
||||||
|
"sk*" { return "Slovak" }
|
||||||
|
"sl*" { return "Slovenian" }
|
||||||
|
{($_ -like "es*") -and ($_ -ne "es-MX")} { return "Spanish" }
|
||||||
|
"es-MX" { return "Spanish (Mexico)" }
|
||||||
|
"sv*" { return "Swedish" }
|
||||||
|
"th*" { return "Thai" }
|
||||||
|
"tr*" { return "Turkish" }
|
||||||
|
"uk*" { return "Ukrainian" }
|
||||||
|
default { return "English" }
|
||||||
|
}
|
||||||
|
}
|
21
functions/microwin/Microwin-GetLocalizedUsers.ps1
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
function Microwin-GetLocalizedUsers
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Gets a localized user group representation for ICACLS commands (Port from DISMTools PE Helper)
|
||||||
|
.PARAMETER admins
|
||||||
|
Determines whether to get a localized user group representation for the Administrators user group
|
||||||
|
.OUTPUTS
|
||||||
|
A string containing the localized user group
|
||||||
|
.EXAMPLE
|
||||||
|
Microwin-GetLocalizedUsers -admins $true
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0)] [bool]$admins
|
||||||
|
)
|
||||||
|
if ($admins) {
|
||||||
|
return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-544" }).Name
|
||||||
|
} else {
|
||||||
|
return (Get-LocalGroup | Where-Object { $_.SID.Value -like "S-1-5-32-545" }).Name
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,17 @@
|
|||||||
function Get-Oscdimg {
|
function Microwin-GetOscdimg {
|
||||||
<#
|
<#
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function will download oscdimg file from github Release folders and put it into env:temp folder
|
This function will download oscdimg file from github Release folders and put it into env:temp folder
|
||||||
|
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
Get-Oscdimg
|
Microwin-GetOscdimg
|
||||||
#>
|
#>
|
||||||
param( [Parameter(Mandatory=$true)]
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory, position=0)]
|
||||||
[string]$oscdimgPath
|
[string]$oscdimgPath
|
||||||
)
|
)
|
||||||
|
|
||||||
$oscdimgPath = "$env:TEMP\oscdimg.exe"
|
$oscdimgPath = "$env:TEMP\oscdimg.exe"
|
||||||
$downloadUrl = "https://github.com/ChrisTitusTech/winutil/raw/main/releases/oscdimg.exe"
|
$downloadUrl = "https://github.com/ChrisTitusTech/winutil/raw/main/releases/oscdimg.exe"
|
||||||
Invoke-RestMethod -Uri $downloadUrl -OutFile $oscdimgPath
|
Invoke-RestMethod -Uri $downloadUrl -OutFile $oscdimgPath
|
73
functions/microwin/Microwin-NewCheckInstall.ps1
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
function Microwin-NewCheckInstall {
|
||||||
|
|
||||||
|
# using here string to embedd firstrun
|
||||||
|
$checkInstall = @'
|
||||||
|
@echo off
|
||||||
|
if exist "%HOMEDRIVE%\windows\cpu.txt" (
|
||||||
|
echo %HOMEDRIVE%\windows\cpu.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\windows\cpu.txt does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\windows\SerialNumber.txt" (
|
||||||
|
echo %HOMEDRIVE%\windows\SerialNumber.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\windows\SerialNumber.txt does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\unattend.xml" (
|
||||||
|
echo %HOMEDRIVE%\unattend.xml exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\unattend.xml does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd" (
|
||||||
|
echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\Setup\Scripts\SetupComplete.cmd does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\Panther\unattend.xml" (
|
||||||
|
echo %HOMEDRIVE%\Windows\Panther\unattend.xml exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\Panther\unattend.xml does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml" (
|
||||||
|
echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\System32\Sysprep\unattend.xml does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\FirstStartup.ps1" (
|
||||||
|
echo %HOMEDRIVE%\Windows\FirstStartup.ps1 exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\FirstStartup.ps1 does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\winutil.ps1" (
|
||||||
|
echo %HOMEDRIVE%\Windows\winutil.ps1 exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\winutil.ps1 does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\LogSpecialize.txt" (
|
||||||
|
echo %HOMEDRIVE%\Windows\LogSpecialize.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\LogSpecialize.txt does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\LogAuditUser.txt" (
|
||||||
|
echo %HOMEDRIVE%\Windows\LogAuditUser.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\LogAuditUser.txt does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\Windows\LogOobeSystem.txt" (
|
||||||
|
echo %HOMEDRIVE%\Windows\LogOobeSystem.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\Windows\LogOobeSystem.txt does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\windows\csup.txt" (
|
||||||
|
echo %HOMEDRIVE%\windows\csup.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\windows\csup.txt does not exist
|
||||||
|
)
|
||||||
|
if exist "%HOMEDRIVE%\windows\LogFirstRun.txt" (
|
||||||
|
echo %HOMEDRIVE%\windows\LogFirstRun.txt exists
|
||||||
|
) else (
|
||||||
|
echo %HOMEDRIVE%\windows\LogFirstRun.txt does not exist
|
||||||
|
)
|
||||||
|
'@
|
||||||
|
$checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii
|
||||||
|
}
|
91
functions/microwin/Microwin-NewFirstRun.ps1
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
function Microwin-NewFirstRun {
|
||||||
|
|
||||||
|
# using here string to embedd firstrun
|
||||||
|
$firstRun = @'
|
||||||
|
# Set the global error action preference to continue
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
function Remove-RegistryValue {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$RegistryPath,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$ValueName
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if the registry path exists
|
||||||
|
if (Test-Path -Path $RegistryPath) {
|
||||||
|
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
# Check if the registry value exists
|
||||||
|
if ($registryValue) {
|
||||||
|
# Remove the registry value
|
||||||
|
Remove-ItemProperty -Path $RegistryPath -Name $ValueName -Force
|
||||||
|
Write-Host "Registry value '$ValueName' removed from '$RegistryPath'."
|
||||||
|
} else {
|
||||||
|
Write-Host "Registry value '$ValueName' not found in '$RegistryPath'."
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Registry path '$RegistryPath' not found."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"FirstStartup has worked" | Out-File -FilePath "$env:HOMEDRIVE\windows\LogFirstRun.txt" -Append -NoClobber
|
||||||
|
|
||||||
|
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
|
||||||
|
# Delete all files on the Taskbar
|
||||||
|
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 "FavoritesChanges"
|
||||||
|
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "Favorites"
|
||||||
|
|
||||||
|
# Delete Edge Icon from the desktop
|
||||||
|
$edgeShortcutFiles = Get-ChildItem -Path $desktopPath -Filter "*Edge*.lnk"
|
||||||
|
# Check if Edge shortcuts exist on the desktop
|
||||||
|
if ($edgeShortcutFiles) {
|
||||||
|
foreach ($shortcutFile in $edgeShortcutFiles) {
|
||||||
|
# Remove each Edge shortcut
|
||||||
|
Remove-Item -Path $shortcutFile.FullName -Force
|
||||||
|
Write-Host "Edge shortcut '$($shortcutFile.Name)' removed from the desktop."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Remove-Item -Path "$env:USERPROFILE\Desktop\*.lnk"
|
||||||
|
Remove-Item -Path "$env:HOMEDRIVE\Users\Default\Desktop\*.lnk"
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.State -eq 'Enabled' -and $_.FeatureName -like "Recall" }).Count -gt 0)
|
||||||
|
{
|
||||||
|
Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get BCD entries and set bootmgr timeout accordingly
|
||||||
|
try
|
||||||
|
{
|
||||||
|
# Check if the number of occurrences of "path" is 2 - this fixes the Boot Manager screen issue (#2562)
|
||||||
|
if ((bcdedit | Select-String "path").Count -eq 2)
|
||||||
|
{
|
||||||
|
# Set bootmgr timeout to 0
|
||||||
|
bcdedit /set `{bootmgr`} timeout 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested" /f
|
||||||
|
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.Suggested" /v Enabled /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.StartupApp" /f
|
||||||
|
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Windows.SystemToast.StartupApp" /v Enabled /t REG_DWORD /d 0 /f
|
||||||
|
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.SkyDrive.Desktop" /f
|
||||||
|
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Notifications\Settings\Microsoft.SkyDrive.Desktop" /v Enabled /t REG_DWORD /d 0 /f
|
||||||
|
|
||||||
|
'@
|
||||||
|
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
|
||||||
|
}
|
327
functions/microwin/Microwin-NewUnattend.ps1
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
function Microwin-NewUnattend {
|
||||||
|
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory, Position = 0)] [string]$userName,
|
||||||
|
[Parameter(Position = 1)] [string]$userPassword
|
||||||
|
)
|
||||||
|
|
||||||
|
$unattend = @'
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<unattend xmlns="urn:schemas-microsoft-com:unattend"
|
||||||
|
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<#REPLACEME#>
|
||||||
|
<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">
|
||||||
|
<RunSynchronous>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<CommandLine>CMD /C echo LAU GG>C:\Windows\LogAuditUser.txt</CommandLine>
|
||||||
|
<Description>StartMenu</Description>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
</RunSynchronous>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
<settings pass="oobeSystem">
|
||||||
|
<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">
|
||||||
|
<UserAccounts>
|
||||||
|
<LocalAccounts>
|
||||||
|
<LocalAccount wcm:action="add">
|
||||||
|
<Name>USER-REPLACEME</Name>
|
||||||
|
<Group>Administrators</Group>
|
||||||
|
<Password>
|
||||||
|
<Value>PW-REPLACEME</Value>
|
||||||
|
<PlainText>PT-STATUS</PlainText>
|
||||||
|
</Password>
|
||||||
|
</LocalAccount>
|
||||||
|
</LocalAccounts>
|
||||||
|
</UserAccounts>
|
||||||
|
<AutoLogon>
|
||||||
|
<Username>USER-REPLACEME</Username>
|
||||||
|
<Enabled>true</Enabled>
|
||||||
|
<LogonCount>1</LogonCount>
|
||||||
|
<Password>
|
||||||
|
<Value>PW-REPLACEME</Value>
|
||||||
|
<PlainText>PT-STATUS</PlainText>
|
||||||
|
</Password>
|
||||||
|
</AutoLogon>
|
||||||
|
<OOBE>
|
||||||
|
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
|
||||||
|
<SkipUserOOBE>true</SkipUserOOBE>
|
||||||
|
<SkipMachineOOBE>true</SkipMachineOOBE>
|
||||||
|
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
|
||||||
|
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||||
|
<HideEULAPage>true</HideEULAPage>
|
||||||
|
<ProtectYourPC>3</ProtectYourPC>
|
||||||
|
</OOBE>
|
||||||
|
<FirstLogonCommands>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<CommandLine>cmd.exe /c echo 23>c:\windows\csup.txt</CommandLine>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<CommandLine>CMD /C echo GG>C:\Windows\LogOobeSystem.txt</CommandLine>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>4</Order>
|
||||||
|
<CommandLine>powershell -ExecutionPolicy Bypass -File c:\windows\FirstStartup.ps1</CommandLine>
|
||||||
|
</SynchronousCommand>
|
||||||
|
</FirstLogonCommands>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
</unattend>
|
||||||
|
'@
|
||||||
|
$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>
|
||||||
|
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
|
||||||
|
<RunSynchronous>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OOBE" /v BypassNRO /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "UninstallCopilot" /t REG_SZ /d "powershell.exe -NoProfile -Command \"Get-AppxPackage -Name 'Microsoft.Windows.Ai.Copilot.Provider' | Remove-AppxPackage;\"" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>4</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Policies\Microsoft\Windows\WindowsCopilot" /v TurnOffWindowsCopilot /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>5</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>6</Order>
|
||||||
|
<Path>reg.exe delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>7</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>8</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Notepad" /v ShowStoreBanner /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>9</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>10</Order>
|
||||||
|
<Path>cmd.exe /c "del "C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\OneDrive.lnk""</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>11</Order>
|
||||||
|
<Path>cmd.exe /c "del "C:\Windows\System32\OneDriveSetup.exe""</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>12</Order>
|
||||||
|
<Path>cmd.exe /c "del "C:\Windows\SysWOW64\OneDriveSetup.exe""</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>13</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>14</Order>
|
||||||
|
<Path>reg.exe delete "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Run" /v OneDriveSetup /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>15</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>16</Order>
|
||||||
|
<Path>reg.exe delete "HKLM\SOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>17</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Communications" /v ConfigureChatAutoInstall /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>18</Order>
|
||||||
|
<Path>powershell.exe -NoProfile -Command "$xml = [xml]::new(); $xml.Load('C:\Windows\Panther\unattend.xml'); $sb = [scriptblock]::Create( $xml.unattend.Extensions.ExtractScript ); Invoke-Command -ScriptBlock $sb -ArgumentList $xml;"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>19</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>20</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_ProviderSet /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>21</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\current\device\Start" /v ConfigureStartPins_WinningProvider /t REG_SZ /d B5292708-1619-419B-9923-E5D9F3925E71 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>22</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins /t REG_SZ /d "{ \"pinnedList\": [] }" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>23</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Microsoft\PolicyManager\providers\B5292708-1619-419B-9923-E5D9F3925E71\default\Device\Start" /v ConfigureStartPins_LastWrite /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>24</Order>
|
||||||
|
<Path>net.exe accounts /maxpwage:UNLIMITED</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>25</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\FileSystem" /v LongPathsEnabled /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>26</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>27</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Dsh" /v AllowNewsAndInterests /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>28</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>29</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "ContentDeliveryAllowed" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>30</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "FeatureManagementEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>31</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "OEMPreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>32</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>33</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "PreInstalledAppsEverEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>34</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SilentInstalledAppsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>35</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SoftLandingEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>36</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContentEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>37</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-310093Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>38</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338387Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>39</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338388Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>40</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338389Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>41</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-338393Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>42</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SubscribedContent-353698Enabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>43</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" /v "SystemPaneSuggestionsEnabled" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>44</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>45</Order>
|
||||||
|
<Path>reg.exe add "HKLM\Software\Policies\Microsoft\Windows\CloudContent" /v "DisableWindowsConsumerFeatures" /t REG_DWORD /d 0 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>46</Order>
|
||||||
|
<Path>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\BitLocker" /v "PreventDeviceEncryption" /t REG_DWORD /d 1 /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>47</Order>
|
||||||
|
<Path>reg.exe load "HKU\DefaultUser" "C:\Users\Default\NTUSER.DAT"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>48</Order>
|
||||||
|
<Path>reg.exe add "HKU\DefaultUser\Software\Microsoft\Windows\CurrentVersion\Runonce" /v "ClassicContextMenu" /t REG_SZ /d "reg.exe add \"HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32\" /ve /f" /f</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
<RunSynchronousCommand wcm:action="add">
|
||||||
|
<Order>49</Order>
|
||||||
|
<Path>reg.exe unload "HKU\DefaultUser"</Path>
|
||||||
|
</RunSynchronousCommand>
|
||||||
|
</RunSynchronous>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
'@
|
||||||
|
if ((Microwin-TestCompatibleImage $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()
|
||||||
|
}
|
||||||
|
|
||||||
|
# User password in Base64. According to Microsoft, this is the way you can hide this sensitive information.
|
||||||
|
# More information can be found here: https://learn.microsoft.com/en-us/windows-hardware/customize/desktop/wsim/hide-sensitive-data-in-an-answer-file
|
||||||
|
# Yeah, I know this is not the best way to protect this kind of data, but we all know how Microsoft is - "the Apple of security" (in a sense, it takes them
|
||||||
|
# an eternity to implement basic security features right. Just look at the NTLM and Kerberos situation!)
|
||||||
|
|
||||||
|
$b64pass = ""
|
||||||
|
|
||||||
|
# Replace default User and Password values with the provided parameters
|
||||||
|
$unattend = $unattend.Replace("USER-REPLACEME", $userName).Trim()
|
||||||
|
try {
|
||||||
|
# I want to play it safe here - I don't want encoding mismatch problems like last time
|
||||||
|
|
||||||
|
# NOTE: "Password" needs to be appended to the password specified by the user. Otherwise, a parse error will occur when processing oobeSystem.
|
||||||
|
# This will not be added to the actual password stored in the target system's SAM file - only the provided password
|
||||||
|
$b64pass = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("$($userPassword)Password"))
|
||||||
|
} catch {
|
||||||
|
$b64pass = ""
|
||||||
|
}
|
||||||
|
if ($b64pass -ne "") {
|
||||||
|
# If we could encode the password with Base64, put it in the answer file and indicate that it's NOT in plain text
|
||||||
|
$unattend = $unattend.Replace("PW-REPLACEME", $b64pass).Trim()
|
||||||
|
$unattend = $unattend.Replace("PT-STATUS", "false").Trim()
|
||||||
|
$b64pass = ""
|
||||||
|
} else {
|
||||||
|
$unattend = $unattend.Replace("PW-REPLACEME", $userPassword).Trim()
|
||||||
|
$unattend = $unattend.Replace("PT-STATUS", "true").Trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
# Save unattended answer file with UTF-8 encoding
|
||||||
|
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8
|
||||||
|
}
|
82
functions/microwin/Microwin-RemoveFeatures.ps1
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
function Microwin-RemoveFeatures() {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Removes certain features from ISO image
|
||||||
|
|
||||||
|
.PARAMETER UseCmdlets
|
||||||
|
Determines whether or not to use the DISM cmdlets for processing.
|
||||||
|
- If true, DISM cmdlets will be used
|
||||||
|
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
|
||||||
|
the DISM conversion to cmdlets)
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Microwin-RemoveFeatures -UseCmdlets $true
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
|
||||||
|
)
|
||||||
|
try {
|
||||||
|
if ($UseCmdlets) {
|
||||||
|
$featlist = (Get-WindowsOptionalFeature -Path "$scratchDir")
|
||||||
|
|
||||||
|
$featlist = $featlist | Where-Object {
|
||||||
|
$_.FeatureName -NotLike "*Defender*" -AND
|
||||||
|
$_.FeatureName -NotLike "*Printing*" -AND
|
||||||
|
$_.FeatureName -NotLike "*TelnetClient*" -AND
|
||||||
|
$_.FeatureName -NotLike "*PowerShell*" -AND
|
||||||
|
$_.FeatureName -NotLike "*NetFx*" -AND
|
||||||
|
$_.FeatureName -NotLike "*Media*" -AND
|
||||||
|
$_.FeatureName -NotLike "*NFS*" -AND
|
||||||
|
$_.FeatureName -NotLike "*SearchEngine*" -AND
|
||||||
|
$_.FeatureName -NotLike "*RemoteDesktop*" -AND
|
||||||
|
$_.State -ne "Disabled"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$featList = dism /english /image="$scratchDir" /get-features | Select-String -Pattern "Feature Name : " -CaseSensitive -SimpleMatch
|
||||||
|
if ($?) {
|
||||||
|
$featList = $featList -split "Feature Name : " | Where-Object {$_}
|
||||||
|
# Exclude the same items. Note: for now, this doesn't exclude those features that are disabled.
|
||||||
|
# This will appear in the future
|
||||||
|
$featList = $featList | Where-Object {
|
||||||
|
$_ -NotLike "*Defender*" -AND
|
||||||
|
$_ -NotLike "*Printing*" -AND
|
||||||
|
$_ -NotLike "*TelnetClient*" -AND
|
||||||
|
$_ -NotLike "*PowerShell*" -AND
|
||||||
|
$_ -NotLike "*NetFx*" -AND
|
||||||
|
$_ -NotLike "*Media*" -AND
|
||||||
|
$_ -NotLike "*NFS*" -AND
|
||||||
|
$_ -NotLike "*SearchEngine*" -AND
|
||||||
|
$_ -NotLike "*RemoteDesktop*"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Features could not be obtained with DISM. MicroWin processing will continue, but features will be skipped."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($UseCmdlets) {
|
||||||
|
foreach ($feature in $featList) {
|
||||||
|
$status = "Removing feature $($feature.FeatureName)"
|
||||||
|
Write-Progress -Activity "Removing features" -Status $status -PercentComplete ($counter++/$featlist.Count*100)
|
||||||
|
Write-Debug "Removing feature $($feature.FeatureName)"
|
||||||
|
Disable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName $($feature.FeatureName) -Remove -ErrorAction SilentlyContinue -NoRestart
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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"
|
||||||
|
dism /english /image="$scratchDir" /disable-feature /featurename=$feature /remove /quiet /norestart | Out-Null
|
||||||
|
if ($? -eq $false) {
|
||||||
|
Write-Host "Feature $feature could not be disabled."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
Write-Host "Unable to get information about the features. A fallback will be used..."
|
||||||
|
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||||
|
Microwin-RemoveFeatures -UseCmdlets $false
|
||||||
|
}
|
||||||
|
}
|
46
functions/microwin/Microwin-RemoveFileOrDirectory.ps1
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
function Microwin-RemoveFileOrDirectory([string]$pathToDelete, [string]$mask = "", [switch]$Directory = $false) {
|
||||||
|
if(([string]::IsNullOrEmpty($pathToDelete))) { return }
|
||||||
|
if (-not (Test-Path -Path "$($pathToDelete)")) { return }
|
||||||
|
|
||||||
|
$yesNo = Get-LocalizedYesNo
|
||||||
|
Write-Host "[INFO] In Your local takeown expects '$($yesNo[0])' as a Yes answer."
|
||||||
|
|
||||||
|
$itemsToDelete = [System.Collections.ArrayList]::new()
|
||||||
|
|
||||||
|
if ($mask -eq "") {
|
||||||
|
Write-Debug "Adding $($pathToDelete) to array."
|
||||||
|
[void]$itemsToDelete.Add($pathToDelete)
|
||||||
|
} else {
|
||||||
|
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
|
||||||
|
if ($Directory) {
|
||||||
|
$itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory
|
||||||
|
} else {
|
||||||
|
$itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($itemToDelete in $itemsToDelete) {
|
||||||
|
$status = "Deleting $($itemToDelete)"
|
||||||
|
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ($counter++/$itemsToDelete.Count*100)
|
||||||
|
|
||||||
|
if (Test-Path -Path "$($itemToDelete)" -PathType Container) {
|
||||||
|
$status = "Deleting directory: $($itemToDelete)"
|
||||||
|
|
||||||
|
takeown /r /d $yesNo[0] /a /f "$($itemToDelete)"
|
||||||
|
icacls "$($itemToDelete)" /q /c /t /reset
|
||||||
|
icacls $itemToDelete /setowner "*S-1-5-32-544"
|
||||||
|
icacls $itemToDelete /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
||||||
|
Remove-Item -Force -Recurse "$($itemToDelete)"
|
||||||
|
}
|
||||||
|
elseif (Test-Path -Path "$($itemToDelete)" -PathType Leaf) {
|
||||||
|
$status = "Deleting file: $($itemToDelete)"
|
||||||
|
|
||||||
|
takeown /a /f "$($itemToDelete)"
|
||||||
|
icacls "$($itemToDelete)" /q /c /t /reset
|
||||||
|
icacls "$($itemToDelete)" /setowner "*S-1-5-32-544"
|
||||||
|
icacls "$($itemToDelete)" /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
||||||
|
Remove-Item -Force "$($itemToDelete)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Activity "Removing Items" -Status "Ready" -Completed
|
||||||
|
}
|
129
functions/microwin/Microwin-RemovePackages.ps1
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
function Microwin-RemovePackages {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Removes certain packages from ISO image
|
||||||
|
|
||||||
|
.PARAMETER UseCmdlets
|
||||||
|
Determines whether or not to use the DISM cmdlets for processing.
|
||||||
|
- If true, DISM cmdlets will be used
|
||||||
|
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
|
||||||
|
the DISM conversion to cmdlets)
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Microwin-RemovePackages -UseCmdlets $true
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
|
||||||
|
)
|
||||||
|
try {
|
||||||
|
if ($useCmdlets) {
|
||||||
|
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
|
||||||
|
|
||||||
|
$pkglist = $pkglist | Where-Object {
|
||||||
|
$_ -NotLike "*ApplicationModel*" -AND
|
||||||
|
$_ -NotLike "*indows-Client-LanguagePack*" -AND
|
||||||
|
$_ -NotLike "*LanguageFeatures-Basic*" -AND
|
||||||
|
$_ -NotLike "*Package_for_ServicingStack*" -AND
|
||||||
|
$_ -NotLike "*DotNet*" -AND
|
||||||
|
$_ -NotLike "*Notepad*" -AND
|
||||||
|
$_ -NotLike "*WMIC*" -AND
|
||||||
|
$_ -NotLike "*Ethernet*" -AND
|
||||||
|
$_ -NotLike "*Wifi*" -AND
|
||||||
|
$_ -NotLike "*FodMetadata*" -AND
|
||||||
|
$_ -NotLike "*Foundation*" -AND
|
||||||
|
$_ -NotLike "*LanguageFeatures*" -AND
|
||||||
|
$_ -NotLike "*VBSCRIPT*" -AND
|
||||||
|
$_ -NotLike "*License*" -AND
|
||||||
|
$_ -NotLike "*Hello-Face*" -AND
|
||||||
|
$_ -NotLike "*ISE*" -AND
|
||||||
|
$_ -NotLike "*OpenSSH*"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pkgList = dism /english /image="$scratchDir" /get-packages | Select-String -Pattern "Package Identity : " -CaseSensitive -SimpleMatch
|
||||||
|
if ($?) {
|
||||||
|
$pkgList = $pkgList -split "Package Identity : " | Where-Object {$_}
|
||||||
|
# Exclude the same items.
|
||||||
|
$pkgList = $pkgList | Where-Object {
|
||||||
|
$_ -NotLike "*ApplicationModel*" -AND
|
||||||
|
$_ -NotLike "*indows-Client-LanguagePack*" -AND
|
||||||
|
$_ -NotLike "*LanguageFeatures-Basic*" -AND
|
||||||
|
$_ -NotLike "*Package_for_ServicingStack*" -AND
|
||||||
|
$_ -NotLike "*DotNet*" -AND
|
||||||
|
$_ -NotLike "*Notepad*" -AND
|
||||||
|
$_ -NotLike "*WMIC*" -AND
|
||||||
|
$_ -NotLike "*Ethernet*" -AND
|
||||||
|
$_ -NotLike "*Wifi*" -AND
|
||||||
|
$_ -NotLike "*FodMetadata*" -AND
|
||||||
|
$_ -NotLike "*Foundation*" -AND
|
||||||
|
$_ -NotLike "*LanguageFeatures*" -AND
|
||||||
|
$_ -NotLike "*VBSCRIPT*" -AND
|
||||||
|
$_ -NotLike "*License*" -AND
|
||||||
|
$_ -NotLike "*Hello-Face*" -AND
|
||||||
|
$_ -NotLike "*ISE*" -AND
|
||||||
|
$_ -NotLike "*OpenSSH*"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Packages could not be obtained with DISM. MicroWin processing will continue, but packages will be skipped."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($UseCmdlets) {
|
||||||
|
$failedCount = 0
|
||||||
|
|
||||||
|
$erroredPackages = [System.Collections.Generic.List[ErroredPackage]]::new()
|
||||||
|
|
||||||
|
foreach ($pkg in $pkglist) {
|
||||||
|
try {
|
||||||
|
$status = "Removing $pkg"
|
||||||
|
Write-Progress -Activity "Removing Packages" -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
|
||||||
|
$erroredPackages.Add([ErroredPackage]::new($pkg, $_.Exception.Message))
|
||||||
|
$failedCount += 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($package in $pkgList) {
|
||||||
|
$status = "Removing package $package"
|
||||||
|
Write-Progress -Activity "Removing Packages" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
|
||||||
|
Write-Debug "Removing package $package"
|
||||||
|
dism /english /image="$scratchDir" /remove-package /packagename=$package /quiet /norestart | Out-Null
|
||||||
|
if ($? -eq $false) {
|
||||||
|
Write-Host "Package $package could not be removed."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed
|
||||||
|
if ($UseCmdlets -and $failedCount -gt 0)
|
||||||
|
{
|
||||||
|
Write-Host "$failedCount package(s) could not be removed. Your image will still work fine, however. Below is information on what packages failed to be removed and why."
|
||||||
|
if ($erroredPackages.Count -gt 0)
|
||||||
|
{
|
||||||
|
$erroredPackages = $erroredPackages | Sort-Object -Property ErrorMessage
|
||||||
|
|
||||||
|
$previousErroredPackage = $erroredPackages[0]
|
||||||
|
$counter = 0
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "- $($previousErroredPackage.ErrorMessage)"
|
||||||
|
foreach ($erroredPackage in $erroredPackages) {
|
||||||
|
if ($erroredPackage.ErrorMessage -ne $previousErroredPackage.ErrorMessage) {
|
||||||
|
Write-Host ""
|
||||||
|
$counter = 0
|
||||||
|
Write-Host "- $($erroredPackage.ErrorMessage)"
|
||||||
|
}
|
||||||
|
$counter += 1
|
||||||
|
Write-Host " $counter) $($erroredPackage.PackageName)"
|
||||||
|
$previousErroredPackage = $erroredPackage
|
||||||
|
}
|
||||||
|
Write-Host ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host "Unable to get information about the packages. A fallback will be used..."
|
||||||
|
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||||
|
Microwin-RemovePackages -UseCmdlets $false
|
||||||
|
}
|
||||||
|
}
|
96
functions/microwin/Microwin-RemoveProvisionedPackages.ps1
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
function Microwin-RemoveProvisionedPackages() {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Removes AppX packages from a Windows image during MicroWin processing
|
||||||
|
|
||||||
|
.PARAMETER UseCmdlets
|
||||||
|
Determines whether or not to use the DISM cmdlets for processing.
|
||||||
|
- If true, DISM cmdlets will be used
|
||||||
|
- If false, calls to the DISM executable will be made whilst selecting bits and pieces from the output as a string (that was how MicroWin worked before
|
||||||
|
the DISM conversion to cmdlets)
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Microwin-RemoveProvisionedPackages
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0)] [bool]$UseCmdlets
|
||||||
|
)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ($UseCmdlets) {
|
||||||
|
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
|
||||||
|
$_.PackageName -NotLike "*AppInstaller*" -AND
|
||||||
|
$_.PackageName -NotLike "*Store*" -and
|
||||||
|
$_.PackageName -NotLike "*Notepad*" -and
|
||||||
|
$_.PackageName -NotLike "*Printing*" -and
|
||||||
|
$_.PackageName -NotLike "*YourPhone*" -and
|
||||||
|
$_.PackageName -NotLike "*Xbox*" -and
|
||||||
|
$_.PackageName -NotLike "*WindowsTerminal*" -and
|
||||||
|
$_.PackageName -NotLike "*Calculator*" -and
|
||||||
|
$_.PackageName -NotLike "*Photos*" -and
|
||||||
|
$_.PackageName -NotLike "*VCLibs*" -and
|
||||||
|
$_.PackageName -NotLike "*Paint*" -and
|
||||||
|
$_.PackageName -NotLike "*Gaming*" -and
|
||||||
|
$_.PackageName -NotLike "*Extension*" -and
|
||||||
|
$_.PackageName -NotLike "*SecHealthUI*" -and
|
||||||
|
$_.PackageName -NotLike "*ScreenSketch*"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$appxProvisionedPackages = dism /english /image="$scratchDir" /get-provisionedappxpackages | Select-String -Pattern "PackageName : " -CaseSensitive -SimpleMatch
|
||||||
|
if ($?) {
|
||||||
|
$appxProvisionedPackages = $appxProvisionedPackages -split "PackageName : " | Where-Object {$_}
|
||||||
|
# Exclude the same items.
|
||||||
|
$appxProvisionedPackages = $appxProvisionedPackages | Where-Object {
|
||||||
|
$_ -NotLike "*AppInstaller*" -AND
|
||||||
|
$_ -NotLike "*Store*" -and
|
||||||
|
$_ -NotLike "*Notepad*" -and
|
||||||
|
$_ -NotLike "*Printing*" -and
|
||||||
|
$_ -NotLike "*YourPhone*" -and
|
||||||
|
$_ -NotLike "*Xbox*" -and
|
||||||
|
$_ -NotLike "*WindowsTerminal*" -and
|
||||||
|
$_ -NotLike "*Calculator*" -and
|
||||||
|
$_ -NotLike "*Photos*" -and
|
||||||
|
$_ -NotLike "*VCLibs*" -and
|
||||||
|
$_ -NotLike "*Paint*" -and
|
||||||
|
$_ -NotLike "*Gaming*" -and
|
||||||
|
$_ -NotLike "*Extension*" -and
|
||||||
|
$_ -NotLike "*SecHealthUI*" -and
|
||||||
|
$_ -NotLike "*ScreenSketch*"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "AppX packages could not be obtained with DISM. MicroWin processing will continue, but AppX packages will be skipped."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$counter = 0
|
||||||
|
if ($UseCmdlets) {
|
||||||
|
foreach ($appx in $appxProvisionedPackages) {
|
||||||
|
$status = "Removing Provisioned $($appx.PackageName)"
|
||||||
|
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
|
||||||
|
try {
|
||||||
|
Remove-AppxProvisionedPackage -Path "$scratchDir" -PackageName $appx.PackageName -ErrorAction SilentlyContinue
|
||||||
|
} catch {
|
||||||
|
Write-Host "Application $($appx.PackageName) could not be removed"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($appx in $appxProvisionedPackages) {
|
||||||
|
$status = "Removing Provisioned $appx"
|
||||||
|
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
|
||||||
|
dism /english /image="$scratchDir" /remove-provisionedappxpackage /packagename=$appx /quiet /norestart | Out-Null
|
||||||
|
if ($? -eq $false) {
|
||||||
|
Write-Host "AppX package $appx could not be removed."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Progress -Activity "Removing Provisioned Apps" -Status "Ready" -Completed
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Write-Host "Unable to get information about the AppX packages. A fallback will be used..."
|
||||||
|
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||||
|
Microwin-RemoveProvisionedPackages -UseCmdlets $false
|
||||||
|
}
|
||||||
|
}
|
26
functions/microwin/Microwin-TestCompatibleImage.ps1
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
function Microwin-TestCompatibleImage() {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
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 Name
|
||||||
|
imgVersion - The version of the Windows image
|
||||||
|
desiredVersion - The version to compare the image version with
|
||||||
|
#>
|
||||||
|
|
||||||
|
param
|
||||||
|
(
|
||||||
|
[Parameter(Mandatory, position=0)]
|
||||||
|
[string]$imgVersion,
|
||||||
|
|
||||||
|
[Parameter(Mandatory, position=1)]
|
||||||
|
[Version]$desiredVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
$version = [Version]$imgVersion
|
||||||
|
return $version -ge $desiredVersion
|
||||||
|
} catch {
|
||||||
|
return $False
|
||||||
|
}
|
||||||
|
}
|
28
functions/microwin/Toggle-MicrowinPanel.ps1
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
function Toggle-MicrowinPanel {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Toggles the visibility of the Microwin options and ISO panels in the GUI.
|
||||||
|
.DESCRIPTION
|
||||||
|
This function toggles the visibility of the Microwin options and ISO panels in the GUI.
|
||||||
|
.PARAMETER MicrowinOptionsPanel
|
||||||
|
The panel containing Microwin options.
|
||||||
|
.PARAMETER MicrowinISOPanel
|
||||||
|
The panel containing the Microwin ISO options.
|
||||||
|
.EXAMPLE
|
||||||
|
Toggle-MicrowinPanel 1
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, Position = 0)]
|
||||||
|
[ValidateSet(1, 2)]
|
||||||
|
[int]$PanelNumber
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($PanelNumber -eq 1) {
|
||||||
|
$sync.MicrowinISOPanel.Visibility = 'Visible'
|
||||||
|
$sync.MicrowinOptionsPanel.Visibility = 'Collapsed'
|
||||||
|
|
||||||
|
} elseif ($PanelNumber -eq 2) {
|
||||||
|
$sync.MicrowinOptionsPanel.Visibility = 'Visible'
|
||||||
|
$sync.MicrowinISOPanel.Visibility = 'Collapsed'
|
||||||
|
}
|
||||||
|
}
|
50
functions/private/Add-SelectedAppsMenuItem.ps1
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
function Add-SelectedAppsMenuItem {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
This is a helper function that generates and adds the Menu Items to the Selected Apps Popup.
|
||||||
|
|
||||||
|
.Parameter name
|
||||||
|
The actual Name of an App like "Chrome" or "Brave"
|
||||||
|
This name is contained in the "Content" property inside the applications.json
|
||||||
|
.PARAMETER key
|
||||||
|
The key which identifies an app object in applications.json
|
||||||
|
For Chrome this would be "WPFInstallchrome" because "WPFInstall" is prepended automatically for each key in applications.json
|
||||||
|
#>
|
||||||
|
|
||||||
|
param ([string]$name, [string]$key)
|
||||||
|
|
||||||
|
$selectedAppGrid = New-Object Windows.Controls.Grid
|
||||||
|
|
||||||
|
$selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "*"}))
|
||||||
|
$selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "30"}))
|
||||||
|
|
||||||
|
# Sets the name to the Content as well as the Tooltip, because the parent Popup Border has a fixed width and text could "overflow".
|
||||||
|
# With the tooltip, you can still read the whole entry on hover
|
||||||
|
$selectedAppLabel = New-Object Windows.Controls.Label
|
||||||
|
$selectedAppLabel.Content = $name
|
||||||
|
$selectedAppLabel.ToolTip = $name
|
||||||
|
$selectedAppLabel.HorizontalAlignment = "Left"
|
||||||
|
$selectedAppLabel.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
[System.Windows.Controls.Grid]::SetColumn($selectedAppLabel, 0)
|
||||||
|
$selectedAppGrid.Children.Add($selectedAppLabel)
|
||||||
|
|
||||||
|
$selectedAppRemoveButton = New-Object Windows.Controls.Button
|
||||||
|
$selectedAppRemoveButton.FontFamily = "Segoe MDL2 Assets"
|
||||||
|
$selectedAppRemoveButton.Content = [string]([char]0xE711)
|
||||||
|
$selectedAppRemoveButton.HorizontalAlignment = "Center"
|
||||||
|
$selectedAppRemoveButton.Tag = $key
|
||||||
|
$selectedAppRemoveButton.ToolTip = "Remove the App from Selection"
|
||||||
|
$selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::StyleProperty, "HoverButtonStyle")
|
||||||
|
|
||||||
|
# Highlight the Remove icon on Hover
|
||||||
|
$selectedAppRemoveButton.Add_MouseEnter({ $this.Foreground = "Red" })
|
||||||
|
$selectedAppRemoveButton.Add_MouseLeave({ $this.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") })
|
||||||
|
$selectedAppRemoveButton.Add_Click({
|
||||||
|
$sync.($this.Tag).isChecked = $false # On click of the remove button, we only have to uncheck the corresponding checkbox. This will kick of all neccessary changes to update the UI
|
||||||
|
})
|
||||||
|
[System.Windows.Controls.Grid]::SetColumn($selectedAppRemoveButton, 1)
|
||||||
|
$selectedAppGrid.Children.Add($selectedAppRemoveButton)
|
||||||
|
# Add new Element to Popup
|
||||||
|
$sync.selectedAppsstackPanel.Children.Add($selectedAppGrid)
|
||||||
|
}
|
@ -1,93 +0,0 @@
|
|||||||
function ConvertTo-Icon {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.DESCRIPTION
|
|
||||||
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
|
|
||||||
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, position=0)]
|
|
||||||
[string]$bitmapPath,
|
|
||||||
[Parameter(Mandatory=$true, position=1)]
|
|
||||||
[string]$iconPath,
|
|
||||||
[Parameter(position=2)]
|
|
||||||
[bool]$overrideIconFile = $true
|
|
||||||
)
|
|
||||||
|
|
||||||
Add-Type -AssemblyName System.Drawing
|
|
||||||
|
|
||||||
if (Test-Path $bitmapPath) {
|
|
||||||
if ((Test-Path $iconPath) -AND ($overrideIconFile -eq $false)) {
|
|
||||||
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
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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'."
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,11 +2,17 @@ function Copy-Files {
|
|||||||
<#
|
<#
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
This function will make all modifications to the registry
|
Copies the contents of a given ISO file to a given destination
|
||||||
|
.PARAMETER Path
|
||||||
|
The source of the files to copy
|
||||||
|
.PARAMETER Destination
|
||||||
|
The destination to copy the files to
|
||||||
|
.PARAMETER Recurse
|
||||||
|
Determines whether or not to copy all files of the ISO file, including those in subdirectories
|
||||||
|
.PARAMETER Force
|
||||||
|
Determines whether or not to overwrite existing files
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
|
Copy-Files "D:" "C:\ISOFile" -Recurse -Force
|
||||||
Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0"
|
|
||||||
|
|
||||||
#>
|
#>
|
||||||
param (
|
param (
|
||||||
@ -19,30 +25,29 @@ function Copy-Files {
|
|||||||
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) file(s) from $path to $destination"
|
||||||
|
|
||||||
foreach($file in $files)
|
foreach ($file in $files) {
|
||||||
{
|
$status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name
|
||||||
$status = "Copy files {0} on {1}: {2}" -f $counter, $files.Count, $file.Name
|
Write-Progress -Activity "Copy disc image files" -Status $status -PercentComplete ($counter++/$files.count*100)
|
||||||
Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100)
|
|
||||||
$restpath = $file.FullName -Replace $path, ''
|
$restpath = $file.FullName -Replace $path, ''
|
||||||
|
|
||||||
if($file.PSIsContainer -eq $true)
|
if ($file.PSIsContainer -eq $true) {
|
||||||
{
|
|
||||||
Write-Debug "Creating $($destination + $restpath)"
|
Write-Debug "Creating $($destination + $restpath)"
|
||||||
New-Item ($destination+$restpath) -Force:$force -Type Directory -ErrorAction SilentlyContinue
|
New-Item ($destination+$restpath) -Force:$force -Type Directory -ErrorAction SilentlyContinue
|
||||||
}
|
} 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 disc image files" -Status "Ready" -Completed
|
||||||
}
|
} catch {
|
||||||
Catch{
|
Write-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow
|
||||||
Write-Warning "Unable to Copy all the files due to unhandled exception"
|
Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow
|
||||||
Write-Warning $psitem.Exception.StackTrace
|
Write-Host "Additional information:" -ForegroundColor Yellow
|
||||||
|
Write-Host $PSItem.Exception.StackTrace
|
||||||
|
# Write possible suggestions
|
||||||
|
Write-Host "`nIf you are using an antivirus, try configuring exclusions"
|
||||||
}
|
}
|
||||||
}
|
}
|
49
functions/private/Find-AppsByNameOrDescription.ps1
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
function Find-AppsByNameOrDescription {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Searches through the Apps on the Install Tab and hides all entries that do not match the string
|
||||||
|
|
||||||
|
.PARAMETER SearchString
|
||||||
|
The string to be searched for
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]$SearchString = ""
|
||||||
|
)
|
||||||
|
# Reset the visibility if the search string is empty or the search is cleared
|
||||||
|
if ([string]::IsNullOrWhiteSpace($SearchString)) {
|
||||||
|
$sync.ItemsControl.Items | ForEach-Object {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
$_.Children | ForEach-Object {
|
||||||
|
if ($null -ne $_) {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$sync.ItemsControl.Items | ForEach-Object {
|
||||||
|
# Ensure ToggleButtons remain visible
|
||||||
|
if ($_.Tag -like "CategoryToggleButton") {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
return
|
||||||
|
}
|
||||||
|
# Hide all CategoryWrapPanel and ToggleButton
|
||||||
|
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
if ($_.Tag -like "CategoryWrapPanel_*") {
|
||||||
|
# Search for Apps that match the search string
|
||||||
|
$_.Children | Foreach-Object {
|
||||||
|
$appEntry = $sync.configs.applicationsHashtable.$($_.Tag)
|
||||||
|
if ($appEntry.Content -like "*$SearchString*" -or $appEntry.Description -like "*$SearchString*") {
|
||||||
|
# Show the App and the parent CategoryWrapPanel if the string is found
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
$_.parent.Visibility = [Windows.Visibility]::Visible
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
100
functions/private/Find-TweaksByNameOrDescription.ps1
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
function Find-TweaksByNameOrDescription {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Searches through the Tweaks on the Tweaks Tab and hides all entries that do not match the search string
|
||||||
|
|
||||||
|
.PARAMETER SearchString
|
||||||
|
The string to be searched for
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]$SearchString = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
# Reset the visibility if the search string is empty or the search is cleared
|
||||||
|
if ([string]::IsNullOrWhiteSpace($SearchString)) {
|
||||||
|
# Show all categories
|
||||||
|
$tweakspanel = $sync.Form.FindName("tweakspanel")
|
||||||
|
$tweakspanel.Children | ForEach-Object {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
|
||||||
|
# Foreach category section, show all items
|
||||||
|
if ($_ -is [Windows.Controls.Border]) {
|
||||||
|
$_.Visibility = [Windows.Visibility]::Visible
|
||||||
|
|
||||||
|
# Find ItemsControl
|
||||||
|
$dockPanel = $_.Child
|
||||||
|
if ($dockPanel -is [Windows.Controls.DockPanel]) {
|
||||||
|
$itemsControl = $dockPanel.Children | Where-Object { $_ -is [Windows.Controls.ItemsControl] }
|
||||||
|
if ($itemsControl) {
|
||||||
|
# Show items in the category
|
||||||
|
foreach ($item in $itemsControl.Items) {
|
||||||
|
if ($item -is [Windows.Controls.Label]) {
|
||||||
|
$item.Visibility = [Windows.Visibility]::Visible
|
||||||
|
} elseif ($item -is [Windows.Controls.DockPanel] -or
|
||||||
|
$item -is [Windows.Controls.StackPanel]) {
|
||||||
|
$item.Visibility = [Windows.Visibility]::Visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Search for matching tweaks when search string is not null
|
||||||
|
$tweakspanel = $sync.Form.FindName("tweakspanel")
|
||||||
|
|
||||||
|
$tweakspanel.Children | ForEach-Object {
|
||||||
|
$categoryBorder = $_
|
||||||
|
$categoryVisible = $false
|
||||||
|
|
||||||
|
if ($_ -is [Windows.Controls.Border]) {
|
||||||
|
# Find the ItemsControl
|
||||||
|
$dockPanel = $_.Child
|
||||||
|
if ($dockPanel -is [Windows.Controls.DockPanel]) {
|
||||||
|
$itemsControl = $dockPanel.Children | Where-Object { $_ -is [Windows.Controls.ItemsControl] }
|
||||||
|
if ($itemsControl) {
|
||||||
|
$categoryLabel = $null
|
||||||
|
|
||||||
|
# Process all items in the ItemsControl
|
||||||
|
for ($i = 0; $i -lt $itemsControl.Items.Count; $i++) {
|
||||||
|
$item = $itemsControl.Items[$i]
|
||||||
|
|
||||||
|
if ($item -is [Windows.Controls.Label]) {
|
||||||
|
$categoryLabel = $item
|
||||||
|
$item.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
} elseif ($item -is [Windows.Controls.DockPanel]) {
|
||||||
|
$checkbox = $item.Children | Where-Object { $_ -is [Windows.Controls.CheckBox] } | Select-Object -First 1
|
||||||
|
$label = $item.Children | Where-Object { $_ -is [Windows.Controls.Label] } | Select-Object -First 1
|
||||||
|
|
||||||
|
if ($label -and ($label.Content -like "*$SearchString*" -or $label.ToolTip -like "*$SearchString*")) {
|
||||||
|
$item.Visibility = [Windows.Visibility]::Visible
|
||||||
|
if ($categoryLabel) { $categoryLabel.Visibility = [Windows.Visibility]::Visible }
|
||||||
|
$categoryVisible = $true
|
||||||
|
} else {
|
||||||
|
$item.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
}
|
||||||
|
} elseif ($item -is [Windows.Controls.StackPanel]) {
|
||||||
|
# StackPanel which contain checkboxes or other elements
|
||||||
|
$checkbox = $item.Children | Where-Object { $_ -is [Windows.Controls.CheckBox] } | Select-Object -First 1
|
||||||
|
|
||||||
|
if ($checkbox -and ($checkbox.Content -like "*$SearchString*" -or $checkbox.ToolTip -like "*$SearchString*")) {
|
||||||
|
$item.Visibility = [Windows.Visibility]::Visible
|
||||||
|
if ($categoryLabel) { $categoryLabel.Visibility = [Windows.Visibility]::Visible }
|
||||||
|
$categoryVisible = $true
|
||||||
|
} else {
|
||||||
|
$item.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set the visibility based on if any item matched
|
||||||
|
$categoryBorder.Visibility = if ($categoryVisible) { [Windows.Visibility]::Visible } else { [Windows.Visibility]::Collapsed }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,217 +0,0 @@
|
|||||||
function Get-TabXaml {
|
|
||||||
<#
|
|
||||||
.SYNOPSIS
|
|
||||||
Generates XAML for a tab in the WinUtil GUI
|
|
||||||
This function is used to generate the XAML for the applications tab in the WinUtil GUI
|
|
||||||
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
|
|
||||||
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
|
|
||||||
The number of columns to display the applications in, default is 0
|
|
||||||
.OUTPUTS
|
|
||||||
The XAML for the tab
|
|
||||||
.EXAMPLE
|
|
||||||
Get-TabXaml "applications" 3
|
|
||||||
#>
|
|
||||||
|
|
||||||
|
|
||||||
param(
|
|
||||||
[Parameter(Mandatory, position=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 = @{}
|
|
||||||
# Iterate through JSON data and organize by panel and category
|
|
||||||
foreach ($appName in $sync.configs.$tabname.PSObject.Properties.Name) {
|
|
||||||
$appInfo = $sync.configs.$tabname.$appName
|
|
||||||
|
|
||||||
# Create an object for the application
|
|
||||||
$appObject = [PSCustomObject]@{
|
|
||||||
Name = $appName
|
|
||||||
Category = $appInfo.Category
|
|
||||||
Content = $appInfo.Content
|
|
||||||
Choco = $appInfo.choco
|
|
||||||
Winget = $appInfo.winget
|
|
||||||
Panel = if ($columncount -gt 0 ) { "0" } else {$appInfo.panel}
|
|
||||||
Link = $appInfo.link
|
|
||||||
Description = $appInfo.description
|
|
||||||
# Type is (Checkbox,Toggle,Button,Combobox ) (Default is Checkbox)
|
|
||||||
Type = $appInfo.type
|
|
||||||
ComboItems = $appInfo.ComboItems
|
|
||||||
# Checked is the property to set startup checked status of checkbox (Default is false)
|
|
||||||
Checked = $appInfo.Checked
|
|
||||||
ButtonWidth = $appInfo.ButtonWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not $organizedData.ContainsKey($appObject.panel)) {
|
|
||||||
$organizedData[$appObject.panel] = @{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not $organizedData[$appObject.panel].ContainsKey($appObject.Category)) {
|
|
||||||
$organizedData[$appObject.panel][$appObject.Category] = @{}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Store application data in a sub-array under the category
|
|
||||||
# Add Order property to keep the original order of tweaks and features
|
|
||||||
$organizedData[$appObject.panel][$appInfo.Category]["$($appInfo.order)$appName"] = $appObject
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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
|
|
||||||
if ($columncount -gt 0) {
|
|
||||||
$appcount = $sync.configs.$tabname.PSObject.Properties.Name.count + $organizedData["0"].Keys.count
|
|
||||||
$maxcount = [Math]::Round( $appcount / $columncount + 0.5)
|
|
||||||
$paneltotal = $columncount
|
|
||||||
}
|
|
||||||
# add ColumnDefinitions to evenly draw colums
|
|
||||||
$blockXml = "<Grid.ColumnDefinitions>"
|
|
||||||
$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
|
|
||||||
foreach ($panel in ($organizedData.Keys | Sort-Object)) {
|
|
||||||
$blockXml += $precal_indent_m1 + "<Border Grid.Row=""1"" Grid.Column=""$panelcount"">" + "`r`n"
|
|
||||||
$blockXml += $precal_indent + "<StackPanel Background=""{MainBackgroundColor}"" SnapsToDevicePixels=""True"">" + "`r`n"
|
|
||||||
$panelcount++
|
|
||||||
foreach ($category in ($organizedData[$panel].Keys | Sort-Object)) {
|
|
||||||
$count++
|
|
||||||
if ($columncount -gt 0) {
|
|
||||||
$panelcount2 = [Int](($count)/$maxcount-0.5)
|
|
||||||
if ($panelcount -eq $panelcount2 ) {
|
|
||||||
$blockXml += $precal_indent_p2 + "</StackPanel>" + "`r`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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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
|
|
||||||
foreach ($appName in $sortedApps) {
|
|
||||||
$count++
|
|
||||||
|
|
||||||
if ($columncount -gt 0) {
|
|
||||||
$panelcount2 = [Int](($count)/$maxcount-0.5)
|
|
||||||
# Verify the indentation actually works...
|
|
||||||
if ($panelcount -eq $panelcount2 ) {
|
|
||||||
$blockXml += $precal_indent_m1 +
|
|
||||||
"</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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$appInfo = $organizedData[$panel][$category][$appName]
|
|
||||||
switch ($appInfo.Type) {
|
|
||||||
"Toggle" {
|
|
||||||
$blockXml += $precal_indent_m1 +
|
|
||||||
"<DockPanel LastChildFill=""True"">" + "`r`n"
|
|
||||||
$blockXml += $precal_indent +
|
|
||||||
"<CheckBox Name=""$($appInfo.Name)"" Style=""{StaticResource ColorfulToggleSwitchStyle}"" Margin=""4,0""" + " " +
|
|
||||||
"HorizontalAlignment=""Right"" FontSize=""{FontSize}""/>" + "`r`n"
|
|
||||||
$blockXml += $precal_indent +
|
|
||||||
"<Label Content=""$($appInfo.Content)"" ToolTip=""$($appInfo.Description)""" + " " +
|
|
||||||
"HorizontalAlignment=""Left"" FontSize=""{FontSize}""/>" + "`r`n"
|
|
||||||
$blockXml += $precal_indent_m1 +
|
|
||||||
"</DockPanel>" + "`r`n"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Combobox" {
|
|
||||||
$blockXml += $precal_indent_m1 +
|
|
||||||
"<StackPanel Orientation=""Horizontal"" Margin=""0,5,0,0"">" + "`r`n"
|
|
||||||
$blockXml += $precal_indent + "<Label Content=""$($appInfo.Content)"" HorizontalAlignment=""Left""" + " " +
|
|
||||||
"VerticalAlignment=""Center"" FontSize=""{FontSize}""/>" + "`r`n"
|
|
||||||
$blockXml += $precal_indent +
|
|
||||||
"<ComboBox Name=""$($appInfo.Name)"" Height=""32"" Width=""186"" HorizontalAlignment=""Left""" + " " +
|
|
||||||
"VerticalAlignment=""Center"" Margin=""5,5"" FontSize=""{FontSize}"">" + "`r`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"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Button" {
|
|
||||||
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 += $precal_indent_p1 + "</StackPanel>" + "`r`n"
|
|
||||||
$blockXml += $precal_indent + "</Border>" + "`r`n"
|
|
||||||
}
|
|
||||||
return ($blockXml)
|
|
||||||
}
|
|
@ -3,10 +3,13 @@ function Get-WPFObjectName {
|
|||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
This is a helper function that generates an objectname with the prefix WPF that can be used as a Powershell Variable after compilation.
|
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.
|
To achieve this, all characters that are not a-z, A-Z or 0-9 are simply removed from the name.
|
||||||
|
|
||||||
.PARAMETER type
|
.PARAMETER type
|
||||||
The type of object for which the name should be generated. (e.g. Label, Button, CheckBox...)
|
The type of object for which the name should be generated. (e.g. Label, Button, CheckBox...)
|
||||||
|
|
||||||
.PARAMETER name
|
.PARAMETER name
|
||||||
The name or description to be used for the object. (invalid characters are removed)
|
The name or description to be used for the object. (invalid characters are removed)
|
||||||
|
|
||||||
.OUTPUTS
|
.OUTPUTS
|
||||||
A string that can be used as a object/variable name in powershell.
|
A string that can be used as a object/variable name in powershell.
|
||||||
For example: WPFLabelMicrosoftTools
|
For example: WPFLabelMicrosoftTools
|
||||||
@ -15,13 +18,14 @@ function Get-WPFObjectName {
|
|||||||
Get-WPFObjectName -type Label -name "Microsoft Tools"
|
Get-WPFObjectName -type Label -name "Microsoft Tools"
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param( [Parameter(Mandatory=$true)]
|
param(
|
||||||
$type,
|
[Parameter(Mandatory, position=0)]
|
||||||
$name
|
[string]$type,
|
||||||
|
|
||||||
|
[Parameter(position=1)]
|
||||||
|
[string]$name
|
||||||
)
|
)
|
||||||
|
|
||||||
$Output = $("WPF"+$type+$name) -replace '[^a-zA-Z0-9]', ''
|
$Output = $("WPF"+$type+$name) -replace '[^a-zA-Z0-9]', ''
|
||||||
|
|
||||||
return $Output
|
return $Output
|
||||||
|
|
||||||
}
|
}
|
59
functions/private/Get-WinUtilSelectedPackages.ps1
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
function Get-WinUtilSelectedPackages
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Sorts given packages based on installer preference and availability.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
Hashtable. Key = Package Manager, Value = ArrayList of packages to install
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
$PackageList,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[PackageManagers]$Preference
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($PackageList.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" })
|
||||||
|
}
|
||||||
|
|
||||||
|
$packages = [System.Collections.Hashtable]::new()
|
||||||
|
$packagesWinget = [System.Collections.ArrayList]::new()
|
||||||
|
$packagesChoco = [System.Collections.ArrayList]::new()
|
||||||
|
$packages[[PackageManagers]::Winget] = $packagesWinget
|
||||||
|
$packages[[PackageManagers]::Choco] = $packagesChoco
|
||||||
|
|
||||||
|
Write-Debug "Checking packages using Preference '$($Preference)'"
|
||||||
|
|
||||||
|
foreach ($package in $PackageList) {
|
||||||
|
switch ($Preference) {
|
||||||
|
"Choco" {
|
||||||
|
if ($package.choco -eq "na") {
|
||||||
|
Write-Debug "$($package.content) has no Choco value."
|
||||||
|
$null = $packagesWinget.add($($package.winget))
|
||||||
|
Write-Host "Queueing $($package.winget) for Winget"
|
||||||
|
} else {
|
||||||
|
$null = $packagesChoco.add($package.choco)
|
||||||
|
Write-Host "Queueing $($package.choco) for Chocolatey"
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
"Winget" {
|
||||||
|
if ($package.winget -eq "na") {
|
||||||
|
Write-Debug "$($package.content) has no Winget value."
|
||||||
|
$null = $packagesChoco.add($package.choco)
|
||||||
|
Write-Host "Queueing $($package.choco) for Chocolatey"
|
||||||
|
} else {
|
||||||
|
$null = $packagesWinget.add($($package.winget))
|
||||||
|
Write-Host "Queueing $($package.winget) for Winget"
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packages
|
||||||
|
}
|
@ -13,145 +13,66 @@ Function Get-WinUtilToggleStatus {
|
|||||||
#>
|
#>
|
||||||
|
|
||||||
Param($ToggleSwitch)
|
Param($ToggleSwitch)
|
||||||
if($ToggleSwitch -eq "WPFToggleDarkMode"){
|
|
||||||
$app = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme
|
|
||||||
$system = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').SystemUsesLightTheme
|
|
||||||
if($app -eq 0 -and $system -eq 0){
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($ToggleSwitch -eq "WPFToggleBingSearch"){
|
|
||||||
$bingsearch = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search').BingSearchEnabled
|
|
||||||
if($bingsearch -eq 0){
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($ToggleSwitch -eq "WPFToggleNumLock"){
|
|
||||||
$numlockvalue = (Get-ItemProperty -path 'HKCU:\Control Panel\Keyboard').InitialKeyboardIndicators
|
|
||||||
if($numlockvalue -eq 2){
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($ToggleSwitch -eq "WPFToggleVerboseLogon"){
|
|
||||||
$VerboseStatusvalue = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System').VerboseStatus
|
|
||||||
if($VerboseStatusvalue -eq 1){
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($ToggleSwitch -eq "WPFToggleShowExt"){
|
|
||||||
$hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt
|
|
||||||
if($hideextvalue -eq 0){
|
|
||||||
return $true
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
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"){
|
|
||||||
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout
|
|
||||||
if($hidesnap -eq 0){
|
|
||||||
return $false
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
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"){
|
|
||||||
$MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed
|
|
||||||
$MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1
|
|
||||||
$MouseThreshold2 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold2
|
|
||||||
|
|
||||||
if($MouseSpeed -eq 1 -and $MouseThreshold1 -eq 6 -and $MouseThreshold2 -eq 10){
|
$ToggleSwitchReg = $sync.configs.tweaks.$ToggleSwitch.registry
|
||||||
return $true
|
|
||||||
|
try {
|
||||||
|
if (($ToggleSwitchReg.path -imatch "hku") -and !(Get-PSDrive -Name HKU -ErrorAction SilentlyContinue)) {
|
||||||
|
$null = (New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS)
|
||||||
|
if (Get-PSDrive -Name HKU -ErrorAction SilentlyContinue) {
|
||||||
|
Write-Debug "HKU drive created successfully"
|
||||||
|
} else {
|
||||||
|
Write-Debug "Failed to create HKU drive"
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Error "An error occurred regarding the HKU Drive: $_"
|
||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($ToggleSwitchReg) {
|
||||||
|
$count = 0
|
||||||
|
|
||||||
|
foreach ($regentry in $ToggleSwitchReg) {
|
||||||
|
try {
|
||||||
|
if (!(Test-Path $regentry.Path)) {
|
||||||
|
New-Item -Path $regentry.Path -Force | Out-Null
|
||||||
}
|
}
|
||||||
if($ToggleSwitch -eq "WPFToggleTaskbarSearch"){
|
$regstate = (Get-ItemProperty -path $regentry.Path).$($regentry.Name)
|
||||||
$SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode
|
if ($regstate -eq $regentry.Value) {
|
||||||
if($SearchButton -eq 0){
|
$count += 1
|
||||||
return $false
|
Write-Debug "$($regentry.Name) is true (state: $regstate, value: $($regentry.Value), original: $($regentry.OriginalValue))"
|
||||||
|
} else {
|
||||||
|
Write-Debug "$($regentry.Name) is false (state: $regstate, value: $($regentry.Value), original: $($regentry.OriginalValue))"
|
||||||
}
|
}
|
||||||
else{
|
if (!$regstate) {
|
||||||
return $true
|
switch ($regentry.DefaultState) {
|
||||||
|
"true" {
|
||||||
|
$regstate = $regentry.Value
|
||||||
|
$count += 1
|
||||||
|
}
|
||||||
|
"false" {
|
||||||
|
$regstate = $regentry.OriginalValue
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Error "Entry for $($regentry.Name) does not exist and no DefaultState is defined."
|
||||||
|
$regstate = $regentry.OriginalValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($ToggleSwitch -eq "WPFToggleStickyKeys") {
|
|
||||||
$StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags
|
|
||||||
if($StickyKeys -eq 58){
|
|
||||||
return $false
|
|
||||||
}
|
}
|
||||||
else{
|
} catch {
|
||||||
return $true
|
Write-Error "An unexpected error occurred: $_"
|
||||||
}
|
|
||||||
}
|
|
||||||
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") {
|
if ($count -eq $ToggleSwitchReg.Count) {
|
||||||
$HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden
|
Write-Debug "$($ToggleSwitchReg.Name) is true (count: $count)"
|
||||||
if($HiddenFiles -eq 0){
|
return $true
|
||||||
|
} else {
|
||||||
|
Write-Debug "$($ToggleSwitchReg.Name) is false (count: $count)"
|
||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
else{
|
} 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
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,12 @@ function Get-WinUtilVariables {
|
|||||||
$keys = ($sync.keys).where{ $_ -like "WPF*" }
|
$keys = ($sync.keys).where{ $_ -like "WPF*" }
|
||||||
if ($Type) {
|
if ($Type) {
|
||||||
$output = $keys | ForEach-Object {
|
$output = $keys | ForEach-Object {
|
||||||
Try {
|
try {
|
||||||
$objType = $sync["$psitem"].GetType().Name
|
$objType = $sync["$psitem"].GetType().Name
|
||||||
if ($Type -contains $objType) {
|
if ($Type -contains $objType) {
|
||||||
Write-Output $psitem
|
Write-Output $psitem
|
||||||
}
|
}
|
||||||
}
|
} catch {
|
||||||
Catch {
|
|
||||||
<#I am here so errors don't get outputted for a couple variables that don't have the .GetType() attribute#>
|
<#I am here so errors don't get outputted for a couple variables that don't have the .GetType() attribute#>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
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')
|
|
||||||
}
|
|
||||||
}
|
|
12
functions/private/Hide-WPFInstallAppBusy.ps1
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
function Hide-WPFInstallAppBusy {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Hides the busy overlay in the install app area of the WPF form.
|
||||||
|
This is used to indicate that an install or uninstall has finished.
|
||||||
|
#>
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{
|
||||||
|
$sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
$sync.InstallAppAreaBorder.IsEnabled = $true
|
||||||
|
$sync.InstallAppAreaScrollViewer.Effect.Radius = 0
|
||||||
|
})
|
||||||
|
}
|
74
functions/private/Initalize-InstallAppEntry.ps1
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
function Initialize-InstallAppEntry {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates the app entry to be placed on the isntall tab for a given app
|
||||||
|
Used to as part of the Install Tab UI generation
|
||||||
|
.PARAMETER TargetElement
|
||||||
|
The Element into which the Apps should be placed
|
||||||
|
.PARAMETER appKey
|
||||||
|
The Key of the app inside the $sync.configs.applicationsHashtable
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
[Windows.Controls.WrapPanel]$TargetElement,
|
||||||
|
$appKey
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the outer Border for the application type
|
||||||
|
$border = New-Object Windows.Controls.Border
|
||||||
|
$border.Style = $sync.Form.Resources.AppEntryBorderStyle
|
||||||
|
$border.Tag = $appKey
|
||||||
|
$border.ToolTip = $Apps.$appKey.description
|
||||||
|
$border.Add_MouseLeftButtonUp({
|
||||||
|
$childCheckbox = ($this.Child | Where-Object {$_.Template.TargetType -eq [System.Windows.Controls.Checkbox]})[0]
|
||||||
|
$childCheckBox.isChecked = -not $childCheckbox.IsChecked
|
||||||
|
})
|
||||||
|
$border.Add_MouseEnter({
|
||||||
|
if (($sync.$($this.Tag).IsChecked) -eq $false) {
|
||||||
|
$this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallHighlightedColor")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$border.Add_MouseLeave({
|
||||||
|
if (($sync.$($this.Tag).IsChecked) -eq $false) {
|
||||||
|
$this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$border.Add_MouseRightButtonUp({
|
||||||
|
# Store the selected app in a global variable so it can be used in the popup
|
||||||
|
$sync.appPopupSelectedApp = $this.Tag
|
||||||
|
# Set the popup position to the current mouse position
|
||||||
|
$sync.appPopup.PlacementTarget = $this
|
||||||
|
$sync.appPopup.IsOpen = $true
|
||||||
|
})
|
||||||
|
|
||||||
|
$checkBox = New-Object Windows.Controls.CheckBox
|
||||||
|
$checkBox.Name = $appKey
|
||||||
|
$checkbox.Style = $sync.Form.Resources.AppEntryCheckboxStyle
|
||||||
|
$checkbox.Add_Checked({
|
||||||
|
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $this
|
||||||
|
$borderElement = $this.Parent
|
||||||
|
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallSelectedColor")
|
||||||
|
})
|
||||||
|
|
||||||
|
$checkbox.Add_Unchecked({
|
||||||
|
Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this
|
||||||
|
$borderElement = $this.Parent
|
||||||
|
$borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor")
|
||||||
|
})
|
||||||
|
|
||||||
|
# Create the TextBlock for the application name
|
||||||
|
$appName = New-Object Windows.Controls.TextBlock
|
||||||
|
$appName.Style = $sync.Form.Resources.AppEntryNameStyle
|
||||||
|
$appName.Text = $Apps.$appKey.content
|
||||||
|
|
||||||
|
# Add the name to the Checkbox
|
||||||
|
$checkBox.Content = $appName
|
||||||
|
|
||||||
|
# Add accessibility properties to make the elements screen reader friendly
|
||||||
|
$checkBox.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $Apps.$appKey.content)
|
||||||
|
$border.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $Apps.$appKey.content)
|
||||||
|
|
||||||
|
$border.Child = $checkBox
|
||||||
|
# Add the border to the corresponding Category
|
||||||
|
$TargetElement.Children.Add($border) | Out-Null
|
||||||
|
return $checkbox
|
||||||
|
}
|
112
functions/private/Initialize-InstallAppArea.ps1
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
function Initialize-InstallAppArea {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Creates a [Windows.Controls.ScrollViewer] containing a [Windows.Controls.ItemsControl] which is setup to use Virtualization to only load the visible elements for performance reasons.
|
||||||
|
This is used as the parent object for all category and app entries on the install tab
|
||||||
|
Used to as part of the Install Tab UI generation
|
||||||
|
|
||||||
|
Also creates an overlay with a progress bar and text to indicate that an install or uninstall is in progress
|
||||||
|
|
||||||
|
.PARAMETER TargetElement
|
||||||
|
The element to which the AppArea shoud be added
|
||||||
|
|
||||||
|
#>
|
||||||
|
param($TargetElement)
|
||||||
|
$targetGrid = $sync.Form.FindName($TargetElement)
|
||||||
|
$null = $targetGrid.Children.Clear()
|
||||||
|
|
||||||
|
# Create the outer Border for the aren where the apps will be placed
|
||||||
|
$Border = New-Object Windows.Controls.Border
|
||||||
|
$Border.VerticalAlignment = "Stretch"
|
||||||
|
$Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle")
|
||||||
|
$sync.InstallAppAreaBorder = $Border
|
||||||
|
|
||||||
|
# Add a ScrollViewer, because the ItemsControl does not support scrolling by itself
|
||||||
|
$scrollViewer = New-Object Windows.Controls.ScrollViewer
|
||||||
|
$scrollViewer.VerticalScrollBarVisibility = 'Auto'
|
||||||
|
$scrollViewer.HorizontalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.VerticalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.CanContentScroll = $true
|
||||||
|
$sync.InstallAppAreaScrollViewer = $scrollViewer
|
||||||
|
$Border.Child = $scrollViewer
|
||||||
|
|
||||||
|
# Initialize the Blur Effect for the ScrollViewer, which will be used to indicate that an install/uninstall is in progress
|
||||||
|
$blurEffect = New-Object Windows.Media.Effects.BlurEffect
|
||||||
|
$blurEffect.Radius = 0
|
||||||
|
$scrollViewer.Effect = $blurEffect
|
||||||
|
|
||||||
|
## Create the ItemsControl, which will be the parent of all the app entries
|
||||||
|
$itemsControl = New-Object Windows.Controls.ItemsControl
|
||||||
|
$itemsControl.HorizontalAlignment = 'Stretch'
|
||||||
|
$itemsControl.VerticalAlignment = 'Stretch'
|
||||||
|
$scrollViewer.Content = $itemsControl
|
||||||
|
|
||||||
|
# Enable virtualization for the ItemsControl to improve performance (It's hard to test if this is actually working, so if you know what you're doing, please check this)
|
||||||
|
$itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate
|
||||||
|
$factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel])
|
||||||
|
$itemsPanelTemplate.VisualTree = $factory
|
||||||
|
$itemsControl.ItemsPanel = $itemsPanelTemplate
|
||||||
|
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true)
|
||||||
|
$itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling)
|
||||||
|
|
||||||
|
# Add the Border containing the App Area to the target Grid
|
||||||
|
$targetGrid.Children.Add($Border) | Out-Null
|
||||||
|
|
||||||
|
$overlay = New-Object Windows.Controls.Border
|
||||||
|
$overlay.CornerRadius = New-Object Windows.CornerRadius(10)
|
||||||
|
$overlay.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallOverlayBackgroundColor")
|
||||||
|
$overlay.Visibility = [Windows.Visibility]::Collapsed
|
||||||
|
|
||||||
|
# Also add the overlay to the target Grid on top of the App Area
|
||||||
|
$targetGrid.Children.Add($overlay) | Out-Null
|
||||||
|
$sync.InstallAppAreaOverlay = $overlay
|
||||||
|
|
||||||
|
$overlayText = New-Object Windows.Controls.TextBlock
|
||||||
|
$overlayText.Text = "Installing apps..."
|
||||||
|
$overlayText.HorizontalAlignment = 'Center'
|
||||||
|
$overlayText.VerticalAlignment = 'Center'
|
||||||
|
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "MainForegroundColor")
|
||||||
|
$overlayText.Background = "Transparent"
|
||||||
|
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontSizeProperty, "HeaderFontSize")
|
||||||
|
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontFamilyProperty, "MainFontFamily")
|
||||||
|
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontWeightProperty, "MainFontWeight")
|
||||||
|
$overlayText.SetResourceReference([Windows.Controls.TextBlock]::MarginProperty, "MainMargin")
|
||||||
|
$sync.InstallAppAreaOverlayText = $overlayText
|
||||||
|
|
||||||
|
$progressbar = New-Object Windows.Controls.ProgressBar
|
||||||
|
$progressbar.Name = "ProgressBar"
|
||||||
|
$progressbar.Width = 250
|
||||||
|
$progressbar.Height = 50
|
||||||
|
$sync.ProgressBar = $progressbar
|
||||||
|
|
||||||
|
# Add a TextBlock overlay for the progress bar text
|
||||||
|
$progressBarTextBlock = New-Object Windows.Controls.TextBlock
|
||||||
|
$progressBarTextBlock.Name = "progressBarTextBlock"
|
||||||
|
$progressBarTextBlock.FontWeight = [Windows.FontWeights]::Bold
|
||||||
|
$progressBarTextBlock.FontSize = 16
|
||||||
|
$progressBarTextBlock.Width = $progressbar.Width
|
||||||
|
$progressBarTextBlock.Height = $progressbar.Height
|
||||||
|
$progressBarTextBlock.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "ProgressBarTextColor")
|
||||||
|
$progressBarTextBlock.TextTrimming = "CharacterEllipsis"
|
||||||
|
$progressBarTextBlock.Background = "Transparent"
|
||||||
|
$sync.progressBarTextBlock = $progressBarTextBlock
|
||||||
|
|
||||||
|
# Create a Grid to overlay the text on the progress bar
|
||||||
|
$progressGrid = New-Object Windows.Controls.Grid
|
||||||
|
$progressGrid.Width = $progressbar.Width
|
||||||
|
$progressGrid.Height = $progressbar.Height
|
||||||
|
$progressGrid.Margin = "0,10,0,10"
|
||||||
|
$progressGrid.Children.Add($progressbar) | Out-Null
|
||||||
|
$progressGrid.Children.Add($progressBarTextBlock) | Out-Null
|
||||||
|
|
||||||
|
$overlayStackPanel = New-Object Windows.Controls.StackPanel
|
||||||
|
$overlayStackPanel.Orientation = "Vertical"
|
||||||
|
$overlayStackPanel.HorizontalAlignment = 'Center'
|
||||||
|
$overlayStackPanel.VerticalAlignment = 'Center'
|
||||||
|
$overlayStackPanel.Children.Add($overlayText) | Out-Null
|
||||||
|
$overlayStackPanel.Children.Add($progressGrid) | Out-Null
|
||||||
|
|
||||||
|
$overlay.Child = $overlayStackPanel
|
||||||
|
|
||||||
|
return $itemsControl
|
||||||
|
}
|
56
functions/private/Initialize-InstallCategoryAppList.ps1
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
function Initialize-InstallCategoryAppList {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Clears the Target Element and sets up a "Loading" message. This is done, because loading of all apps can take a bit of time in some scenarios
|
||||||
|
Iterates through all Categories and Apps and adds them to the UI
|
||||||
|
Used to as part of the Install Tab UI generation
|
||||||
|
.PARAMETER TargetElement
|
||||||
|
The Element into which the Categories and Apps should be placed
|
||||||
|
.PARAMETER Apps
|
||||||
|
The Hashtable of Apps to be added to the UI
|
||||||
|
The Categories are also extracted from the Apps Hashtable
|
||||||
|
|
||||||
|
#>
|
||||||
|
param(
|
||||||
|
$TargetElement,
|
||||||
|
$Apps
|
||||||
|
)
|
||||||
|
function Add-Category {
|
||||||
|
param(
|
||||||
|
[string]$Category,
|
||||||
|
[Windows.Controls.ItemsControl]$TargetElement
|
||||||
|
)
|
||||||
|
|
||||||
|
$toggleButton = New-Object Windows.Controls.Label
|
||||||
|
$toggleButton.Content = "$Category"
|
||||||
|
$toggleButton.Tag = "CategoryToggleButton"
|
||||||
|
$sync.$Category = $Category
|
||||||
|
|
||||||
|
$null = $TargetElement.Items.Add($toggleButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Pre-group apps by category
|
||||||
|
$appsByCategory = @{}
|
||||||
|
foreach ($appKey in $Apps.Keys) {
|
||||||
|
$category = $Apps.$appKey.Category
|
||||||
|
if (-not $appsByCategory.ContainsKey($category)) {
|
||||||
|
$appsByCategory[$category] = @()
|
||||||
|
}
|
||||||
|
$appsByCategory[$category] += $appKey
|
||||||
|
}
|
||||||
|
foreach ($category in $($appsByCategory.Keys | Sort-Object)) {
|
||||||
|
Add-Category -Category $category -TargetElement $TargetElement
|
||||||
|
$wrapPanel = New-Object Windows.Controls.WrapPanel
|
||||||
|
$wrapPanel.Orientation = "Horizontal"
|
||||||
|
$wrapPanel.HorizontalAlignment = "Stretch"
|
||||||
|
$wrapPanel.VerticalAlignment = "Center"
|
||||||
|
$wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 20)
|
||||||
|
$wrapPanel.Visibility = [Windows.Visibility]::Visible
|
||||||
|
$wrapPanel.Tag = "CategoryWrapPanel_$category"
|
||||||
|
$null = $TargetElement.Items.Add($wrapPanel)
|
||||||
|
$appsByCategory[$category] |Sort-Object | ForEach-Object {
|
||||||
|
$sync.$_ = $(Initialize-InstallAppEntry -TargetElement $wrapPanel -AppKey $_)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,13 +13,13 @@ function Install-WinUtilChoco {
|
|||||||
if((Test-WinUtilPackageManager -choco) -eq "installed") {
|
if((Test-WinUtilPackageManager -choco) -eq "installed") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
# Install logic taken from https://chocolatey.org/install#individual
|
||||||
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;
|
||||||
powershell choco feature enable -n allowGlobalConfirmation
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
|
||||||
|
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
||||||
|
|
||||||
}
|
} catch {
|
||||||
Catch {
|
|
||||||
Write-Host "===========================================" -Foregroundcolor Red
|
Write-Host "===========================================" -Foregroundcolor Red
|
||||||
Write-Host "-- Chocolatey failed to install ---" -Foregroundcolor Red
|
Write-Host "-- Chocolatey failed to install ---" -Foregroundcolor Red
|
||||||
Write-Host "===========================================" -Foregroundcolor Red
|
Write-Host "===========================================" -Foregroundcolor Red
|
||||||
|
@ -1,91 +1,258 @@
|
|||||||
function Install-WinUtilProgramChoco {
|
function Install-WinUtilProgramChoco {
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Manages the provided programs using Chocolatey
|
Manages the installation or uninstallation of a list of Chocolatey packages.
|
||||||
|
|
||||||
.PARAMETER ProgramsToInstall
|
.PARAMETER Programs
|
||||||
A list of programs to manage
|
A string array containing the programs to be installed or uninstalled.
|
||||||
|
|
||||||
.PARAMETER manage
|
.PARAMETER Action
|
||||||
The action to perform on the programs, can be either 'Installing' or 'Uninstalling'
|
Specifies the action to perform: "Install" or "Uninstall". The default value is "Install".
|
||||||
|
|
||||||
.NOTES
|
.DESCRIPTION
|
||||||
The triple quotes are required any time you need a " in a normal script block.
|
This function processes a list of programs to be managed using Chocolatey. Depending on the specified action, it either installs or uninstalls each program in the list, updating the taskbar progress accordingly. After all operations are completed, temporary output files are cleaned up.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Install-WinUtilProgramChoco -Programs @("7zip","chrome") -Action "Uninstall"
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory, Position = 0)]
|
[Parameter(Mandatory, Position = 0)]
|
||||||
[PsCustomObject]$ProgramsToInstall,
|
[string[]]$Programs,
|
||||||
|
|
||||||
[Parameter(Position = 1)]
|
[Parameter(Position = 1)]
|
||||||
[String]$manage = "Installing"
|
[String]$Action = "Install"
|
||||||
)
|
)
|
||||||
|
|
||||||
$x = 0
|
function Initialize-OutputFile {
|
||||||
$count = $ProgramsToInstall.Count
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Initializes an output file by removing any existing file and creating a new, empty file at the specified path.
|
||||||
|
|
||||||
# This check isn't really necessary, as there's a couple of checks before this Private Function gets called, but just to make sure ;)
|
.PARAMETER filePath
|
||||||
if($count -le 0) {
|
The full path to the file to be initialized.
|
||||||
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."
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This function ensures that the specified file is reset by removing any existing file at the provided path and then creating a new, empty file. It is useful when preparing a log or output file for subsequent operations.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Initialize-OutputFile -filePath "C:\temp\output.txt"
|
||||||
|
#>
|
||||||
|
|
||||||
|
param ($filePath)
|
||||||
|
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
|
||||||
|
New-Item -ItemType File -Path $filePath | Out-Null
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0
|
function Invoke-ChocoCommand {
|
||||||
Write-Host "==========================================="
|
<#
|
||||||
Write-Host "-- Configuring Chocolatey pacakages ---"
|
.SYNOPSIS
|
||||||
Write-Host "==========================================="
|
Executes a Chocolatey command with the specified arguments and returns the exit code.
|
||||||
Foreach ($Program in $ProgramsToInstall){
|
|
||||||
Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.choco) $($x + 1) of $count" -PercentComplete $($x/$count*100)
|
.PARAMETER arguments
|
||||||
if($manage -eq "Installing"){
|
The arguments to be passed to the Chocolatey command.
|
||||||
write-host "Starting install of $($Program.choco) with Chocolatey."
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This function runs a specified Chocolatey command by passing the provided arguments to the `choco` executable. It waits for the process to complete and then returns the exit code, allowing the caller to determine success or failure based on the exit code.
|
||||||
|
|
||||||
|
.RETURNS
|
||||||
|
[int]
|
||||||
|
The exit code of the Chocolatey command.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$exitCode = Invoke-ChocoCommand -arguments "install 7zip -y"
|
||||||
|
#>
|
||||||
|
|
||||||
|
param ($arguments)
|
||||||
|
return (Start-Process -FilePath "choco" -ArgumentList $arguments -Wait -PassThru).ExitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-UpgradeNeeded {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Checks if an upgrade is needed for a Chocolatey package based on the content of a log file.
|
||||||
|
|
||||||
|
.PARAMETER filePath
|
||||||
|
The path to the log file that contains the output of a Chocolatey install command.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This function reads the specified log file and checks for keywords that indicate whether an upgrade is needed. It returns a boolean value indicating whether the terms "reinstall" or "already installed" are present, which suggests that the package might need an upgrade.
|
||||||
|
|
||||||
|
.RETURNS
|
||||||
|
[bool]
|
||||||
|
True if the log file indicates that an upgrade is needed; otherwise, false.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$isUpgradeNeeded = Test-UpgradeNeeded -filePath "C:\temp\install-output.txt"
|
||||||
|
#>
|
||||||
|
|
||||||
|
param ($filePath)
|
||||||
|
return Get-Content -Path $filePath | Select-String -Pattern "reinstall|already installed" -Quiet
|
||||||
|
}
|
||||||
|
|
||||||
|
function Update-TaskbarProgress {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Updates the taskbar progress based on the current installation progress.
|
||||||
|
|
||||||
|
.PARAMETER currentIndex
|
||||||
|
The current index of the program being installed or uninstalled.
|
||||||
|
|
||||||
|
.PARAMETER totalPrograms
|
||||||
|
The total number of programs to be installed or uninstalled.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This function calculates the progress of the installation or uninstallation process and updates the taskbar accordingly. The taskbar is set to "Normal" if all programs have been processed, otherwise, it is set to "Error" as a placeholder.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Update-TaskbarProgress -currentIndex 3 -totalPrograms 10
|
||||||
|
#>
|
||||||
|
|
||||||
|
param (
|
||||||
|
[int]$currentIndex,
|
||||||
|
[int]$totalPrograms
|
||||||
|
)
|
||||||
|
$progressState = if ($currentIndex -eq $totalPrograms) { "Normal" } else { "Error" }
|
||||||
|
$sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state $progressState -value ($currentIndex / $totalPrograms) })
|
||||||
|
}
|
||||||
|
|
||||||
|
function Install-ChocoPackage {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Installs a Chocolatey package and optionally upgrades it if needed.
|
||||||
|
|
||||||
|
.PARAMETER Program
|
||||||
|
A string containing the name of the Chocolatey package to be installed.
|
||||||
|
|
||||||
|
.PARAMETER currentIndex
|
||||||
|
The current index of the program in the list of programs to be managed.
|
||||||
|
|
||||||
|
.PARAMETER totalPrograms
|
||||||
|
The total number of programs to be installed.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This function installs a Chocolatey package by running the `choco install` command. If the installation output indicates that an upgrade might be needed, the function will attempt to upgrade the package. The taskbar progress is updated after each package is processed.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Install-ChocoPackage -Program $Program -currentIndex 0 -totalPrograms 5
|
||||||
|
#>
|
||||||
|
|
||||||
|
param (
|
||||||
|
[string]$Program,
|
||||||
|
[int]$currentIndex,
|
||||||
|
[int]$totalPrograms
|
||||||
|
)
|
||||||
|
|
||||||
|
$installOutputFile = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
|
||||||
|
Initialize-OutputFile $installOutputFile
|
||||||
|
|
||||||
|
Write-Host "Starting installation of $Program with Chocolatey."
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$tryUpgrade = $false
|
$installStatusCode = Invoke-ChocoCommand "install $Program -y --log-file $installOutputFile"
|
||||||
$installOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt"
|
if ($installStatusCode -eq 0) {
|
||||||
New-Item -ItemType File -Path $installOutputFilePath
|
|
||||||
$chocoInstallStatus = $(Start-Process -FilePath "choco" -ArgumentList "install $($Program.choco) -y" -Wait -PassThru -RedirectStandardOutput $installOutputFilePath).ExitCode
|
if (Test-UpgradeNeeded $installOutputFile) {
|
||||||
if(($chocoInstallStatus -eq 0) -AND (Test-Path -Path $installOutputFilePath)) {
|
$upgradeStatusCode = Invoke-ChocoCommand "upgrade $Program -y"
|
||||||
$keywordsFound = Get-Content -Path $installOutputFilePath | Where-Object {$_ -match "reinstall" -OR $_ -match "already installed"}
|
Write-Host "$Program was" $(if ($upgradeStatusCode -eq 0) { "upgraded successfully." } else { "not upgraded." })
|
||||||
if ($keywordsFound) {
|
}
|
||||||
$tryUpgrade = $true
|
else {
|
||||||
|
Write-Host "$Program installed successfully."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# 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.
|
else {
|
||||||
if ($tryUpgrade) {
|
Write-Host "Failed to install $Program."
|
||||||
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."
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
Write-Host "Failed to install $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $installOutputFilePath)."
|
|
||||||
}
|
}
|
||||||
} catch {
|
catch {
|
||||||
Write-Host "Failed to install $($Program.choco) due to an error: $_"
|
Write-Host "Failed to install $Program due to an error: $_"
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Update-TaskbarProgress $currentIndex $totalPrograms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($manage -eq "Uninstalling"){
|
function Uninstall-ChocoPackage {
|
||||||
write-host "Starting uninstall of $($Program.choco) with Chocolatey."
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Uninstalls a Chocolatey package and any related metapackages.
|
||||||
|
|
||||||
|
.PARAMETER Program
|
||||||
|
A string containing the name of the Chocolatey package to be uninstalled.
|
||||||
|
|
||||||
|
.PARAMETER currentIndex
|
||||||
|
The current index of the program in the list of programs to be managed.
|
||||||
|
|
||||||
|
.PARAMETER totalPrograms
|
||||||
|
The total number of programs to be uninstalled.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
This function uninstalls a Chocolatey package and any related metapackages (e.g., .install or .portable variants). It updates the taskbar progress after processing each package.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
Uninstall-ChocoPackage -Program $Program -currentIndex 0 -totalPrograms 5
|
||||||
|
#>
|
||||||
|
|
||||||
|
param (
|
||||||
|
[string]$Program,
|
||||||
|
[int]$currentIndex,
|
||||||
|
[int]$totalPrograms
|
||||||
|
)
|
||||||
|
|
||||||
|
$uninstallOutputFile = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt"
|
||||||
|
Initialize-OutputFile $uninstallOutputFile
|
||||||
|
|
||||||
|
Write-Host "Searching for metapackages of $Program (.install or .portable)"
|
||||||
|
$chocoPackages = ((choco list | Select-String -Pattern "$Program(\.install|\.portable)?").Matches.Value) -join " "
|
||||||
|
if ($chocoPackages) {
|
||||||
|
Write-Host "Starting uninstallation of $chocoPackages with Chocolatey."
|
||||||
try {
|
try {
|
||||||
$uninstallOutputFilePath = "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt"
|
$uninstallStatusCode = Invoke-ChocoCommand "uninstall $chocoPackages -y"
|
||||||
New-Item -ItemType File -Path $uninstallOutputFilePath
|
Write-Host "$Program" $(if ($uninstallStatusCode -eq 0) { "uninstalled successfully." } else { "failed to uninstall." })
|
||||||
$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."
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
Write-Host "Failed to uninstall $($Program.choco) using Chocolatey, Chocolatey output:`n`n$(Get-Content -Path $uninstallOutputFilePath)."
|
|
||||||
}
|
}
|
||||||
} catch {
|
catch {
|
||||||
Write-Host "Failed to uninstall $($Program.choco) due to an error: $_"
|
Write-Host "Failed to uninstall $Program due to an error: $_"
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Update-TaskbarProgress $currentIndex $totalPrograms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$x++
|
else {
|
||||||
|
Write-Host "$Program is not installed."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
|
|
||||||
|
|
||||||
# Cleanup leftovers files
|
$totalPrograms = $Programs.Count
|
||||||
if(Test-Path -Path $installOutputFilePath){ Remove-Item -Path $installOutputFilePath }
|
if ($totalPrograms -le 0) {
|
||||||
if(Test-Path -Path $uninstallOutputFilePath){ Remove-Item -Path $uninstallOutputFilePath }
|
throw "Parameter 'Programs' must have at least one item."
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Host "==========================================="
|
||||||
|
Write-Host "-- Configuring Chocolatey packages ---"
|
||||||
|
Write-Host "==========================================="
|
||||||
|
|
||||||
|
for ($currentIndex = 0; $currentIndex -lt $totalPrograms; $currentIndex++) {
|
||||||
|
$Program = $Programs[$currentIndex]
|
||||||
|
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($currentIndex / $totalPrograms * 100)
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($currentIndex / $totalPrograms)})
|
||||||
|
|
||||||
|
switch ($Action) {
|
||||||
|
"Install" {
|
||||||
|
Install-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms
|
||||||
|
}
|
||||||
|
"Uninstall" {
|
||||||
|
Uninstall-ChocoPackage -Program $Program -currentIndex $currentIndex -totalPrograms $totalPrograms
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
throw "Invalid action parameter value: '$Action'."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100
|
||||||
|
# Cleanup Output Files
|
||||||
|
$outputFiles = @("$env:TEMP\Install-WinUtilProgramChoco.install-command.output.txt", "$env:TEMP\Install-WinUtilProgramChoco.uninstall-command.output.txt")
|
||||||
|
foreach ($filePath in $outputFiles) {
|
||||||
|
Remove-Item -Path $filePath -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,106 +1,169 @@
|
|||||||
Function Install-WinUtilProgramWinget {
|
Function Install-WinUtilProgramWinget {
|
||||||
|
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Manages the provided programs using Winget
|
Runs the designated action on the provided programs using Winget
|
||||||
|
|
||||||
.PARAMETER ProgramsToInstall
|
.PARAMETER Programs
|
||||||
A list of programs to manage
|
A list of programs to process
|
||||||
|
|
||||||
.PARAMETER manage
|
.PARAMETER action
|
||||||
The action to perform on the programs, can be either 'Installing' or 'Uninstalling'
|
The action to perform on the programs, can be either 'Install' or 'Uninstall'
|
||||||
|
|
||||||
.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
|
The winget Return codes are documented here: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-actionr/winget/returnCodes.md
|
||||||
#>
|
#>
|
||||||
|
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory, Position=0)]
|
[Parameter(Mandatory, Position=0)]$Programs,
|
||||||
[PsCustomObject]$ProgramsToInstall,
|
|
||||||
|
|
||||||
[Parameter(Position=1)]
|
[Parameter(Mandatory, Position=1)]
|
||||||
[String]$manage = "Installing"
|
[ValidateSet("Install", "Uninstall")]
|
||||||
|
[String]$Action
|
||||||
)
|
)
|
||||||
|
|
||||||
$count = $ProgramsToInstall.Count
|
Function Invoke-Winget {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Invokes the winget.exe with the provided arguments and return the exit code
|
||||||
|
|
||||||
Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0
|
.PARAMETER wingetId
|
||||||
Write-Host "==========================================="
|
The Id of the Program that Winget should Install/Uninstall
|
||||||
Write-Host "-- Configuring winget packages ---"
|
|
||||||
Write-Host "==========================================="
|
.PARAMETER scope
|
||||||
for ($i = 0; $i -le $ProgramsToInstall.Count; $i++) {
|
Determines the installation mode. Can be "user" or "machine" (For more info look at the winget documentation)
|
||||||
$Program = $ProgramsToInstall[$i]
|
|
||||||
$failedPackages = @()
|
.PARAMETER credential
|
||||||
Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.winget) $($i + 1) of $count" -PercentComplete $(($i/$count) * 100)
|
The PSCredential Object of the user that should be used to run winget
|
||||||
if($manage -eq "Installing") {
|
|
||||||
# Install package via ID, if it fails try again with different scope and then with an unelevated prompt.
|
.NOTES
|
||||||
# Since Install-WinGetPackage might not be directly available, we use winget install command as a workaround.
|
Invoke Winget uses the public variable $Action defined outside the function to determine if a Program should be installed or removed
|
||||||
# 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.
|
param (
|
||||||
Write-Host "Starting install of $($Program.winget) with winget."
|
[string]$wingetId,
|
||||||
try {
|
[string]$scope = "",
|
||||||
$status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode
|
[PScredential]$credential = $null
|
||||||
|
)
|
||||||
|
|
||||||
|
$commonArguments = "--id $wingetId --silent"
|
||||||
|
$arguments = if ($Action -eq "Install") {
|
||||||
|
"install $commonArguments --accept-source-agreements --accept-package-agreements $(if ($scope) {" --scope $scope"})"
|
||||||
|
} else {
|
||||||
|
"uninstall $commonArguments"
|
||||||
|
}
|
||||||
|
|
||||||
|
$processParams = @{
|
||||||
|
FilePath = "winget"
|
||||||
|
ArgumentList = $arguments
|
||||||
|
Wait = $true
|
||||||
|
PassThru = $true
|
||||||
|
NoNewWindow = $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($credential) {
|
||||||
|
$processParams.credential = $credential
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Start-Process @processParams).ExitCode
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Invoke-Install {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Contains the Install Logic and return code handling from winget
|
||||||
|
|
||||||
|
.PARAMETER Program
|
||||||
|
The Winget ID of the Program that should be installed
|
||||||
|
#>
|
||||||
|
param (
|
||||||
|
[string]$Program
|
||||||
|
)
|
||||||
|
$status = Invoke-Winget -wingetId $Program
|
||||||
if ($status -eq 0) {
|
if ($status -eq 0) {
|
||||||
Write-Host "$($Program.winget) installed successfully."
|
Write-Host "$($Program) installed successfully."
|
||||||
continue
|
return $true
|
||||||
|
} elseif ($status -eq -1978335189) {
|
||||||
|
Write-Host "$($Program) No applicable update found"
|
||||||
|
return $true
|
||||||
}
|
}
|
||||||
if ($status -eq -1978335189) {
|
|
||||||
Write-Host "$($Program.winget) No applicable update found"
|
Write-Host "Attempt installation of $($Program) with User scope"
|
||||||
continue
|
$status = Invoke-Winget -wingetId $Program -scope "user"
|
||||||
}
|
|
||||||
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) {
|
if ($status -eq 0) {
|
||||||
Write-Host "$($Program.winget) installed successfully with User scope."
|
Write-Host "$($Program) installed successfully with User scope."
|
||||||
continue
|
return $true
|
||||||
|
} elseif ($status -eq -1978335189) {
|
||||||
|
Write-Host "$($Program) No applicable update found"
|
||||||
|
return $true
|
||||||
}
|
}
|
||||||
if ($status -eq -1978335189) {
|
|
||||||
Write-Host "$($Program.winget) No applicable update found"
|
$userChoice = [System.Windows.MessageBox]::Show("Do you want to attempt $($Program) installation with specific user credentials? Select 'Yes' to proceed or 'No' to skip.", "User credential Prompt", [System.Windows.MessageBoxButton]::YesNo)
|
||||||
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') {
|
if ($userChoice -eq 'Yes') {
|
||||||
$getcreds = Get-Credential
|
$getcreds = Get-Credential
|
||||||
$process = Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Credential $getcreds -PassThru -NoNewWindow
|
$status = Invoke-Winget -wingetId $Program -credential $getcreds
|
||||||
Wait-Process -Id $process.Id
|
if ($status -eq 0) {
|
||||||
$status = $process.ExitCode
|
Write-Host "$($Program) installed successfully with User prompt."
|
||||||
|
return $true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Write-Host "Skipping installation with specific user credentials."
|
Write-Host "Skipping installation with specific user credentials."
|
||||||
}
|
}
|
||||||
if($status -eq 0) {
|
|
||||||
Write-Host "$($Program.winget) installed successfully with User prompt."
|
Write-Host "Failed to install $($Program)."
|
||||||
continue
|
return $false
|
||||||
}
|
}
|
||||||
if ($status -eq -1978335189) {
|
|
||||||
Write-Host "$($Program.winget) No applicable update found"
|
Function Invoke-Uninstall {
|
||||||
continue
|
<#
|
||||||
}
|
.SYNOPSIS
|
||||||
} catch {
|
Contains the Uninstall Logic and return code handling from winget
|
||||||
Write-Host "Failed to install $($Program.winget). With winget"
|
|
||||||
$failedPackages += $Program
|
.PARAMETER Program
|
||||||
}
|
The Winget ID of the Program that should be uninstalled
|
||||||
}
|
#>
|
||||||
elseif($manage -eq "Uninstalling") {
|
param (
|
||||||
# Uninstall package via ID using winget directly.
|
[psobject]$Program
|
||||||
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode
|
$status = Invoke-Winget -wingetId $Program
|
||||||
if($status -ne 0) {
|
if ($status -eq 0) {
|
||||||
Write-Host "Failed to uninstall $($Program.winget)."
|
Write-Host "$($Program) uninstalled successfully."
|
||||||
|
return $true
|
||||||
} else {
|
} else {
|
||||||
Write-Host "$($Program.winget) uninstalled successfully."
|
Write-Host "Failed to uninstall $($Program)."
|
||||||
$failedPackages += $Program
|
return $false
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
Write-Host "Failed to uninstall $($Program.winget) due to an error: $_"
|
Write-Host "Failed to uninstall $($Program) due to an error: $_"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = $Programs.Count
|
||||||
|
$failedPackages = @()
|
||||||
|
|
||||||
|
Write-Host "==========================================="
|
||||||
|
Write-Host "-- Configuring winget packages ---"
|
||||||
|
Write-Host "==========================================="
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $count; $i++) {
|
||||||
|
$Program = $Programs[$i]
|
||||||
|
$result = $false
|
||||||
|
Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100)
|
||||||
|
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i / $count)})
|
||||||
|
|
||||||
|
$result = switch ($Action) {
|
||||||
|
"Install" {Invoke-Install -Program $Program}
|
||||||
|
"Uninstall" {Invoke-Uninstall -Program $Program}
|
||||||
|
default {throw "[Install-WinUtilProgramWinget] Invalid action: $Action"}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $result) {
|
||||||
$failedPackages += $Program
|
$failedPackages += $Program
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage"
|
Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100
|
||||||
}
|
return $failedPackages
|
||||||
}
|
|
||||||
Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed
|
|
||||||
return $failedPackages;
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ function Install-WinUtilWinget {
|
|||||||
#>
|
#>
|
||||||
$isWingetInstalled = Test-WinUtilPackageManager -winget
|
$isWingetInstalled = Test-WinUtilPackageManager -winget
|
||||||
|
|
||||||
Try {
|
try {
|
||||||
if ($isWingetInstalled -eq "installed") {
|
if ($isWingetInstalled -eq "installed") {
|
||||||
Write-Host "`nWinget is already installed.`r" -ForegroundColor Green
|
Write-Host "`nWinget is already installed.`r" -ForegroundColor Green
|
||||||
return
|
return
|
||||||
@ -19,6 +19,7 @@ function Install-WinUtilWinget {
|
|||||||
Write-Host "`nWinget is not Installed. Continuing with install.`r" -ForegroundColor Red
|
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
|
||||||
@ -32,35 +33,44 @@ function Install-WinUtilWinget {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
# Install Winget via GitHub method.
|
Write-Host "Attempting to install/update Winget`r"
|
||||||
# Used part of my own script with some modification: ruxunderscore/windows-initialization
|
try {
|
||||||
Write-Host "Downloading Winget Prerequsites`n"
|
$wingetCmd = Get-Command winget -ErrorAction Stop
|
||||||
Get-WinUtilWingetPrerequisites
|
Write-Information "Attempting to update WinGet using WinGet..."
|
||||||
Write-Host "Downloading Winget and License File`r"
|
$result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
|
||||||
Get-WinUtilWingetLatest
|
if ($result.ExitCode -ne 0) {
|
||||||
Write-Host "Installing Winget w/ Prerequsites`r"
|
throw "WinGet update failed with exit code: $($result.ExitCode)"
|
||||||
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"
|
Write-Output "Refreshing Environment Variables...`n"
|
||||||
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
} Catch {
|
return
|
||||||
Write-Host "Failure detected while installing via GitHub method. Continuing with Chocolatey method as fallback." -ForegroundColor Red
|
} catch {
|
||||||
# In case install fails via GitHub method.
|
Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..."
|
||||||
Try {
|
}
|
||||||
# Install Choco if not already present
|
try {
|
||||||
Install-WinUtilChoco
|
Write-Host "Attempting to repair WinGet using Repair-WinGetPackageManager..." -ForegroundColor Yellow
|
||||||
Start-Process -Verb runas -FilePath powershell.exe -ArgumentList "choco install winget-cli"
|
|
||||||
Write-Host "Winget Installed" -ForegroundColor Green
|
# Check if Windows version supports Repair-WinGetPackageManager (24H2 and above)
|
||||||
|
if ([System.Environment]::OSVersion.Version.Build -ge 26100) {
|
||||||
|
Repair-WinGetPackageManager -Force -Latest -Verbose
|
||||||
|
# Verify if repair was successful
|
||||||
|
$wingetCmd = Get-Command winget -ErrorAction Stop
|
||||||
|
Write-Host "WinGet repair successful!" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "Repair-WinGetPackageManager is only available on Windows 24H2 and above. Your version doesn't support this method." -ForegroundColor Yellow
|
||||||
|
throw "Windows version not supported for repair method"
|
||||||
|
}
|
||||||
|
|
||||||
Write-Output "Refreshing Environment Variables...`n"
|
Write-Output "Refreshing Environment Variables...`n"
|
||||||
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
} Catch {
|
return
|
||||||
throw [WingetFailedInstall]::new('Failed to install!')
|
|
||||||
}
|
} catch {
|
||||||
|
Write-Error "All installation methods failed. Unable to install WinGet."
|
||||||
|
throw
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Error "An error occurred during WinGet installation: $_"
|
||||||
|
throw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,654 +0,0 @@
|
|||||||
function Test-CompatibleImage() {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
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 Name
|
|
||||||
imgVersion - The version of the Windows image
|
|
||||||
desiredVersion - The version to compare the image version with
|
|
||||||
|
|
||||||
#>
|
|
||||||
|
|
||||||
param
|
|
||||||
(
|
|
||||||
[Parameter(Mandatory = $true, Position=0)] [string] $imgVersion,
|
|
||||||
[Parameter(Mandatory = $true, Position=1)] [Version] $desiredVersion
|
|
||||||
)
|
|
||||||
|
|
||||||
try {
|
|
||||||
$version = [Version]$imgVersion
|
|
||||||
return $version -ge $desiredVersion
|
|
||||||
} catch {
|
|
||||||
return $False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Remove-Features([switch] $dumpFeatures = $false, [switch] $keepDefender = $false) {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Removes certain features from ISO image
|
|
||||||
|
|
||||||
.PARAMETER Name
|
|
||||||
dumpFeatures - Dumps all features found in the ISO into a file called allfeaturesdump.txt. This file can be examined and used to decide what to remove.
|
|
||||||
keepDefender - Should Defender be removed from the ISO?
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
Remove-Features -keepDefender:$false
|
|
||||||
|
|
||||||
#>
|
|
||||||
$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."
|
|
||||||
}
|
|
||||||
|
|
||||||
function Remove-Packages
|
|
||||||
{
|
|
||||||
$pkglist = (Get-WindowsPackage -Path "$scratchDir").PackageName
|
|
||||||
|
|
||||||
$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
|
|
||||||
}
|
|
||||||
|
|
||||||
function Remove-ProvisionedPackages([switch] $keepSecurity = $false)
|
|
||||||
{
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Removes AppX packages from a Windows image during MicroWin processing
|
|
||||||
|
|
||||||
.PARAMETER Name
|
|
||||||
keepSecurity - Boolean that determines whether to keep "Microsoft.SecHealthUI" (Windows Security) in the Windows image
|
|
||||||
|
|
||||||
.EXAMPLE
|
|
||||||
Remove-ProvisionedPackages -keepSecurity:$false
|
|
||||||
|
|
||||||
#>
|
|
||||||
$appxProvisionedPackages = Get-AppxProvisionedPackage -Path "$($scratchDir)" | Where-Object {
|
|
||||||
$_.PackageName -NotLike "*AppInstaller*" -AND
|
|
||||||
$_.PackageName -NotLike "*Store*" -and
|
|
||||||
$_.PackageName -NotLike "*dism*" -and
|
|
||||||
$_.PackageName -NotLike "*Foundation*" -and
|
|
||||||
$_.PackageName -NotLike "*FodMetadata*" -and
|
|
||||||
$_.PackageName -NotLike "*LanguageFeatures*" -and
|
|
||||||
$_.PackageName -NotLike "*Notepad*" -and
|
|
||||||
$_.PackageName -NotLike "*Printing*" -and
|
|
||||||
$_.PackageName -NotLike "*Wifi*" -and
|
|
||||||
$_.PackageName -NotLike "*Foundation*"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($?)
|
|
||||||
{
|
|
||||||
if ($keepSecurity) { $appxProvisionedPackages = $appxProvisionedPackages | Where-Object { $_.PackageName -NotLike "*SecHealthUI*" }}
|
|
||||||
$counter = 0
|
|
||||||
foreach ($appx in $appxProvisionedPackages)
|
|
||||||
{
|
|
||||||
$status = "Removing Provisioned $($appx.PackageName)"
|
|
||||||
Write-Progress -Activity "Removing Provisioned Apps" -Status $status -PercentComplete ($counter++/$appxProvisionedPackages.Count*100)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Write-Host "Could not get Provisioned App information. Skipping process..."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Copy-ToUSB([string] $fileToCopy)
|
|
||||||
{
|
|
||||||
foreach ($volume in Get-Volume) {
|
|
||||||
if ($volume -and $volume.FileSystemLabel -ieq "ventoy") {
|
|
||||||
$destinationPath = "$($volume.DriveLetter):\"
|
|
||||||
#Copy-Item -Path $fileToCopy -Destination $destinationPath -Force
|
|
||||||
# Get the total size of the file
|
|
||||||
$totalSize = (Get-Item $fileToCopy).length
|
|
||||||
|
|
||||||
Copy-Item -Path $fileToCopy -Destination $destinationPath -Verbose -Force -Recurse -Container -PassThru |
|
|
||||||
ForEach-Object {
|
|
||||||
# Calculate the percentage completed
|
|
||||||
$completed = ($_.BytesTransferred / $totalSize) * 100
|
|
||||||
|
|
||||||
# Display the progress bar
|
|
||||||
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.DriveLetter)"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Write-Host "Ventoy USB Key is not inserted"
|
|
||||||
}
|
|
||||||
|
|
||||||
function Remove-FileOrDirectory([string] $pathToDelete, [string] $mask = "", [switch] $Directory = $false)
|
|
||||||
{
|
|
||||||
if(([string]::IsNullOrEmpty($pathToDelete))) { return }
|
|
||||||
if (-not (Test-Path -Path "$($pathToDelete)")) { return }
|
|
||||||
|
|
||||||
$yesNo = Get-LocalizedYesNo
|
|
||||||
Write-Host "[INFO] In Your local takeown expects '$($yesNo[0])' as a Yes answer."
|
|
||||||
|
|
||||||
# Specify the path to the directory
|
|
||||||
# $directoryPath = "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup"
|
|
||||||
# takeown /a /r /d $yesNo[0] /f "$($directoryPath)" > $null
|
|
||||||
# icacls "$($directoryPath)" /q /c /t /reset > $null
|
|
||||||
# icacls $directoryPath /setowner "*S-1-5-32-544"
|
|
||||||
# icacls $directoryPath /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
|
||||||
# Remove-Item -Path $directoryPath -Recurse -Force
|
|
||||||
|
|
||||||
# # Grant full control to BUILTIN\Administrators using icacls
|
|
||||||
# $directoryPath = "$($scratchDir)\Windows\System32\WebThreatDefSvc"
|
|
||||||
# takeown /a /r /d $yesNo[0] /f "$($directoryPath)" > $null
|
|
||||||
# icacls "$($directoryPath)" /q /c /t /reset > $null
|
|
||||||
# icacls $directoryPath /setowner "*S-1-5-32-544"
|
|
||||||
# icacls $directoryPath /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
|
||||||
# Remove-Item -Path $directoryPath -Recurse -Force
|
|
||||||
|
|
||||||
$itemsToDelete = [System.Collections.ArrayList]::new()
|
|
||||||
|
|
||||||
if ($mask -eq "")
|
|
||||||
{
|
|
||||||
Write-Debug "Adding $($pathToDelete) to array."
|
|
||||||
[void]$itemsToDelete.Add($pathToDelete)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Write-Debug "Adding $($pathToDelete) to array and mask is $($mask)"
|
|
||||||
if ($Directory) { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse -Directory }
|
|
||||||
else { $itemsToDelete = Get-ChildItem $pathToDelete -Include $mask -Recurse }
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($itemToDelete in $itemsToDelete)
|
|
||||||
{
|
|
||||||
$status = "Deleting $($itemToDelete)"
|
|
||||||
Write-Progress -Activity "Removing Items" -Status $status -PercentComplete ($counter++/$itemsToDelete.Count*100)
|
|
||||||
|
|
||||||
if (Test-Path -Path "$($itemToDelete)" -PathType Container)
|
|
||||||
{
|
|
||||||
$status = "Deleting directory: $($itemToDelete)"
|
|
||||||
|
|
||||||
takeown /r /d $yesNo[0] /a /f "$($itemToDelete)"
|
|
||||||
icacls "$($itemToDelete)" /q /c /t /reset
|
|
||||||
icacls $itemToDelete /setowner "*S-1-5-32-544"
|
|
||||||
icacls $itemToDelete /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
|
||||||
Remove-Item -Force -Recurse "$($itemToDelete)"
|
|
||||||
}
|
|
||||||
elseif (Test-Path -Path "$($itemToDelete)" -PathType Leaf)
|
|
||||||
{
|
|
||||||
$status = "Deleting file: $($itemToDelete)"
|
|
||||||
|
|
||||||
takeown /a /f "$($itemToDelete)"
|
|
||||||
icacls "$($itemToDelete)" /q /c /t /reset
|
|
||||||
icacls "$($itemToDelete)" /setowner "*S-1-5-32-544"
|
|
||||||
icacls "$($itemToDelete)" /grant "*S-1-5-32-544:(OI)(CI)F" /t /c /q
|
|
||||||
Remove-Item -Force "$($itemToDelete)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Write-Progress -Activity "Removing Items" -Status "Ready" -Completed
|
|
||||||
}
|
|
||||||
|
|
||||||
function New-Unattend {
|
|
||||||
|
|
||||||
# later if we wont to remove even more bloat EU requires MS to remove everything from English(world)
|
|
||||||
# Below is an example how to do it we probably should create a drop down with common locals
|
|
||||||
# <settings pass="specialize">
|
|
||||||
# <!-- Specify English (World) locale -->
|
|
||||||
# <component name="Microsoft-Windows-International-Core" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
# <SetupUILanguage>
|
|
||||||
# <UILanguage>en-US</UILanguage>
|
|
||||||
# </SetupUILanguage>
|
|
||||||
# <InputLocale>en-US</InputLocale>
|
|
||||||
# <SystemLocale>en-US</SystemLocale>
|
|
||||||
# <UILanguage>en-US</UILanguage>
|
|
||||||
# <UserLocale>en-US</UserLocale>
|
|
||||||
# </component>
|
|
||||||
# </settings>
|
|
||||||
|
|
||||||
# <settings pass="oobeSystem">
|
|
||||||
# <!-- Specify English (World) locale -->
|
|
||||||
# <component name="Microsoft-Windows-International-Core" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
# <InputLocale>en-US</InputLocale>
|
|
||||||
# <SystemLocale>en-US</SystemLocale>
|
|
||||||
# <UILanguage>en-US</UILanguage>
|
|
||||||
# <UserLocale>en-US</UserLocale>
|
|
||||||
# </component>
|
|
||||||
# </settings>
|
|
||||||
# using here string to embedd unattend
|
|
||||||
# <RunSynchronousCommand wcm:action="add">
|
|
||||||
# <Order>1</Order>
|
|
||||||
# <Path>net user administrator /active:yes</Path>
|
|
||||||
# </RunSynchronousCommand>
|
|
||||||
|
|
||||||
# this section doesn't work in win10/????
|
|
||||||
# <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>
|
|
||||||
|
|
||||||
$unattend = @'
|
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<unattend xmlns="urn:schemas-microsoft-com:unattend"
|
|
||||||
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<#REPLACEME#>
|
|
||||||
<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">
|
|
||||||
<RunSynchronous>
|
|
||||||
<RunSynchronousCommand wcm:action="add">
|
|
||||||
<Order>1</Order>
|
|
||||||
<CommandLine>CMD /C echo LAU GG>C:\Windows\LogAuditUser.txt</CommandLine>
|
|
||||||
<Description>StartMenu</Description>
|
|
||||||
</RunSynchronousCommand>
|
|
||||||
</RunSynchronous>
|
|
||||||
</component>
|
|
||||||
</settings>
|
|
||||||
<settings pass="oobeSystem">
|
|
||||||
<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">
|
|
||||||
<OOBE>
|
|
||||||
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
|
|
||||||
<SkipUserOOBE>false</SkipUserOOBE>
|
|
||||||
<SkipMachineOOBE>false</SkipMachineOOBE>
|
|
||||||
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
|
|
||||||
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
|
||||||
<HideEULAPage>true</HideEULAPage>
|
|
||||||
<ProtectYourPC>3</ProtectYourPC>
|
|
||||||
</OOBE>
|
|
||||||
<FirstLogonCommands>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>1</Order>
|
|
||||||
<CommandLine>cmd.exe /c echo 23>c:\windows\csup.txt</CommandLine>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>2</Order>
|
|
||||||
<CommandLine>CMD /C echo GG>C:\Windows\LogOobeSystem.txt</CommandLine>
|
|
||||||
</SynchronousCommand>
|
|
||||||
<SynchronousCommand wcm:action="add">
|
|
||||||
<Order>3</Order>
|
|
||||||
<CommandLine>powershell -ExecutionPolicy Bypass -File c:\windows\FirstStartup.ps1</CommandLine>
|
|
||||||
</SynchronousCommand>
|
|
||||||
</FirstLogonCommands>
|
|
||||||
</component>
|
|
||||||
</settings>
|
|
||||||
</unattend>
|
|
||||||
'@
|
|
||||||
$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 {
|
|
||||||
|
|
||||||
# using here string to embedd firstrun
|
|
||||||
$checkInstall = @'
|
|
||||||
@echo off
|
|
||||||
if exist "C:\windows\cpu.txt" (
|
|
||||||
echo C:\windows\cpu.txt exists
|
|
||||||
) else (
|
|
||||||
echo C:\windows\cpu.txt does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\windows\SerialNumber.txt" (
|
|
||||||
echo C:\windows\SerialNumber.txt exists
|
|
||||||
) else (
|
|
||||||
echo C:\windows\SerialNumber.txt does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\unattend.xml" (
|
|
||||||
echo C:\unattend.xml exists
|
|
||||||
) else (
|
|
||||||
echo C:\unattend.xml does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\Setup\Scripts\SetupComplete.cmd" (
|
|
||||||
echo C:\Windows\Setup\Scripts\SetupComplete.cmd exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\Setup\Scripts\SetupComplete.cmd does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\Panther\unattend.xml" (
|
|
||||||
echo C:\Windows\Panther\unattend.xml exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\Panther\unattend.xml does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\System32\Sysprep\unattend.xml" (
|
|
||||||
echo C:\Windows\System32\Sysprep\unattend.xml exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\System32\Sysprep\unattend.xml does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\FirstStartup.ps1" (
|
|
||||||
echo C:\Windows\FirstStartup.ps1 exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\FirstStartup.ps1 does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\winutil.ps1" (
|
|
||||||
echo C:\Windows\winutil.ps1 exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\winutil.ps1 does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\LogSpecialize.txt" (
|
|
||||||
echo C:\Windows\LogSpecialize.txt exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\LogSpecialize.txt does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\LogAuditUser.txt" (
|
|
||||||
echo C:\Windows\LogAuditUser.txt exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\LogAuditUser.txt does not exist
|
|
||||||
)
|
|
||||||
if exist "C:\Windows\LogOobeSystem.txt" (
|
|
||||||
echo C:\Windows\LogOobeSystem.txt exists
|
|
||||||
) else (
|
|
||||||
echo C:\Windows\LogOobeSystem.txt does not exist
|
|
||||||
)
|
|
||||||
if exist "c:\windows\csup.txt" (
|
|
||||||
echo c:\windows\csup.txt exists
|
|
||||||
) else (
|
|
||||||
echo c:\windows\csup.txt does not exist
|
|
||||||
)
|
|
||||||
if exist "c:\windows\LogFirstRun.txt" (
|
|
||||||
echo c:\windows\LogFirstRun.txt exists
|
|
||||||
) else (
|
|
||||||
echo c:\windows\LogFirstRun.txt does not exist
|
|
||||||
)
|
|
||||||
'@
|
|
||||||
$checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii
|
|
||||||
}
|
|
||||||
|
|
||||||
function New-FirstRun {
|
|
||||||
|
|
||||||
# using here string to embedd firstrun
|
|
||||||
$firstRun = @'
|
|
||||||
# Set the global error action preference to continue
|
|
||||||
$ErrorActionPreference = "Continue"
|
|
||||||
function Remove-RegistryValue
|
|
||||||
{
|
|
||||||
param (
|
|
||||||
[Parameter(Mandatory = $true)]
|
|
||||||
[string]$RegistryPath,
|
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
|
||||||
[string]$ValueName
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if the registry path exists
|
|
||||||
if (Test-Path -Path $RegistryPath)
|
|
||||||
{
|
|
||||||
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
# Check if the registry value exists
|
|
||||||
if ($registryValue)
|
|
||||||
{
|
|
||||||
# Remove the registry value
|
|
||||||
Remove-ItemProperty -Path $RegistryPath -Name $ValueName -Force
|
|
||||||
Write-Host "Registry value '$ValueName' removed from '$RegistryPath'."
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Write-Host "Registry value '$ValueName' not found in '$RegistryPath'."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Write-Host "Registry path '$RegistryPath' not found."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function Stop-UnnecessaryServices
|
|
||||||
{
|
|
||||||
$servicesToExclude = @(
|
|
||||||
"AudioSrv",
|
|
||||||
"AudioEndpointBuilder",
|
|
||||||
"BFE",
|
|
||||||
"BITS",
|
|
||||||
"BrokerInfrastructure",
|
|
||||||
"CDPSvc",
|
|
||||||
"CDPUserSvc_dc2a4",
|
|
||||||
"CoreMessagingRegistrar",
|
|
||||||
"CryptSvc",
|
|
||||||
"DPS",
|
|
||||||
"DcomLaunch",
|
|
||||||
"Dhcp",
|
|
||||||
"DispBrokerDesktopSvc",
|
|
||||||
"Dnscache",
|
|
||||||
"DoSvc",
|
|
||||||
"DusmSvc",
|
|
||||||
"EventLog",
|
|
||||||
"EventSystem",
|
|
||||||
"FontCache",
|
|
||||||
"LSM",
|
|
||||||
"LanmanServer",
|
|
||||||
"LanmanWorkstation",
|
|
||||||
"MapsBroker",
|
|
||||||
"MpsSvc",
|
|
||||||
"OneSyncSvc_dc2a4",
|
|
||||||
"Power",
|
|
||||||
"ProfSvc",
|
|
||||||
"RpcEptMapper",
|
|
||||||
"RpcSs",
|
|
||||||
"SCardSvr",
|
|
||||||
"SENS",
|
|
||||||
"SamSs",
|
|
||||||
"Schedule",
|
|
||||||
"SgrmBroker",
|
|
||||||
"ShellHWDetection",
|
|
||||||
"Spooler",
|
|
||||||
"SysMain",
|
|
||||||
"SystemEventsBroker",
|
|
||||||
"TextInputManagementService",
|
|
||||||
"Themes",
|
|
||||||
"TrkWks",
|
|
||||||
"UserManager",
|
|
||||||
"VGAuthService",
|
|
||||||
"VMTools",
|
|
||||||
"WSearch",
|
|
||||||
"Wcmsvc",
|
|
||||||
"WinDefend",
|
|
||||||
"Winmgmt",
|
|
||||||
"WlanSvc",
|
|
||||||
"WpnService",
|
|
||||||
"WpnUserService_dc2a4",
|
|
||||||
"cbdhsvc_dc2a4",
|
|
||||||
"edgeupdate",
|
|
||||||
"gpsvc",
|
|
||||||
"iphlpsvc",
|
|
||||||
"mpssvc",
|
|
||||||
"nsi",
|
|
||||||
"sppsvc",
|
|
||||||
"tiledatamodelsvc",
|
|
||||||
"vm3dservice",
|
|
||||||
"webthreatdefusersvc_dc2a4",
|
|
||||||
"wscsvc"
|
|
||||||
)
|
|
||||||
|
|
||||||
$runningServices = Get-Service | Where-Object { $servicesToExclude -notcontains $_.Name }
|
|
||||||
foreach($service in $runningServices)
|
|
||||||
{
|
|
||||||
Stop-Service -Name $service.Name -PassThru
|
|
||||||
Set-Service $service.Name -StartupType Manual
|
|
||||||
"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
|
|
||||||
|
|
||||||
$Theme = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
|
|
||||||
Set-ItemProperty -Path $Theme -Name AppsUseLightTheme -Value 1
|
|
||||||
Set-ItemProperty -Path $Theme -Name SystemUsesLightTheme -Value 1
|
|
||||||
|
|
||||||
# figure this out later how to set updates to security only
|
|
||||||
#Import-Module -Name PSWindowsUpdate;
|
|
||||||
#Stop-Service -Name wuauserv
|
|
||||||
#Set-WUSettings -MicrosoftUpdateEnabled -AutoUpdateOption 'Never'
|
|
||||||
#Start-Service -Name wuauserv
|
|
||||||
|
|
||||||
Stop-UnnecessaryServices
|
|
||||||
|
|
||||||
$taskbarPath = "$env:AppData\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar"
|
|
||||||
# Delete all files on the Taskbar
|
|
||||||
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 "FavoritesChanges"
|
|
||||||
Remove-RegistryValue -RegistryPath "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband" -ValueName "Favorites"
|
|
||||||
|
|
||||||
# Stop-Process -Name explorer -Force
|
|
||||||
|
|
||||||
$process = Get-Process -Name "explorer"
|
|
||||||
Stop-Process -InputObject $process
|
|
||||||
# Wait for the process to exit
|
|
||||||
Wait-Process -InputObject $process
|
|
||||||
Start-Sleep -Seconds 3
|
|
||||||
|
|
||||||
# Delete Edge Icon from the desktop
|
|
||||||
$edgeShortcutFiles = Get-ChildItem -Path $desktopPath -Filter "*Edge*.lnk"
|
|
||||||
# Check if Edge shortcuts exist on the desktop
|
|
||||||
if ($edgeShortcutFiles)
|
|
||||||
{
|
|
||||||
foreach ($shortcutFile in $edgeShortcutFiles)
|
|
||||||
{
|
|
||||||
# Remove each Edge shortcut
|
|
||||||
Remove-Item -Path $shortcutFile.FullName -Force
|
|
||||||
Write-Host "Edge shortcut '$($shortcutFile.Name)' removed from the desktop."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Remove-Item -Path "$env:USERPROFILE\Desktop\*.lnk"
|
|
||||||
Remove-Item -Path "C:\Users\Default\Desktop\*.lnk"
|
|
||||||
|
|
||||||
# ************************************************
|
|
||||||
# Create WinUtil shortcut on the desktop
|
|
||||||
#
|
|
||||||
$desktopPath = "$($env:USERPROFILE)\Desktop"
|
|
||||||
# Specify the target PowerShell command
|
|
||||||
$command = "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command 'irm https://christitus.com/win | iex'"
|
|
||||||
# Specify the path for the shortcut
|
|
||||||
$shortcutPath = Join-Path $desktopPath 'winutil.lnk'
|
|
||||||
# Create a shell object
|
|
||||||
$shell = New-Object -ComObject WScript.Shell
|
|
||||||
|
|
||||||
# Create a shortcut object
|
|
||||||
$shortcut = $shell.CreateShortcut($shortcutPath)
|
|
||||||
|
|
||||||
if (Test-Path -Path "c:\Windows\cttlogo.png")
|
|
||||||
{
|
|
||||||
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set properties of the shortcut
|
|
||||||
$shortcut.TargetPath = "powershell.exe"
|
|
||||||
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
|
|
||||||
# Save the shortcut
|
|
||||||
$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"
|
|
||||||
#
|
|
||||||
# Done create WinUtil shortcut on the desktop
|
|
||||||
# ************************************************
|
|
||||||
|
|
||||||
Start-Process explorer
|
|
||||||
|
|
||||||
'@
|
|
||||||
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
|
|
||||||
}
|
|
199
functions/private/Invoke-WinUtilAssets.ps1
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
function Invoke-WinUtilAssets {
|
||||||
|
param (
|
||||||
|
$type,
|
||||||
|
$Size,
|
||||||
|
[switch]$render
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the Viewbox and set its size
|
||||||
|
$LogoViewbox = New-Object Windows.Controls.Viewbox
|
||||||
|
$LogoViewbox.Width = $Size
|
||||||
|
$LogoViewbox.Height = $Size
|
||||||
|
|
||||||
|
# Create a Canvas to hold the paths
|
||||||
|
$canvas = New-Object Windows.Controls.Canvas
|
||||||
|
$canvas.Width = 100
|
||||||
|
$canvas.Height = 100
|
||||||
|
|
||||||
|
# Define a scale factor for the content inside the Canvas
|
||||||
|
$scaleFactor = $Size / 100
|
||||||
|
|
||||||
|
# Apply a scale transform to the Canvas content
|
||||||
|
$scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor)
|
||||||
|
$canvas.LayoutTransform = $scaleTransform
|
||||||
|
|
||||||
|
switch ($type) {
|
||||||
|
'logo' {
|
||||||
|
$LogoPathData1 = @"
|
||||||
|
M 18.00,14.00
|
||||||
|
C 18.00,14.00 45.00,27.74 45.00,27.74
|
||||||
|
45.00,27.74 57.40,34.63 57.40,34.63
|
||||||
|
57.40,34.63 59.00,43.00 59.00,43.00
|
||||||
|
59.00,43.00 59.00,83.00 59.00,83.00
|
||||||
|
55.35,81.66 46.99,77.79 44.72,74.79
|
||||||
|
41.17,70.10 42.01,59.80 42.00,54.00
|
||||||
|
42.00,51.62 42.20,48.29 40.98,46.21
|
||||||
|
38.34,41.74 25.78,38.60 21.28,33.79
|
||||||
|
16.81,29.02 18.00,20.20 18.00,14.00 Z
|
||||||
|
"@
|
||||||
|
$LogoPath1 = New-Object Windows.Shapes.Path
|
||||||
|
$LogoPath1.Data = [Windows.Media.Geometry]::Parse($LogoPathData1)
|
||||||
|
$LogoPath1.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff")
|
||||||
|
|
||||||
|
$LogoPathData2 = @"
|
||||||
|
M 107.00,14.00
|
||||||
|
C 109.01,19.06 108.93,30.37 104.66,34.21
|
||||||
|
100.47,37.98 86.38,43.10 84.60,47.21
|
||||||
|
83.94,48.74 84.01,51.32 84.00,53.00
|
||||||
|
83.97,57.04 84.46,68.90 83.26,72.00
|
||||||
|
81.06,77.70 72.54,81.42 67.00,83.00
|
||||||
|
67.00,83.00 67.00,43.00 67.00,43.00
|
||||||
|
67.00,43.00 67.99,35.63 67.99,35.63
|
||||||
|
67.99,35.63 80.00,28.26 80.00,28.26
|
||||||
|
80.00,28.26 107.00,14.00 107.00,14.00 Z
|
||||||
|
"@
|
||||||
|
$LogoPath2 = New-Object Windows.Shapes.Path
|
||||||
|
$LogoPath2.Data = [Windows.Media.Geometry]::Parse($LogoPathData2)
|
||||||
|
$LogoPath2.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff")
|
||||||
|
|
||||||
|
$LogoPathData3 = @"
|
||||||
|
M 19.00,46.00
|
||||||
|
C 21.36,47.14 28.67,50.71 30.01,52.63
|
||||||
|
31.17,54.30 30.99,57.04 31.00,59.00
|
||||||
|
31.04,65.41 30.35,72.16 33.56,78.00
|
||||||
|
38.19,86.45 46.10,89.04 54.00,93.31
|
||||||
|
56.55,94.69 60.10,97.20 63.00,97.22
|
||||||
|
65.50,97.24 68.77,95.36 71.00,94.25
|
||||||
|
76.42,91.55 84.51,87.78 88.82,83.68
|
||||||
|
94.56,78.20 95.96,70.59 96.00,63.00
|
||||||
|
96.01,60.24 95.59,54.63 97.02,52.39
|
||||||
|
98.80,49.60 103.95,47.87 107.00,47.00
|
||||||
|
107.00,47.00 107.00,67.00 107.00,67.00
|
||||||
|
106.90,87.69 96.10,93.85 80.00,103.00
|
||||||
|
76.51,104.98 66.66,110.67 63.00,110.52
|
||||||
|
60.33,110.41 55.55,107.53 53.00,106.25
|
||||||
|
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
|
||||||
|
"@
|
||||||
|
$LogoPath3 = New-Object Windows.Shapes.Path
|
||||||
|
$LogoPath3.Data = [Windows.Media.Geometry]::Parse($LogoPathData3)
|
||||||
|
$LogoPath3.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#a3a4a6")
|
||||||
|
|
||||||
|
$canvas.Children.Add($LogoPath1) | Out-Null
|
||||||
|
$canvas.Children.Add($LogoPath2) | Out-Null
|
||||||
|
$canvas.Children.Add($LogoPath3) | Out-Null
|
||||||
|
}
|
||||||
|
'checkmark' {
|
||||||
|
$canvas.Width = 512
|
||||||
|
$canvas.Height = 512
|
||||||
|
|
||||||
|
$scaleFactor = $Size / 2.54
|
||||||
|
$scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor)
|
||||||
|
$canvas.LayoutTransform = $scaleTransform
|
||||||
|
|
||||||
|
# Define the circle path
|
||||||
|
$circlePathData = "M 1.27,0 A 1.27,1.27 0 1,0 1.27,2.54 A 1.27,1.27 0 1,0 1.27,0"
|
||||||
|
$circlePath = New-Object Windows.Shapes.Path
|
||||||
|
$circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData)
|
||||||
|
$circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#39ba00")
|
||||||
|
|
||||||
|
# Define the checkmark path
|
||||||
|
$checkmarkPathData = "M 0.873 1.89 L 0.41 1.391 A 0.17 0.17 0 0 1 0.418 1.151 A 0.17 0.17 0 0 1 0.658 1.16 L 1.016 1.543 L 1.583 1.013 A 0.17 0.17 0 0 1 1.599 1 L 1.865 0.751 A 0.17 0.17 0 0 1 2.105 0.759 A 0.17 0.17 0 0 1 2.097 0.999 L 1.282 1.759 L 0.999 2.022 L 0.874 1.888 Z"
|
||||||
|
$checkmarkPath = New-Object Windows.Shapes.Path
|
||||||
|
$checkmarkPath.Data = [Windows.Media.Geometry]::Parse($checkmarkPathData)
|
||||||
|
$checkmarkPath.Fill = [Windows.Media.Brushes]::White
|
||||||
|
|
||||||
|
# Add the paths to the Canvas
|
||||||
|
$canvas.Children.Add($circlePath) | Out-Null
|
||||||
|
$canvas.Children.Add($checkmarkPath) | Out-Null
|
||||||
|
}
|
||||||
|
'warning' {
|
||||||
|
$canvas.Width = 512
|
||||||
|
$canvas.Height = 512
|
||||||
|
|
||||||
|
# Define a scale factor for the content inside the Canvas
|
||||||
|
$scaleFactor = $Size / 512 # Adjust scaling based on the canvas size
|
||||||
|
$scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor)
|
||||||
|
$canvas.LayoutTransform = $scaleTransform
|
||||||
|
|
||||||
|
# Define the circle path
|
||||||
|
$circlePathData = "M 256,0 A 256,256 0 1,0 256,512 A 256,256 0 1,0 256,0"
|
||||||
|
$circlePath = New-Object Windows.Shapes.Path
|
||||||
|
$circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData)
|
||||||
|
$circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#f41b43")
|
||||||
|
|
||||||
|
# Define the exclamation mark path
|
||||||
|
$exclamationPathData = "M 256 307.2 A 35.89 35.89 0 0 1 220.14 272.74 L 215.41 153.3 A 35.89 35.89 0 0 1 251.27 116 H 260.73 A 35.89 35.89 0 0 1 296.59 153.3 L 291.86 272.74 A 35.89 35.89 0 0 1 256 307.2 Z"
|
||||||
|
$exclamationPath = New-Object Windows.Shapes.Path
|
||||||
|
$exclamationPath.Data = [Windows.Media.Geometry]::Parse($exclamationPathData)
|
||||||
|
$exclamationPath.Fill = [Windows.Media.Brushes]::White
|
||||||
|
|
||||||
|
# Get the bounds of the exclamation mark path
|
||||||
|
$exclamationBounds = $exclamationPath.Data.Bounds
|
||||||
|
|
||||||
|
# Calculate the center position for the exclamation mark path
|
||||||
|
$exclamationCenterX = ($canvas.Width - $exclamationBounds.Width) / 2 - $exclamationBounds.X
|
||||||
|
$exclamationPath.SetValue([Windows.Controls.Canvas]::LeftProperty, $exclamationCenterX)
|
||||||
|
|
||||||
|
# Define the rounded rectangle at the bottom (dot of exclamation mark)
|
||||||
|
$roundedRectangle = New-Object Windows.Shapes.Rectangle
|
||||||
|
$roundedRectangle.Width = 80
|
||||||
|
$roundedRectangle.Height = 80
|
||||||
|
$roundedRectangle.RadiusX = 30
|
||||||
|
$roundedRectangle.RadiusY = 30
|
||||||
|
$roundedRectangle.Fill = [Windows.Media.Brushes]::White
|
||||||
|
|
||||||
|
# Calculate the center position for the rounded rectangle
|
||||||
|
$centerX = ($canvas.Width - $roundedRectangle.Width) / 2
|
||||||
|
$roundedRectangle.SetValue([Windows.Controls.Canvas]::LeftProperty, $centerX)
|
||||||
|
$roundedRectangle.SetValue([Windows.Controls.Canvas]::TopProperty, 324.34)
|
||||||
|
|
||||||
|
# Add the paths to the Canvas
|
||||||
|
$canvas.Children.Add($circlePath) | Out-Null
|
||||||
|
$canvas.Children.Add($exclamationPath) | Out-Null
|
||||||
|
$canvas.Children.Add($roundedRectangle) | Out-Null
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
Write-Host "Invalid type: $type"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the Canvas to the Viewbox
|
||||||
|
$LogoViewbox.Child = $canvas
|
||||||
|
|
||||||
|
if ($render) {
|
||||||
|
# Measure and arrange the canvas to ensure proper rendering
|
||||||
|
$canvas.Measure([Windows.Size]::new($canvas.Width, $canvas.Height))
|
||||||
|
$canvas.Arrange([Windows.Rect]::new(0, 0, $canvas.Width, $canvas.Height))
|
||||||
|
$canvas.UpdateLayout()
|
||||||
|
|
||||||
|
# Initialize RenderTargetBitmap correctly with dimensions
|
||||||
|
$renderTargetBitmap = New-Object Windows.Media.Imaging.RenderTargetBitmap($canvas.Width, $canvas.Height, 96, 96, [Windows.Media.PixelFormats]::Pbgra32)
|
||||||
|
|
||||||
|
# Render the canvas to the bitmap
|
||||||
|
$renderTargetBitmap.Render($canvas)
|
||||||
|
|
||||||
|
# Create a BitmapFrame from the RenderTargetBitmap
|
||||||
|
$bitmapFrame = [Windows.Media.Imaging.BitmapFrame]::Create($renderTargetBitmap)
|
||||||
|
|
||||||
|
# Create a PngBitmapEncoder and add the frame
|
||||||
|
$bitmapEncoder = [Windows.Media.Imaging.PngBitmapEncoder]::new()
|
||||||
|
$bitmapEncoder.Frames.Add($bitmapFrame)
|
||||||
|
|
||||||
|
# Save to a memory stream
|
||||||
|
$imageStream = New-Object System.IO.MemoryStream
|
||||||
|
$bitmapEncoder.Save($imageStream)
|
||||||
|
$imageStream.Position = 0
|
||||||
|
|
||||||
|
# Load the stream into a BitmapImage
|
||||||
|
$bitmapImage = [Windows.Media.Imaging.BitmapImage]::new()
|
||||||
|
$bitmapImage.BeginInit()
|
||||||
|
$bitmapImage.StreamSource = $imageStream
|
||||||
|
$bitmapImage.CacheOption = [Windows.Media.Imaging.BitmapCacheOption]::OnLoad
|
||||||
|
$bitmapImage.EndInit()
|
||||||
|
|
||||||
|
return $bitmapImage
|
||||||
|
} else {
|
||||||
|
return $LogoViewbox
|
||||||
|
}
|
||||||
|
}
|
@ -1,34 +0,0 @@
|
|||||||
function Invoke-WinUtilBingSearch {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Disables/Enables Bing Search
|
|
||||||
|
|
||||||
.PARAMETER Enabled
|
|
||||||
Indicates whether to enable or disable Bing Search
|
|
||||||
|
|
||||||
#>
|
|
||||||
Param($Enabled)
|
|
||||||
Try{
|
|
||||||
if ($Enabled -eq $false){
|
|
||||||
Write-Host "Enabling Bing Search"
|
|
||||||
$value = 1
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Host "Disabling Bing Search"
|
|
||||||
$value = 0
|
|
||||||
}
|
|
||||||
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search"
|
|
||||||
Set-ItemProperty -Path $Path -Name BingSearchEnabled -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,6 +13,16 @@ Function Invoke-WinUtilCurrentSystem {
|
|||||||
param(
|
param(
|
||||||
$CheckBox
|
$CheckBox
|
||||||
)
|
)
|
||||||
|
if ($CheckBox -eq "choco") {
|
||||||
|
$apps = (choco list | Select-String -Pattern "^\S+").Matches.Value
|
||||||
|
$filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"}
|
||||||
|
$sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object {
|
||||||
|
$dependencies = @($sync.configs.applications.$($psitem.Key).choco -split ";")
|
||||||
|
if ($dependencies -in $apps) {
|
||||||
|
Write-Output $psitem.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($checkbox -eq "winget") {
|
if ($checkbox -eq "winget") {
|
||||||
|
|
||||||
@ -33,7 +43,7 @@ Function Invoke-WinUtilCurrentSystem {
|
|||||||
|
|
||||||
if($CheckBox -eq "tweaks") {
|
if($CheckBox -eq "tweaks") {
|
||||||
|
|
||||||
if(!(Test-Path 'HKU:\')){New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS}
|
if(!(Test-Path 'HKU:\')) {$null = (New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS)}
|
||||||
$ScheduledTasks = Get-ScheduledTask
|
$ScheduledTasks = Get-ScheduledTask
|
||||||
|
|
||||||
$sync.configs.tweaks | Get-Member -MemberType NoteProperty | ForEach-Object {
|
$sync.configs.tweaks | Get-Member -MemberType NoteProperty | ForEach-Object {
|
||||||
@ -57,8 +67,7 @@ Function Invoke-WinUtilCurrentSystem {
|
|||||||
if ($expectedValue -notlike $actualValue) {
|
if ($expectedValue -notlike $actualValue) {
|
||||||
$values += $False
|
$values += $False
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$values += $False
|
$values += $False
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,4 +108,3 @@ Function Invoke-WinUtilCurrentSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
Function Invoke-WinUtilDarkMode {
|
|
||||||
<#
|
|
||||||
|
|
||||||
.SYNOPSIS
|
|
||||||
Enables/Disables Dark Mode
|
|
||||||
|
|
||||||
.PARAMETER DarkMoveEnabled
|
|
||||||
Indicates the current dark mode state
|
|
||||||
|
|
||||||
#>
|
|
||||||
Param($DarkMoveEnabled)
|
|
||||||
Try{
|
|
||||||
if ($DarkMoveEnabled -eq $false){
|
|
||||||
Write-Host "Enabling Dark Mode"
|
|
||||||
$DarkMoveValue = 0
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Host "Disabling Dark Mode"
|
|
||||||
$DarkMoveValue = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
|
|
||||||
Set-ItemProperty -Path $Path -Name AppsUseLightTheme -Value $DarkMoveValue
|
|
||||||
Set-ItemProperty -Path $Path -Name SystemUsesLightTheme -Value $DarkMoveValue
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
43
functions/private/Invoke-WinUtilExplorerUpdate.ps1
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
function Invoke-WinUtilExplorerUpdate {
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Refreshes the Windows Explorer
|
||||||
|
#>
|
||||||
|
|
||||||
|
param (
|
||||||
|
[string]$action = "refresh"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($action -eq "refresh") {
|
||||||
|
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
|
||||||
|
# Send the WM_SETTINGCHANGE message to all windows
|
||||||
|
Add-Type -TypeDefinition @"
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
public class Win32 {
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||||
|
public static extern IntPtr SendMessageTimeout(
|
||||||
|
IntPtr hWnd,
|
||||||
|
uint Msg,
|
||||||
|
IntPtr wParam,
|
||||||
|
string lParam,
|
||||||
|
uint fuFlags,
|
||||||
|
uint uTimeout,
|
||||||
|
out IntPtr lpdwResult);
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
$HWND_BROADCAST = [IntPtr]0xffff
|
||||||
|
$WM_SETTINGCHANGE = 0x1A
|
||||||
|
$SMTO_ABORTIFHUNG = 0x2
|
||||||
|
$timeout = 100
|
||||||
|
|
||||||
|
# Send the broadcast message to all windows
|
||||||
|
[Win32]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [IntPtr]::Zero, "ImmersiveColorSet", $SMTO_ABORTIFHUNG, $timeout, [ref]([IntPtr]::Zero))
|
||||||
|
}
|
||||||
|
} elseif ($action -eq "restart") {
|
||||||
|
# Restart the Windows Explorer
|
||||||
|
taskkill.exe /F /IM "explorer.exe"
|
||||||
|
Start-Process "explorer.exe"
|
||||||
|
}
|
||||||
|
}
|