Compare commits

...

138 Commits

Author SHA1 Message Date
ChrisTitusTech
18de3d59ee Deploying to main from @ ChrisTitusTech/winutil@59d968e7c4 🚀 2025-06-14 15:32:56 +00:00
ChrisTitusTech
59d968e7c4 Deploying to main from @ ChrisTitusTech/winutil@afe85ad7f0 🚀 2025-06-06 15:33:48 +00:00
ChrisTitusTech
afe85ad7f0 Deploying to main from @ ChrisTitusTech/winutil@efb9e5bde6 🚀 2025-06-03 15:35:28 +00:00
Martin Wiethan
efb9e5bde6
correct uninstall variable (#3384) 2025-06-01 10:40:37 -05:00
ChrisTitusTech
56eba47a6c Deploying to main from @ ChrisTitusTech/winutil@e57cde423c 🚀 2025-05-30 15:34:17 +00:00
ChrisTitusTech
e57cde423c Deploying to main from @ ChrisTitusTech/winutil@de9b643129 🚀 2025-05-27 15:34:49 +00:00
Chris Titus
de9b643129 add signing shortcut 2025-05-23 11:26:48 -05:00
Chris Titus
e430e0aad0 revert single form window 2025-05-23 11:22:44 -05:00
Chris Titus
61fd4d2f91 update authors 2025-05-23 11:20:23 -05:00
Chris Titus
b72cd83189 Remove Old Code-Signing 2025-05-23 11:15:18 -05:00
Martin Wiethan
290292ec94
Refactor process termination for explorer.exe in tweaks.json (#3375) 2025-05-23 11:04:26 -05:00
Martin Wiethan
d22865d79b
Fix App references (#3374)
* Update winget reference

* Remove Samsung Magician entry from applications.json as it dosn't exist in winget anymore
2025-05-23 11:03:00 -05:00
Nilesh
5c5b999a09
Change WindowStyle to SingleBorderWindow (#3373) 2025-05-23 10:59:54 -05:00
Martin Wiethan
0c0e6bd243
Implement search bar debounce functionality to improve UI responsiveness (#3371)
* Implement search bar debounce functionality to improve UI responsiveness

* Enhance app search functionality to include description matching
2025-05-23 10:56:24 -05:00
Alice Lia Stapleton
dd06489d63
Windows Spotlight warning (#3354)
Adds a warning for the problem encountered in issue 3203
2025-05-23 10:53:33 -05:00
Martin Wiethan
41df9d3d88
Add Right-Click Action on App Install Page (#3367)
* Add right click context menu for app entries with install, uninstall, and info options

* Add hand cursor on mouse over for button in inputXML.xaml
2025-05-23 10:52:57 -05:00
Raphael Machado
63d56bcac9
remove spotube (#3372)
🚨 Spotube is banned from using "Spotify™ API" 🚨

The developer of Spotube has received a cease and desist letter from Spotify USA Inc. and Spotify AB, asserting a legal threat concerning the distribution and development of any application that utilizes Spotify’s data API in conjunction with content from YouTube® to facilitate ad-free playback of music tracks. The letter contends that this specific use of the Spotify™ APIs contravenes the Spotify™ Agreements and may also infringe upon the rights of music rights holders.

Consequently, as the official maintainer of Spotube, I will immediately cease all forms of official distribution and development of Spotube that continue to employ the aforementioned 'Spotify™ APIs'

Their exact reasoning: (any) "uses of Spotify’s data API in connection with content from YouTube to provide ad-free playback of music tracks. The use of the Spotify APIs in this manner violates the Spotify Agreements and may also violate the rights of music rights holders."

https://spotube.krtirtho.dev/
2025-05-23 10:37:14 -05:00
Martin Wiethan
962b18e8fa
Re-Redesign of the Install Tab (#3350)
* Initial Remove Expanded View

* more cleanup

* Add word wrapping for Tooltips

* Update tooltip colors in themes and XAML styles

* Rename Properties for consistency

* More Cleanup, and simplification. Also added support for screenreaders

* Remove unused variables and shorten window naming

* Rename Invoke-WPFUIApps to Initialize-WPFUI and update function calls for consistency

* Rename Invoke-WPFUIApps.ps1 to Initialize-WPFUI.ps1

* Add TODO comments for sidebar UI generation in Initialize-WPFUI function
2025-05-12 15:45:57 -05:00
ChrisTitusTech
14e761f438 Deploying to main from @ ChrisTitusTech/winutil@3e416f5c14 🚀 2025-05-12 15:35:26 +00:00
Chris Titus
3e416f5c14 format fixes 2025-05-05 10:56:32 -05:00
ChrisTitusTech
95d28ee25d Deploying to main from @ ChrisTitusTech/winutil@50071067b7 🚀 2025-05-05 15:34:04 +00:00
CodingWonders
50071067b7
[MicroWin] April Update (#3317)
* Better formatting

A bit cleaner

* Remove unused scripts

This gets rid of file not found errors during setup

* Have a fallback method for Recall fixes

Go back to the delayed disablement procedure if we fail at modifying the manifest

* Ignore Recall disablement when disabled, and more

- If Recall is disabled, don't disable it again. This may be a waste of time
- Disable certain notification sources that I think are quite annoying, like those from Suggested or the Startup App Notification

* Hopefully? Get rid of News and Interests on Win10

Based on PR #3289, add News and Interests removal to MicroWin. Hopefully Windows 10 gets to cooperate this time, compared to last time, where it was quite stubborn.

*This means that people never give up trying to fight against something they don't like*

* Revert "Refactor preferChocolatey system to handle other package managers eas…" (#3323)

This reverts commit 89919494e5030f700664cfe01e9ffe3a49d48cd8.

* Fixed all the things that could possibly break

* Get rid of extra parameter

Package removal fallback fails here. Quite likely a copy from feature disablement

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2025-05-05 10:24:12 -05:00
Mr.k
3b7d707262
Update documentation links to the new website https://winutil.christitus.com/ (#3335) 2025-05-05 10:21:46 -05:00
Martin Wiethan
ea95dac426
Remove OpenOffice entry from applications.json (#3332) 2025-05-05 10:20:53 -05:00
Martin Wiethan
b4d3368680
Refactor Windows Repair (#3312)
* Refactor Invoke-WPFFixesUpdate and replace Invoke-WPFPanelDISM with Invoke-WPFSystemRepair. Streamline Windows Repair

* Refactor Invoke-WPFSystemRepair to improve function naming, scalablility and fix on english os

* Remove debug switches to minimize clutter and shorten the code

* Replace Write-Verbose with Write-Debug
2025-05-05 10:20:20 -05:00
Martin Wiethan
0b5c44cbcf
Optimize Preprocessor by Implementing File Hashing for Modified Files Detection (#3310)
* Modify preprocessor, to only process modified files

* Refactor Invoke-Preprocessing to remove ThrowExceptionOnEmptyFilesList parameter and switch to MD5 hashing

* Remove SkipExcludedFilesValidation parameter and update validation logic for ExcludedFiles
2025-05-05 10:18:29 -05:00
Nilesh
b8b16be24b
Fix: Searchbar not working (#3270) (#3306) 2025-05-05 10:15:51 -05:00
Martin Wiethan
14943e3c55
Refactor Hotkey Handling (#3299)
* Refactor Hotkey Handling to improve readability and fix a bug

* Remove unnecessary $_.Handled Properties
2025-05-05 10:12:57 -05:00
Chris Titus
91365d50b5 quick format update 2025-05-05 10:12:00 -05:00
Martin Wiethan
82b6c268b0
Refactor Startup Ascii Art (#3298)
Co-authored-by: Chris Titus <contact@christitus.com>
2025-05-05 10:07:51 -05:00
Martin Wiethan
d8c007d2db
Remove the need for inline C# to get the window dimensions (#3297) 2025-05-05 10:06:45 -05:00
CodingWonders
48f1c71584
[Tweaks] Remove trailing commas at the end (#3326) 2025-04-16 10:16:27 -05:00
Martin Wiethan
f770642a6a
Fix Gimp Winget Package (#3311) 2025-04-16 10:13:05 -05:00
Chris Titus
963c0a17aa Tidy up preference file changes 2025-04-16 08:56:22 -05:00
Martin Wiethan
20769f66a1
Switch default mode to compact view (#3327) 2025-04-16 08:40:43 -05:00
Chris Titus Tech
86459b7e24 fix alpha in apps 2025-04-14 14:30:09 -05:00
KamaleiZestri
89919494e5
Refactor preferChocolatey system to handle other package managers easier (#3296)
* Easier to add more package managers changes

* style fixes
2025-04-14 13:33:16 -05:00
Chris Titus Tech
5f6bdb2e48 Update tweaks.json 2025-04-14 13:27:02 -05:00
KamaleiZestri
f614eea435
Add "Disable news and interest" tweak (#3289) 2025-04-14 13:22:29 -05:00
Martin Wiethan
82447a1e7b
Remove Balena Etcher due to privacy concerns (#3268) 2025-04-14 13:19:19 -05:00
Chris Titus Tech
51424abfad Update preset.json 2025-04-14 13:08:55 -05:00
Chris Titus Tech
3caa3be9a3 Update tweaks.json 2025-04-14 13:08:01 -05:00
madkarma
7769a328bb
feat: disable explorer automatic folder discovery (#3262)
* feat: add tweak "Disable Explorer automatic folder discovery"

* refactor: add comments

* feat: add undo script

* refactor: add output comment

* fix: use correct registry key
2025-04-14 13:03:00 -05:00
Mr.k
425f11d787
Fix Double Click problem by using UIElement Names instead of Types (#3246)
* Fix Double Click problem by using UIElement Names instead of Types

* Use lower case 'or' to follow project's common conventions
2025-04-14 12:55:52 -05:00
Chris Titus Tech
6df94df594 Delete Invoke-WinUtilInteractiveNerdFontInstall.ps1 2025-04-14 12:49:59 -05:00
MyDrift
29e2c4d197
Action on application right click (#3243)
* implement right click logic

- right click clears selection and only selects right clicked app

* simplify logic
2025-04-14 12:40:20 -05:00
Joshua Taylor Keays
b63a17b7dd
Create Invoke-WinUtilInteractiveNerdFontInstall.ps1 (#3183)
Using this script, we could integrate inside of the XAML, a list of all current nerdfonts, and user can choose which to install.

https://raw.githubusercontent.com/jpawlowski/nerd-fonts-installer-PS/main/Invoke-NerdFontInstaller.ps1

I am not sure how to add it into xaml :  - (
2025-04-14 12:37:00 -05:00
Martin Wiethan
abe059917c
Optimize UI Performance (#3277)
* Optimize UI Load performance

* remove timers

* Formatting

* Remove unused Collapsed Checkbox Style from inputXML.xaml
2025-04-02 15:54:44 -05:00
MyDrift
698f1644c3
[Toggle] Hide Settings Homepage (#3245)
* addHideSettingsToggle

* set OriginalValue & DefaultState
2025-03-19 14:32:16 -05:00
zy
fd03f33c50
Correct description for Prism Launcher (#3256) 2025-03-19 14:07:21 -05:00
Martin Wiethan
8f9e7d1b7c
Correct the Header Font Size (#3257)
* Correct the Header Font Size naming and simplify the creation of the Selected Apps Button

* Adjust HeaderFontSize from 18 to 16 for improved readability
2025-03-19 14:05:55 -05:00
Martin Wiethan
b3dd1a1a50
Add God Mode panel to Legacy Windows Panels (#3264) 2025-03-19 14:00:30 -05:00
Martin Wiethan
4acad32a38
Add Badge to Link to the Documentation at the Top of the Readme (#3265) 2025-03-19 13:59:10 -05:00
Mr.k
0f4fca31b9
[DOCS] Remove old Announcement about not adding any new applications to the app list (#3269)
* Remove old Announcement about not adding any new applications to the app list

* Update '.gitignore' file

The generated 'site' folder, which contains the docs build result by 'mkdocs', in the same folder as 'mkdocs.yml' (i.e. under '.github' folder), so I've temporarily excluded with '.gitignore' file until we've fully migrated the docs site into another repo.
2025-03-19 13:56:00 -05:00
ChrisTitusTech
36c984b66c Deploying to main from @ ChrisTitusTech/winutil@d215d0fc2c 🚀 2025-03-19 15:33:49 +00:00
ChrisTitusTech
d215d0fc2c Deploying to main from @ ChrisTitusTech/winutil@52de4690ab 🚀 2025-03-07 15:32:54 +00:00
Emil Wójcik
52de4690ab
Update start.ps1 (#3223)
- use join method to parse $argList
- use $PSCommandPath instead of $MyInvocation.MyCommand.Path
- use ScriptBlock method to create request for latest winutil.ps1 with join $argList 
- condition for $processCmd because in case when wt.exe is not available, there was double/redundant declaration of shell which lead to code mishmash (incorrect interpretation of quotes from Start-Process ArgumentList parameters 
- changes in quotes and escape characters because command where not interpreted correctly in all possible cases of $powershellCmd and $processCmd
2025-03-05 12:15:13 -06:00
CodingWonders
ef97a8da24
[WinGet] Fix install loop (#3235)
Only this parameter was missing
2025-03-05 12:13:39 -06:00
MyDrift
18a7f17a0b
[APP addition] Zen Browser (#3231)
* add Zen to Browsers for Applications

* remove choco option since it currently needs the --pre flag
2025-03-04 14:31:28 -06:00
Chris Titus
5a8cf5deb6
Removing Github and Nuget method. Revamp of Version check to use DesktopAppInstaller (#3233) 2025-03-04 14:30:54 -06:00
Chris Titus Tech
e4b2a38372 fix a few tweak errors 2025-03-03 14:31:18 -06:00
Chris Titus
94c5d89430
fix winget for good (#3096) 2025-03-03 14:16:53 -06:00
MyDrift
8a0e0c7715
[UI/UX] Refractor Install Tab (#2859)
* initial visual implementation

- remove idiotic border logic from Invoke-WPFUIElements
- add "application" type & style
- add "radiobutton" type & style
- remove prefer choco checkbox (did not modify logic outside of xaml, so i currently get errors due to that)

* add image support via choco db

- add image support via choco db
- backup image should be taken from unigetui db
- backup backup image is some random package one rn

* add compatibility for every app

* performance improvements

- move get logo to runspace (not working rn)
- readd choco checkbox to mute errors

* add border name

* fix scrollviewer & reimplement logo logic into ui elements

* noimage fix

* add notes

* cleanup & remove nav from search effects

* add button action

* rename buttons

* add sort by options

* move scrollviewer & app buttons into uielements logic

* format logic for app action buttons

* fix app action button logic & move get & clear to sidepanel

* change category of new buttons

* add virtualisation & layouting fixes

- commented out prefer choco logic
- add virtualisation
- layouting improvements

* fix radiobuttons

* LETS GOOO  (#12)

* Add Selected Apps Label, Reshuffel the nesting of the checkbox and the label to be able to reference the name from the actual checkbox

* Add visual selection and allow click on the whole app section

* Fix Theme definition to work with theme change

* Fix Highlight on if label or icon is clicked

* change applications.json to powershell object list and refactor UI Creation logic

* Optimization and Add Collapsable Categories

* Add Button functionality for install, uninstall, info, install selected, uninstall selected, clear and implement search

* Rest application.json to Main

* Reset Compile to main

* Pretty much revamp_apps but without changes to applications.json

* Small fixes

* Add Get-Installed Loading Indicator + small fixes

* Re-Add Choco Preference

* Remove Logic from Invoke-WPFUIElements that is Moved to Invoke-WPFUIApps

* Remove Alphabetical List, Sort Apps inside Category Alphabetically

* Small fixes to the Get-Installed function and formatting stuff

* Style for Hidden Checkbox but visible Content

* Hotfix for Category Expansion during search

* Replace Category Label with ToggleButton, Fix Search Bugs

* First Try at implementing a Compact Mode for the App page

* Fix Whitespace when using Search

* Keep the search status when switching between compact and full view

* Fix weird buggy behaviour in regards to switching the Display Mode and using Show-SelectedOnly

* Improve Togglebutton

- add initial implementation of togglebutton style
- add togglebuttons to appnavigation.json
- refractor UI element creation for Togglebutton
- commit preprocessing changes

* Togglebutton fixes

- move dot to the right in style
- cleanup code
- fix arrangement of content

* Add logic to the new ToggleButtons in the sidebar of the install tab and remove old buttons

* reorder buttons & fix Togglebutton toggling if action not possible

- reorder getinstalled and clearselection
- set togglebutton back if no app is selected

* Slight modificatoin to togglebutton style & fix sidebar width

* Add hover effect for the app tiles

* ToggleButtonStyle animation

- add hover animation to white dot
- remove IsPressed trigger
- improve some comments

* disable show selected filter on clear selection

* Add a Popup Dropdown for Selected Apps with the ability to deselect them

* Split up the functions to seperate files like the rest of the repo

* Fix Bug where Scrollviewer dosnt work

* disable autofallback checkbox

* run preprocessing

* remove installation scope

- remove all 3 radiobuttons from appnavigation.json

* remove scrollviewer from WPFUIElements

* toggle showselected on GetInstalled

* remove unused autofallback

---------

Co-authored-by: Martin Wiethan <47688561+Marterich@users.noreply.github.com>
Co-authored-by: Chris Titus <contact@christitus.com>
2025-03-01 13:50:12 -06:00
bess
1ae16f6f38
Update dev docs table of contents links (#3181) 2025-02-28 10:59:42 -06:00
matthewkasiski
6038556e64
Feature/disable wpbt execution (#3188)
* add IDE

* add tweak
2025-02-28 10:56:45 -06:00
Kurt217432975
329a3de9a6
Fix winget command and update FxSound description (#3207) 2025-02-28 10:55:19 -06:00
ChrisTitusTech
f6e5d0e053 Deploying to main from @ ChrisTitusTech/winutil@364076c25e 🚀 2025-02-27 15:33:22 +00:00
MyDrift
364076c25e
[GHTemplates] Use new preview of Issue templates (#3202)
* use new issue preview

- convert existing issue templates to new template style
- move issue validation to start
- add important section at start
- improve checkbox UX
- improve wording a bit
- add config to link discord & remove blank issues

* remove description
2025-02-25 11:29:18 -06:00
ChrisTitusTech
a051e64a91 Deploying to main from @ ChrisTitusTech/winutil@dccda61ab4 🚀 2025-02-20 15:33:18 +00:00
ChrisTitusTech
dccda61ab4 Deploying to main from @ ChrisTitusTech/winutil@048f580a56 🚀 2025-02-06 15:32:52 +00:00
ChrisTitusTech
048f580a56 Deploying to main from @ ChrisTitusTech/winutil@bfb83ced79 🚀 2025-02-05 15:33:03 +00:00
ChrisTitusTech
bfb83ced79 Deploying to main from @ ChrisTitusTech/winutil@e2b37445f6 🚀 2025-02-01 15:31:03 +00:00
ChrisTitusTech
e2b37445f6 Deploying to main from @ ChrisTitusTech/winutil@c2fb98b0dc 🚀 2025-01-31 15:30:57 +00:00
ChrisTitusTech
c2fb98b0dc Deploying to main from @ ChrisTitusTech/winutil@cf8787a700 🚀 2025-01-30 15:32:01 +00:00
Matt Creekmore
cf8787a700
Fixed impartial nerd font uninstallation (#3171)
* fix: nerdfonts uninstall now deletes corresponding registry keys

* change ErrorAction to SilentlyContinue

* fix some code styling

* removed unused files/docs as per Cryostrixx advice

* restored portions of the feature.json
2025-01-28 13:59:00 -06:00
YusufKhalifadev
53b723fa11
update application.json (#3166) 2025-01-28 13:50:31 -06:00
CodingWonders
32cb94f392
[MicroWin] Fixed divide by zero error for fallback (#3174)
<Insert the never mind - misspelled a variable meme here>
2025-01-28 11:03:35 -06:00
ChrisTitusTech
5550e40270 Deploying to main from @ ChrisTitusTech/winutil@bcecf67c7d 🚀 2025-01-28 15:32:37 +00:00
ChrisTitusTech
bcecf67c7d Deploying to main from @ ChrisTitusTech/winutil@3b50ff813c 🚀 2025-01-27 15:30:51 +00:00
ChrisTitusTech
3b50ff813c Deploying to main from @ ChrisTitusTech/winutil@eba5b35978 🚀 2025-01-26 15:30:58 +00:00
ChrisTitusTech
eba5b35978 Deploying to main from @ ChrisTitusTech/winutil@254738a420 🚀 2025-01-20 15:32:07 +00:00
bvd0
254738a420
Use HTTPS instead of HTTP for URLs where supported. (#3161) 2025-01-17 08:42:42 -06:00
CodingWonders
bcc801683d
[Tweaks] Disable output for DISM for the Recall tweak (#3154)
* Fixed lock caused by expected input for DISM

This is the main event

* Miscellaneous file

Don't know why this file was modified by the compile preprocessor
2025-01-17 08:40:04 -06:00
ChrisTitusTech
72c23823b2 Deploying to main from @ ChrisTitusTech/winutil@4e1ce7e417 🚀 2025-01-11 15:30:55 +00:00
dependabot[bot]
4e1ce7e417
Bump jinja2 from 3.1.4 to 3.1.5 in /.github (#3126)
Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.4...3.1.5)

---
updated-dependencies:
- dependency-name: jinja2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-10 13:42:46 -06:00
maxi322
1dd0367417
Add timestamp server to code signature (#3139)
Co-authored-by: maxi322 <maxi322@users.noreply.github.com>
2025-01-10 13:41:54 -06:00
MyDrift
201f24c76e
[FEAT] Remove Start Menu Recommendations / Fix GetToggle Logic (#3089)
* add WPFToggleRemoveRecommended

- add WPFToggleStartMenuRecommendations
- add reg entrys to modify for toggle
- add non working link bc devdocs are broken in general

* add iseducationenvironment notice

* improve handling if entry does not exist

- add DefaultState property
- add handler for DefaultState in Get-WinUtilToggleStatus

* remove helper console logs

* fix search defaultstate

* added missing default states
2025-01-10 13:41:26 -06:00
CodingWonders
9183e92692
[MicroWin] Preparation for 2025 (#3066)
* Set Boot Manager entry timeout to 0

Fixes #2562

* Exclude Windows Hello stuff from package removal

* Obscure passwords with Base64 and fix indentation

Fixes #3064

* Fix name of excluded package

* Update comment

It reflects my feelings towards Microsoft when it comes to security a lot better

* Remove jargon of scratch directory options

* Package exclusion improvements

- Removed AppX packages from OS package exclusion list
- Added exclusion of PowerShell ISE (source: Discord server - yes, some people still use the PowerShell ISE)

* Exclude Windows Photo Viewer from dir removal

* Improve copy operation to Ventoy drives

This change may fix the issues where there's a conflict between both Ventoy's and MicroWin's unattended answer files, causing target images to stop working as expected during OOBE

* Add VirtIO functionality and more enhancements

- Added the ability to grab VirtIO Guest Tools
- Modified the description of the Copy ISO files function because it basically had nonsense

* Fix typo (#3104)

* Access specific property of ISO image object

Only show the ISO path. No one is interested in the storage type

* Add detections for expedited app removal

They only affect 24H2 and newer. Earlier releases don't have these expedited apps

* Update message

* Add VirtIO instructions to MicroWin page

* Add DISM command fallback

This fallback is triggered if an exception occurs while getting information with the cmdlets (I couldn't test this on my host as everything magically works now - sometimes it threw the Class not registered error)

* Exclude OpenSSH from package removal

Some people need this to avoid installing third-party programs like PuTTY

* Fixed some more indentation
2025-01-10 13:40:25 -06:00
DeveloperDurp
fa9dbcace4
Move Installer for OpenSSH to a runspace (#3117) 2025-01-10 13:39:21 -06:00
ChrisTitusTech
02f0f85c25 Deploying to main from @ ChrisTitusTech/winutil@83ae0579ba 🚀 2025-01-09 15:32:34 +00:00
ChrisTitusTech
83ae0579ba Deploying to main from @ ChrisTitusTech/winutil@5ebcacf404 🚀 2025-01-06 15:31:53 +00:00
ChrisTitusTech
5ebcacf404 Deploying to main from @ ChrisTitusTech/winutil@28bea518f0 🚀 2024-12-31 15:31:36 +00:00
DeveloperDurp
28bea518f0
Add exception catch for Unauthorized Access (#3114) 2024-12-28 15:38:40 -06:00
ChrisTitusTech
61c2e39ddb Deploying to main from @ ChrisTitusTech/winutil@0dfa9617fc 🚀 2024-12-27 15:31:18 +00:00
ChrisTitusTech
0dfa9617fc Deploying to main from @ ChrisTitusTech/winutil@2ce4f54b80 🚀 2024-12-26 15:31:44 +00:00
ChrisTitusTech
2ce4f54b80 Deploying to main from @ ChrisTitusTech/winutil@a05556a896 🚀 2024-12-17 15:34:08 +00:00
ChrisTitusTech
a05556a896 Deploying to main from @ ChrisTitusTech/winutil@985d415db1 🚀 2024-12-16 15:34:05 +00:00
ChrisTitusTech
985d415db1 Deploying to main from @ ChrisTitusTech/winutil@f4d4bdad3c 🚀 2024-12-12 15:34:22 +00:00
Chris Titus Tech
f4d4bdad3c move prefer ipv4 to advanced 2024-12-09 12:08:27 -06:00
Chris Titus Tech
9d47514190 move prefer ipv4 to advanced 2024-12-09 12:07:56 -06:00
ChrisTitusTech
4fc34e44b3 Deploying to main from @ ChrisTitusTech/winutil@c33946bde2 🚀 2024-12-09 15:34:30 +00:00
Chris Titus
c33946bde2 tweaks remove all 2024-12-09 00:21:45 -06:00
ChrisTitusTech
4466720493 Deploying to main from @ ChrisTitusTech/winutil@1d0e3bfd5c 🚀 2024-12-08 15:33:04 +00:00
MyDrift
1d0e3bfd5c
[FEAT] TweakToggles logik overhaul (#3014)
* move logic to json template

- remove Invoke-WPFToggle.ps1
- generalize Get-WinUtilToggleStatus
- add bingsearch reg key for testing
- use Invoke-WinUtilTweaks for actions
- replace Add-Click with checked & unchecked to make undo work

* add reg params for toggles into tweaks.json

- add all reg keys to tweaks.json into existing toggle entry
- remove unneeded scripts

* fix HKU

- load HKU if needed (for tweaks & GetToggleStatus)
- remove unneeded Invoke-WinUtilNumLock
- has loaded HKU does not load/not stay loaded

* add a lot of error handling

* Bugfix: New-PSDrive seems to return the "hku" itself so weirdly gets prepended to the return value so the result becomes ("hku", $false). In powershell pretty much every variable that exists is interpreted as $true so the toggle for numlock got incorrectly checked

* globally fix HKU error & minimize console feedback

- fix HKU issue globally
- remove some console logs, change some others to write-debug

* update Explorerrefresh

- change Invoke-WinUtilExplorerRefresh to handle refresh and restart
- add restart logic to window snapping Flyout & Suggestions
- rename Invoke-WinUtilExplorerRefresh to Invoke-WinUtilExplorerUpdate

* add explorer restart where needed to take effect

add explorer restart logic for hidden files + Fileextension toggles

* fix missing theme change logic in darkmode toggle

* fix window snapping

- fix issue defining WindowArrangementActive as dword instead of string

* fix bing search

- switch bing search enabled/disabled values

* add a little bit of error handling

- add error handling for Get-WinUtilToggleStatus

---------

Co-authored-by: Marterich <47688561+Marterich@users.noreply.github.com>
2024-12-05 21:24:36 -06:00
Mr.k
83450aef7b
[UI/UX] Update the look & feel of the GUI (#2884)
* Add @CodingWonders to the About page for his contribution and determination to make WinUtil (and MicroWin) the best software it can be!

* Remove the 'LogoSize' Parameter for About page - Make every sponsor in the sponsors list a link to ChrisTitusTech's Sponsors web link

* Change Theme Option name from 'ConfigTabButtonFontSize' to 'ConfigUpdateButtonFontSize' - Lower its value from 16 to 14

* Change Theme Option name from 'FontSizeHeading' to 'HeadingFontSize' for consistency

* Update 'LinkForegroundColor' for Light Theme to be lighter which'll make link hover color more noticeable

* Update 'Show-CustomDialog' Private Function

- Made a lot of theming/styling choices for Custom Dialogs exposed as parameters.
- Update the documentation for these new parameters in 'Show-CustomDialog' Function.
- Add a Link Hover Effect using 'Add_EVENT' methods (This can be tweaks/tuned-down if needed).
- Made use of 'Title' Parameter for 'Show-CustomDialog' Function inside 'scripts/main.ps1' script, to change Dialog Window Title.
- Now you can change the Logo Size of WinUtil through the 'LogoSize' Theming Option (the option was there, but not used in implementation).

* Preprocessing result

* Fix Settings Popup not closing after losing focus - Add trivial null checks for better debugging of UI code

* Remove unnecessary whitespace indentation in 'main.ps1' script

* Add a new 'Invoke-WPFPopup' Function to Better Handle Showing/Hiding/Toggling of Popups

* Improve 'Invoke-WPFPopup' by @MyDrift-user

Thanks for the improvements :)

---------

Co-authored-by: MyDrift <personal@mdiana.ch>
Co-authored-by: Chris Titus <contact@christitus.com>
2024-12-05 21:22:33 -06:00
Ed Blankenship
e2ce998426
Adding .NET 9.0 runtime to applications config (#3041) 2024-12-05 21:19:49 -06:00
Chris Titus
cf7f161a06
Fix language and Logic to Updates (#3087) 2024-12-05 21:18:46 -06:00
Chris Titus
d6c1fbe4a2
Change install to winget, nuget, msstore (#3088) 2024-12-05 21:18:28 -06:00
MyDrift
0779dd9096
[CI/CD] Update Issue Commands (#3052)
* update issue commands workflow

- remove existing workflow
- copy linutil's workflow into winutil
- add @CodingWonders as allowed user

* remove op from rights

- op could spam and create a ton of new labels, or spam workflow to close, reopen and so one
2024-12-01 14:30:10 -06:00
MyDrift
d48f212be4
[Issue Template] Add Validation (#3067)
* issue template update

- add  issue validation inspired by https://github.com/ChrisTitusTech/linutil/pull/459
- standardize capitalisation of characters in titles
- update feature request to use headers instead of bold text for titles

* use "I checked" for Issue validation
2024-12-01 14:29:04 -06:00
MyDrift
9c52f01204
remove redundant & outdated info in workflow (#3076)
- stale + closing message contains outdated time
- remove mention of how long it has been to simplify it.
2024-12-01 14:28:37 -06:00
Chris Titus Tech
d49b21f881 Fix onedrive remove for msapps 2024-11-25 10:07:43 -06:00
ChrisTitusTech
39ee4d53c0 Deploying to main from @ ChrisTitusTech/winutil@6e708bfe95 🚀 2024-11-16 15:32:42 +00:00
ChrisTitusTech
6e708bfe95 Deploying to main from @ ChrisTitusTech/winutil@e2b9586b0d 🚀 2024-11-08 15:32:39 +00:00
Mr.k
e2b9586b0d
Simple changes to 'Invoke-WPFTab' Public Function (#2976)
* Improve 'Invoke-WPFTab' Parameter by specifying its type (as expected by the function) and make it Mandatory

* Simple performance increases in 'Invoke-WPFTab' function - Use where method instead of piping the result into Where-Object

* Remove commented-out code in 'Invoke-WPFTab' function
2024-11-07 12:30:15 -06:00
Mr.k
c418fe9030
Simples fixes to 'Compile.ps1' Script (#2971)
* Save WinUtil's json strings with DOS-Style Newline Character (CRLF) instead of Unix-Style Newline Character (LF)

Originated from PR #2816 by @ruxunderscore

* Exit Early when facing Syntax Errors, Solves a problem when passing '-Run' Argument with 'Compile.ps1' Script - Use 'Out-Null' to follow common project conventions
2024-11-07 12:24:47 -06:00
CodingWonders
d619ee7e85
[MicroWin] Fix reference issue after #2888 (#3022)
Specifically, it fixes a reference issue for the "Recall fix". Thankfully, we're not making a release yet :)
2024-11-07 12:14:46 -06:00
Warrentheo
bbc18b2d4b
Displays build version of input ISO (#3015) 2024-11-07 12:12:18 -06:00
MyDrift
9778c0d572
[DOCS] Update Userguide (DNS) (#2987)
* update dns userguide docs

- add adguard
- add dns0
- remove Level3
- change google link from german to english

* remove unneeded negation
2024-11-07 12:11:16 -06:00
Dhruv Mistry
8087a607fc
Updating for Snappy Driver Installation (#2967)
* Updating for Snappy Driver Installation

Just directing it to website rather than the sourceforge download page

* Update applications.json
2024-11-07 12:10:45 -06:00
Samq64
e5b79559bd
Update README Screenshot (#2950)
* Update README Screenshot

* Remove desktop background
2024-11-07 12:10:04 -06:00
Rux
66e6aa7e96
Change Verbs to be in the list of Approved Verbs (#2912)
Check-UpgradeNeeded -> Test-UpgradeNeeded
Run-ChocoCommand -> Invoke-ChocoCommand
2024-11-07 12:07:13 -06:00
sev
def47fe018
KnownIssues: reformat, reorganize, clean up (#2899)
* KnownIssues: reformat, reorganize, clean up

- fix bad tabulation in rendered markdown. GFM is very forgiving with tabs, but most implementations require four spaces per level.
- fix headers and header depth (H3 should not be the toplevel...)
- convert some list items to headers
- fix some grammar and reword some parts
- reorganize some list elements and sections
- unify use of key shortcut presentation (`Win`+`X`)
- convert some quoted words to italics
- don't include punctuation in emphasized/quoted technical words
- better explain some of the troubleshooting steps
- add key takeaways to battery health section
- other general proofreading

* KnownIssues.md: add clarifying text
2024-11-07 12:06:04 -06:00
ChrisTitusTech
b382f16ae8 Deploying to main from @ ChrisTitusTech/winutil@171441ddcf 🚀 2024-11-07 15:32:27 +00:00
Cryostrixx
171441ddcf
Remake PR for Uninstall CTT PowerShell Profile (#3012) 2024-11-06 18:46:56 -06:00
MyDrift
7a0c40420e
Remove Policies in tweaks.json (#2991)
* remove policies in tweaks.json

* add proper console log
2024-11-06 18:38:35 -06:00
Real-MullaC
0f0d9d0ae3
Rename contribute.md to CONTRIBUTING.md (#2981) 2024-11-06 18:36:49 -06:00
Real-MullaC
6149738e6c
Update mkdocs.yml (#2982) 2024-11-06 18:36:26 -06:00
Martin Wiethan
aa0b03feda
Update windev.ps1 (#3016)
Update the text if no pre-release is found and change the text color from red to yellow to mark this as a warning instead of an error
2024-11-06 18:33:17 -06:00
MyDrift
e0889d51db
[Microwin] dedicated Function folder (#2888)
* move Microwin related stuff to own Folder under "Functions"

* update runspace function gathering logic

* update Recall logic (from main repo)

* change to easier naming scheme

- rename files
- rename function names

* remove unneeded comment (after @CodingWonders's suggestion)
2024-11-06 12:11:36 -06:00
ChrisTitusTech
ce1ef2a519 Deploying to main from @ ChrisTitusTech/winutil@77cb0a14c4 🚀 2024-11-01 15:33:13 +00:00
Real-MullaC
77cb0a14c4
Gets docs ready for moving (#2992) 2024-10-29 17:27:31 -05:00
Chris Titus
c254a43f77 Fix policy reset for default updates 2024-10-29 16:58:14 -05:00
CodingWonders
640d2ca107
[MicroWin] Remove WinUtil shortcut on first logon (#2989) 2024-10-29 16:51:32 -05:00
Chris Titus Tech
c186642998 Remove WPFShortcut Creation
Was causing virus false positives.
2024-10-29 16:35:43 -05:00
Chris Titus Tech
47a4f1547e Merge branch 'main' of https://github.com/ChrisTitusTech/winutil 2024-10-29 16:22:04 -05:00
Chris Titus Tech
1caf3111d3 remove shortcut hexedit 2024-10-29 16:21:57 -05:00
ChrisTitusTech
7dcdc4dbb7 Deploying to main from @ ChrisTitusTech/winutil@bfaba14191 🚀 2024-10-26 15:31:46 +00:00
116 changed files with 4526 additions and 4145 deletions

View File

@ -1,26 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
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
View 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
View 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.

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'enhancement'
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. -->

View 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

2
.github/mkdocs.yml vendored
View File

@ -5,7 +5,7 @@ repo_url: https://github.com/ChrisTitusTech/winutil
nav: nav:
- Introduction: 'index.md' - Introduction: 'index.md'
- User Guide: 'userguide.md' - User Guide: 'userguide.md'
- Contributing Guide: 'contribute.md' - Contributing Guide: 'CONTRIBUTING.md'
- Documentation: - Documentation:
- Dev Docs: 'devdocs.md' - Dev Docs: 'devdocs.md'
- Known Issues: 'KnownIssues.md' - Known Issues: 'KnownIssues.md'

View File

@ -15,7 +15,7 @@ gitdb==4.0.11
GitPython==3.1.43 GitPython==3.1.43
htmlmin2==0.1.13 htmlmin2==0.1.13
idna==3.7 idna==3.7
Jinja2==3.1.4 Jinja2==3.1.5
jsmin==3.0.1 jsmin==3.0.1
Markdown==3.6 Markdown==3.6
MarkupSafe==2.1.5 MarkupSafe==2.1.5

View File

@ -28,8 +28,8 @@ jobs:
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

View File

@ -1,11 +1,11 @@
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 # Skip this job if the comment was created/edited on a PR
if: ${{ !github.event.issue.pull_request }} if: ${{ !github.event.issue.pull_request }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -17,6 +17,30 @@ jobs:
steps: steps:
- run: echo "command=false" >> $GITHUB_ENV - run: echo "command=false" >> $GITHUB_ENV
- 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 - name: Check for /close command
id: check_close_command id: check_close_command
run: | run: |
@ -43,15 +67,15 @@ jobs:
id: check_user id: check_user
if: env.command == '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.close_command == '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 }}
@ -63,11 +87,29 @@ jobs:
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }} gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
fi fi
- name: Reopen issue if conditions are met - name: Reopen issue
if: env.reopen_command == 'true' && env.user == 'true' if: env.reopen_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 Reopening the issue... echo Reopening the issue...
gh issue reopen $ISSUE_NUMBER --repo ${{ github.repository }} 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 }}"

View File

@ -49,31 +49,6 @@ jobs:
} }
shell: pwsh shell: pwsh
- name: Create and import code signing certificate
shell: pwsh
run: |
[System.IO.File]::WriteAllBytes("$env:USERPROFILE\code-signing-cert.pfx", [System.Convert]::FromBase64String("$env:CERTIFICATE_BASE64"))
Import-PfxCertificate -FilePath "$env:USERPROFILE\code-signing-cert.pfx" -CertStoreLocation Cert:\CurrentUser\My
- name: Code sign winutil.ps1
shell: pwsh
run: |
$cert = Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
if ($null -eq $cert) { throw "Code signing certificate not found" }
Set-AuthenticodeSignature -FilePath ./winutil.ps1 -Certificate $cert
- name: Verify code signature
shell: pwsh
run: |
$signature = Get-AuthenticodeSignature -FilePath ./winutil.ps1
if ($signature.Status -ne 'Valid') { throw "Code signing failed" }
- name: Upload winutil.ps1 as artifact
uses: actions/upload-artifact@v4
with:
name: winutil
path: ./winutil.ps1
- name: Generate Release Notes - name: Generate Release Notes
id: generate_notes id: generate_notes
uses: release-drafter/release-drafter@v6 uses: release-drafter/release-drafter@v6

9
.gitignore vendored
View File

@ -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
@ -46,4 +50,7 @@ True
test.ps1 test.ps1
winutil.ps1 winutil.ps1
binary/ # temporary excludes for docs
.github/site/
binary/

View File

@ -1,7 +1,6 @@
param ( param (
[switch]$Debug, [switch]$Debug,
[switch]$Run, [switch]$Run,
[switch]$SkipPreprocessing,
[string]$Arguments [string]$Arguments
) )
@ -45,17 +44,16 @@ $header = @"
################################################################################################################ ################################################################################################################
"@ "@
if (-NOT $SkipPreprocessing) {
Update-Progress "Pre-req: Running Preprocessor..." 0
# Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script Update-Progress "Pre-req: Running Preprocessor..." 0
$preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1"
. $preprocessingFilePath
$excludedFiles = @('.\.git\', '.\.gitignore', '.\.gitattributes', '.\.github\CODEOWNERS', '.\LICENSE', "$preprocessingFilePath", '*.png', '*.exe') # Dot source the 'Invoke-Preprocessing' Function from 'tools/Invoke-Preprocessing.ps1' Script
$msg = "Pre-req: Code Formatting" $preprocessingFilePath = ".\tools\Invoke-Preprocessing.ps1"
Invoke-Preprocessing -WorkingDir "$workingdir" -ExcludedFiles $excludedFiles -ProgressStatusMessage $msg -ThrowExceptionOnEmptyFilesList . $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
@ -91,7 +89,7 @@ $($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) = @'`n$json`n'@ `| ConvertFrom-Json" )) $script_content.Add($(Write-Output "`$sync.configs.$($psitem.BaseName) = @'`r`n$json`r`n'@ `| ConvertFrom-Json" ))
} }
# Read the entire XAML file as a single string, preserving line breaks # Read the entire XAML file as a single string, preserving line breaks
@ -125,10 +123,12 @@ Write-Progress -Activity "Compiling" -Completed
Update-Progress -Activity "Validating" -StatusMessage "Checking winutil.ps1 Syntax" -Percent 0 Update-Progress -Activity "Validating" -StatusMessage "Checking winutil.ps1 Syntax" -Percent 0
try { try {
$null = Get-Command -Syntax .\winutil.ps1 Get-Command -Syntax .\winutil.ps1 | Out-Null
} catch { } catch {
Write-Warning "Syntax Validation for 'winutil.ps1' has failed" Write-Warning "Syntax Validation for 'winutil.ps1' has failed"
Write-Host "$($Error[0])" -ForegroundColor Red Write-Host "$($Error[0])" -ForegroundColor Red
Pop-Location # Restore previous location before exiting...
exit 1
} }
Write-Progress -Activity "Validating" -Completed Write-Progress -Activity "Validating" -Completed

View File

@ -3,6 +3,7 @@
[![Version](https://img.shields.io/github/v/release/ChrisTitusTech/winutil?color=%230567ff&label=Latest%20Release&style=for-the-badge)](https://github.com/ChrisTitusTech/winutil/releases/latest) [![Version](https://img.shields.io/github/v/release/ChrisTitusTech/winutil?color=%230567ff&label=Latest%20Release&style=for-the-badge)](https://github.com/ChrisTitusTech/winutil/releases/latest)
![GitHub Downloads (specific asset, all releases)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/winutil.ps1?label=Total%20Downloads&style=for-the-badge) ![GitHub Downloads (specific asset, all releases)](https://img.shields.io/github/downloads/ChrisTitusTech/winutil/winutil.ps1?label=Total%20Downloads&style=for-the-badge)
[![](https://dcbadge.limes.pink/api/server/https://discord.gg/RUbZUZyByQ?theme=default-inverted&style=for-the-badge)](https://discord.gg/RUbZUZyByQ) [![](https://dcbadge.limes.pink/api/server/https://discord.gg/RUbZUZyByQ?theme=default-inverted&style=for-the-badge)](https://discord.gg/RUbZUZyByQ)
[![Static Badge](https://img.shields.io/badge/Documentation-_?style=for-the-badge&logo=bookstack&color=grey)](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.
@ -34,11 +35,11 @@ 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/) ### [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)
@ -52,7 +53,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/ysaito8015"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;3502978?u&#x3D;ca98bf67f04d67080df0feeaa6f007fad51d273f&amp;v&#x3D;4" width="60px" alt="Yusuke Saito" /></a><a href="https://github.com/TriHydera"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;39857764?u&#x3D;5dbda638f45530582eee1703b4473f2a5e229e28&amp;v&#x3D;4" width="60px" alt="TriHydera" /></a><a href="https://github.com/jozozovko"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;3272468?u&#x3D;4391ed4655e4fd8b56e23b4169e44e2ac9b6cd97&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/DelDongo"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;127976398?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/markamos"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;9561861?u&#x3D;3cca179dcff0413538591e57a3abea116d65ce56&amp;v&#x3D;4" width="60px" alt="Mark Amos" /></a><a href="https://github.com/dwelfusius"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;54533224?u&#x3D;a49ea000a8f52adb31382ea69a1a7501b27fefdd&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/mews-se"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;58894405?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/jdiegmueller"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;18660571?u&#x3D;601d0a23040a271c86b5d40339f899a6dbf27086&amp;v&#x3D;4" width="60px" alt="Jason A. Diegmueller" /></a><a href="https://github.com/AlanTristar"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;105566568?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/zepled112"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;65176625?v&#x3D;4" width="60px" alt="wyatt" /></a><a href="https://github.com/altugtekiner"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;105917451?u&#x3D;ee73ff639c7bd9feb4708ab4ba7b14eff80196f7&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/robertsandrock"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;12015331?v&#x3D;4" width="60px" alt="RMS" /></a><a href="https://github.com/mmomega"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;71956566?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/KenichiQaz"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;31177857?u&#x3D;efdbae734a4c60a7bb95df4659d0535e60a6fd57&amp;v&#x3D;4" width="60px" alt="Stefan" /></a><a href="https://github.com/paulsheets"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;45240946?u&#x3D;d4db66f8e8d7a2606fe7a5521daf48ca9f097105&amp;v&#x3D;4" width="60px" alt="Paul" /></a><a href="https://github.com/djones369"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;4107092?v&#x3D;4" width="60px" alt="Dave Jones" /></a><a href="https://github.com/anthonymendez"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;19240897?u&#x3D;f82b4be098cac65c8421421b70ebd2d1da85c67e&amp;v&#x3D;4" width="60px" alt="Anthony Mendez" /></a><a href="https://github.com/xBandaku"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;142067112?u&#x3D;0c9a1edee45ac2a0a42827d418a12b1791d52350&amp;v&#x3D;4" width="60px" alt="xPandaku" /></a><a href="https://github.com/claudemods"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;73653396?u&#x3D;d64c656fb8db24ef56bb000197532df9b618d06c&amp;v&#x3D;4" width="60px" alt="Claudemods" /></a><a href="https://github.com/FatBastard0"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;173957728?v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/tcookj66"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;61920813?v&#x3D;4" width="60px" alt="Timothy Cook" /></a><a href="https://github.com/Ascent7910"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;118260621?v&#x3D;4" width="60px" alt="Max" /></a><a href="https://github.com/DursleyGuy"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;140165544?v&#x3D;4" width="60px" alt="DursleyGuy" /></a><a href="https://github.com/YamiSandman616"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;183505690?u&#x3D;c3bd20157058b6215e28f7568d4f8c4fbbe92838&amp;v&#x3D;4" width="60px" alt="Sandman616" /></a><a href="https://github.com/Lineax17"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;144595200?u&#x3D;a2fcdfbfeae6749396c3483e108612f65afb393d&amp;v&#x3D;4" width="60px" alt="" /></a><!-- sponsors --> <!-- sponsors --><a href="https://github.com/TriHydera"><img src="https:&#x2F;&#x2F;github.com&#x2F;TriHydera.png" width="60px" alt="User avatar: TriHydera" /></a><a href="https://github.com/DelDongo"><img src="https:&#x2F;&#x2F;github.com&#x2F;DelDongo.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/markamos"><img src="https:&#x2F;&#x2F;github.com&#x2F;markamos.png" width="60px" alt="User avatar: Mark Amos" /></a><a href="https://github.com/dwelfusius"><img src="https:&#x2F;&#x2F;github.com&#x2F;dwelfusius.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/mews-se"><img src="https:&#x2F;&#x2F;github.com&#x2F;mews-se.png" width="60px" alt="User avatar: Martin Stockzell" /></a><a href="https://github.com/jdiegmueller"><img src="https:&#x2F;&#x2F;github.com&#x2F;jdiegmueller.png" width="60px" alt="User avatar: Jason A. Diegmueller" /></a><a href="https://github.com/robertsandrock"><img src="https:&#x2F;&#x2F;github.com&#x2F;robertsandrock.png" width="60px" alt="User avatar: RMS" /></a><a href="https://github.com/KenichiQaz"><img src="https:&#x2F;&#x2F;github.com&#x2F;KenichiQaz.png" width="60px" alt="User avatar: Stefan" /></a><a href="https://github.com/paulsheets"><img src="https:&#x2F;&#x2F;github.com&#x2F;paulsheets.png" width="60px" alt="User avatar: Paul" /></a><a href="https://github.com/djones369"><img src="https:&#x2F;&#x2F;github.com&#x2F;djones369.png" width="60px" alt="User avatar: Dave J. - WhamGeek" /></a><a href="https://github.com/anthonymendez"><img src="https:&#x2F;&#x2F;github.com&#x2F;anthonymendez.png" width="60px" alt="User avatar: Anthony Mendez" /></a><a href="https://github.com/FatBastard0"><img src="https:&#x2F;&#x2F;github.com&#x2F;FatBastard0.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DursleyGuy"><img src="https:&#x2F;&#x2F;github.com&#x2F;DursleyGuy.png" width="60px" alt="User avatar: DursleyGuy" /></a><a href="https://github.com/realmuddy"><img src="https:&#x2F;&#x2F;github.com&#x2F;realmuddy.png" width="60px" alt="User avatar: Phillip Waters" /></a><a href="https://github.com/quaszi"><img src="https:&#x2F;&#x2F;github.com&#x2F;quaszi.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/DwayneTheRockLobster1"><img src="https:&#x2F;&#x2F;github.com&#x2F;DwayneTheRockLobster1.png" width="60px" alt="User avatar: " /></a><a href="https://github.com/KieraKujisawa"><img src="https:&#x2F;&#x2F;github.com&#x2F;KieraKujisawa.png" width="60px" alt="User avatar: Kiera Meredith" /></a><a href="https://github.com/craigccfl"><img src="https:&#x2F;&#x2F;github.com&#x2F;craigccfl.png" width="60px" alt="User avatar: CraigW" /></a><a href="https://github.com/RoelCrabbe"><img src="https:&#x2F;&#x2F;github.com&#x2F;RoelCrabbe.png" width="60px" alt="User avatar: Roel Crabbé" /></a><a href="https://github.com/Data-Syd"><img src="https:&#x2F;&#x2F;github.com&#x2F;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
View 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
}

View File

@ -349,7 +349,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",
@ -439,6 +439,14 @@
"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",
@ -519,14 +527,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",
@ -675,9 +675,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",
@ -701,7 +701,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",
@ -908,7 +908,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": {
@ -980,7 +980,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": {
@ -1372,7 +1372,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": {
@ -1503,14 +1503,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",
@ -1691,7 +1683,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"
}, },
@ -1871,14 +1863,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",
@ -1892,7 +1876,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": {
@ -1991,14 +1975,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",
@ -2196,7 +2172,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": {
@ -2453,7 +2429,7 @@
"content": "UniGetUI", "content": "UniGetUI",
"description": "UniGetUI is a GUI for Winget, Chocolatey, and other Windows CLI package managers.", "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",
@ -2926,5 +2902,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
View 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"
}
}

View File

@ -113,7 +113,7 @@
</RunSynchronousCommand> </RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"> <RunSynchronousCommand wcm:action="add">
<Order>19</Order> <Order>19</Order>
<Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\remove-packages.ps1' -Raw | Invoke-Expression;"</Path> <Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\Microwin-RemovePackages.ps1' -Raw | Invoke-Expression;"</Path>
</RunSynchronousCommand> </RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"> <RunSynchronousCommand wcm:action="add">
<Order>20</Order> <Order>20</Order>
@ -312,7 +312,7 @@ foreach( $file in $Document.unattend.Extensions.File ) {
[System.IO.File]::WriteAllBytes( $path, ( $encoding.GetPreamble() + $encoding.GetBytes( $file.InnerText.Trim() ) ) ); [System.IO.File]::WriteAllBytes( $path, ( $encoding.GetPreamble() + $encoding.GetBytes( $file.InnerText.Trim() ) ) );
} }
</ExtractScript> </ExtractScript>
<File path="C:\Windows\Temp\remove-packages.ps1"> <File path="C:\Windows\Temp\Microwin-RemovePackages.ps1">
$selectors = @( $selectors = @(
'Microsoft.Microsoft3DViewer'; 'Microsoft.Microsoft3DViewer';
'Microsoft.BingSearch'; 'Microsoft.BingSearch';
@ -359,7 +359,7 @@ $removeCommand = {
} }
}; };
$type = 'Package'; $type = 'Package';
$logfile = 'C:\Windows\Temp\remove-packages.log'; $logfile = 'C:\Windows\Temp\Microwin-RemovePackages.log';
&amp; { &amp; {
$installed = &amp; $getCommand; $installed = &amp; $getCommand;
foreach( $selector in $selectors ) { foreach( $selector in $selectors ) {

View File

@ -10,7 +10,7 @@
"NetFx3" "NetFx3"
], ],
"InvokeScript": [], "InvokeScript": [],
"link": "https://christitustech.github.io/winutil/dev/features/Features/dotnet" "link": "https://winutil.christitus.com/dev/features/features/dotnet"
}, },
"WPFFeatureshyperv": { "WPFFeatureshyperv": {
"Content": "HyperV Virtualization", "Content": "HyperV Virtualization",
@ -31,7 +31,7 @@
"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://christitustech.github.io/winutil/dev/features/Features/hyperv" "link": "https://winutil.christitus.com/dev/features/features/hyperv"
}, },
"WPFFeatureslegacymedia": { "WPFFeatureslegacymedia": {
"Content": "Legacy Media (WMP, DirectPlay)", "Content": "Legacy Media (WMP, DirectPlay)",
@ -46,7 +46,7 @@
"LegacyComponents" "LegacyComponents"
], ],
"InvokeScript": [], "InvokeScript": [],
"link": "https://christitustech.github.io/winutil/dev/features/Features/legacymedia" "link": "https://winutil.christitus.com/dev/features/features/legacymedia"
}, },
"WPFFeaturewsl": { "WPFFeaturewsl": {
"Content": "Windows Subsystem for Linux", "Content": "Windows Subsystem for Linux",
@ -59,7 +59,7 @@
"Microsoft-Windows-Subsystem-Linux" "Microsoft-Windows-Subsystem-Linux"
], ],
"InvokeScript": [], "InvokeScript": [],
"link": "https://christitustech.github.io/winutil/dev/features/Features/wsl" "link": "https://winutil.christitus.com/dev/features/features/wsl"
}, },
"WPFFeaturenfs": { "WPFFeaturenfs": {
"Content": "NFS - Network File System", "Content": "NFS - Network File System",
@ -79,7 +79,7 @@
"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://christitustech.github.io/winutil/dev/features/Features/nfs" "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)",
@ -97,7 +97,7 @@
Stop-Process -name explorer -force Stop-Process -name explorer -force
" "
], ],
"link": "https://christitustech.github.io/winutil/dev/features/Features/EnableSearchSuggestions" "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)",
@ -115,7 +115,7 @@
Stop-Process -name explorer -force Stop-Process -name explorer -force
" "
], ],
"link": "https://christitustech.github.io/winutil/dev/features/Features/DisableSearchSuggestions" "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",
@ -133,7 +133,7 @@
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://christitustech.github.io/winutil/dev/features/Features/RegBackup" "link": "https://winutil.christitus.com/dev/features/features/regbackup"
}, },
"WPFFeatureEnableLegacyRecovery": { "WPFFeatureEnableLegacyRecovery": {
"Content": "Enable Legacy F8 Boot Recovery", "Content": "Enable Legacy F8 Boot Recovery",
@ -151,7 +151,7 @@
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://christitustech.github.io/winutil/dev/features/Features/EnableLegacyRecovery" "link": "https://winutil.christitus.com/dev/features/features/enablelegacyrecovery"
}, },
"WPFFeatureDisableLegacyRecovery": { "WPFFeatureDisableLegacyRecovery": {
"Content": "Disable Legacy F8 Boot Recovery", "Content": "Disable Legacy F8 Boot Recovery",
@ -169,7 +169,7 @@
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://christitustech.github.io/winutil/dev/features/Features/DisableLegacyRecovery" "link": "https://winutil.christitus.com/dev/features/features/disablelegacyrecovery"
}, },
"WPFFeaturesSandbox": { "WPFFeaturesSandbox": {
"Content": "Windows Sandbox", "Content": "Windows Sandbox",
@ -177,7 +177,7 @@
"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://christitustech.github.io/winutil/dev/features/Features/Sandbox" "link": "https://winutil.christitus.com/dev/features/features/sandbox"
}, },
"WPFFeatureInstall": { "WPFFeatureInstall": {
"Content": "Install Features", "Content": "Install Features",
@ -186,7 +186,7 @@
"Order": "a060_", "Order": "a060_",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Features/Install" "link": "https://winutil.christitus.com/dev/features/features/install"
}, },
"WPFPanelAutologin": { "WPFPanelAutologin": {
"Content": "Set Up Autologin", "Content": "Set Up Autologin",
@ -195,7 +195,7 @@
"panel": "1", "panel": "1",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Autologin" "link": "https://winutil.christitus.com/dev/features/fixes/autologin"
}, },
"WPFFixesUpdate": { "WPFFixesUpdate": {
"Content": "Reset Windows Update", "Content": "Reset Windows Update",
@ -204,7 +204,7 @@
"Order": "a041_", "Order": "a041_",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Update" "link": "https://winutil.christitus.com/dev/features/fixes/update"
}, },
"WPFFixesNetwork": { "WPFFixesNetwork": {
"Content": "Reset Network", "Content": "Reset Network",
@ -213,7 +213,7 @@
"panel": "1", "panel": "1",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Network" "link": "https://winutil.christitus.com/dev/features/fixes/network"
}, },
"WPFPanelDISM": { "WPFPanelDISM": {
"Content": "System Corruption Scan", "Content": "System Corruption Scan",
@ -222,7 +222,7 @@
"Order": "a043_", "Order": "a043_",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/DISM" "link": "https://winutil.christitus.com/dev/features/fixes/dism"
}, },
"WPFFixesWinget": { "WPFFixesWinget": {
"Content": "WinGet Reinstall", "Content": "WinGet Reinstall",
@ -231,7 +231,7 @@
"Order": "a044_", "Order": "a044_",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/Winget" "link": "https://winutil.christitus.com/dev/features/fixes/winget"
}, },
"WPFRunAdobeCCCleanerTool": { "WPFRunAdobeCCCleanerTool": {
"Content": "Remove Adobe Creative Cloud", "Content": "Remove Adobe Creative Cloud",
@ -240,7 +240,7 @@
"Order": "a045_", "Order": "a045_",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Fixes/RunAdobeCCCleanerTool" "link": "https://winutil.christitus.com/dev/features/fixes/runadobecccleanertool"
}, },
"WPFPanelnetwork": { "WPFPanelnetwork": {
"Content": "Network Connections", "Content": "Network Connections",
@ -248,7 +248,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/network" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network"
}, },
"WPFPanelcontrol": { "WPFPanelcontrol": {
"Content": "Control Panel", "Content": "Control Panel",
@ -256,7 +256,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/control" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control"
}, },
"WPFPanelpower": { "WPFPanelpower": {
"Content": "Power Panel", "Content": "Power Panel",
@ -264,7 +264,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/power" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power"
}, },
"WPFPanelregion": { "WPFPanelregion": {
"Content": "Region", "Content": "Region",
@ -272,7 +272,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/region" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region"
}, },
"WPFPanelsound": { "WPFPanelsound": {
"Content": "Sound Settings", "Content": "Sound Settings",
@ -280,7 +280,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/sound" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound"
}, },
"WPFPanelprinter": { "WPFPanelprinter": {
"Content": "Printer Panel", "Content": "Printer Panel",
@ -288,7 +288,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/printer" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer"
}, },
"WPFPanelsystem": { "WPFPanelsystem": {
"Content": "System Properties", "Content": "System Properties",
@ -296,7 +296,7 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/system" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system"
}, },
"WPFPaneluser": { "WPFPaneluser": {
"Content": "User Accounts", "Content": "User Accounts",
@ -304,9 +304,16 @@
"panel": "2", "panel": "2",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/user" "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/user"
}, },
"WPFWinUtilPSProfile": { "WPFPanelGodMode": {
"Content": "God Mode",
"category": "Legacy Windows Panels",
"panel": "2",
"Type": "Button",
"ButtonWidth": "300"
},
"WPFWinUtilInstallPSProfile": {
"Content": "Install CTT PowerShell Profile", "Content": "Install CTT PowerShell Profile",
"category": "Powershell Profile", "category": "Powershell Profile",
"panel": "2", "panel": "2",
@ -314,6 +321,14 @@
"Type": "Button", "Type": "Button",
"ButtonWidth": "300" "ButtonWidth": "300"
}, },
"WPFWinUtilUninstallPSProfile": {
"Content": "Uninstall CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300"
},
"WPFWinUtilSSHServer": { "WPFWinUtilSSHServer": {
"Content": "Enable OpenSSH Server", "Content": "Enable OpenSSH Server",
"category": "Remote Access", "category": "Remote Access",

View File

@ -2,6 +2,7 @@
"Standard": [ "Standard": [
"WPFTweaksAH", "WPFTweaksAH",
"WPFTweaksConsumerFeatures", "WPFTweaksConsumerFeatures",
"WPFTweaksDisableExplorerAutoDiscovery",
"WPFTweaksDVR", "WPFTweaksDVR",
"WPFTweaksHiber", "WPFTweaksHiber",
"WPFTweaksHome", "WPFTweaksHome",
@ -14,11 +15,11 @@
"WPFTweaksDeleteTempFiles", "WPFTweaksDeleteTempFiles",
"WPFTweaksEndTaskOnTaskbar", "WPFTweaksEndTaskOnTaskbar",
"WPFTweaksRestorePoint", "WPFTweaksRestorePoint",
"WPFTweaksIPv46",
"WPFTweaksPowershell7Tele" "WPFTweaksPowershell7Tele"
], ],
"Minimal": [ "Minimal": [
"WPFTweaksConsumerFeatures", "WPFTweaksConsumerFeatures",
"WPFTweaksDisableExplorerAutoDiscovery",
"WPFTweaksHome", "WPFTweaksHome",
"WPFTweaksServices", "WPFTweaksServices",
"WPFTweaksTele" "WPFTweaksTele"

View File

@ -1,13 +1,17 @@
{ {
"shared":{ "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": "16", "HeaderFontSize": "16",
"HeaderFontFamily": "Consolas, Monaco", "HeaderFontFamily": "Consolas, Monaco",
"CheckBoxBulletDecoratorSize": "14", "CheckBoxBulletDecoratorSize": "14",
"CheckBoxMargin": "15,0,0,2", "CheckBoxMargin": "15,0,0,2",
@ -16,6 +20,7 @@
"TabButtonWidth": "110", "TabButtonWidth": "110",
"TabButtonHeight": "26", "TabButtonHeight": "26",
"TabRowHeightInPixels": "50", "TabRowHeightInPixels": "50",
"ToolTipWidth": "300",
"IconFontSize": "14", "IconFontSize": "14",
"IconButtonSize": "35", "IconButtonSize": "35",
"SettingsIconFontSize": "18", "SettingsIconFontSize": "18",
@ -27,7 +32,7 @@
"ButtonFontFamily": "Arial", "ButtonFontFamily": "Arial",
"ButtonWidth": "200", "ButtonWidth": "200",
"ButtonHeight": "25", "ButtonHeight": "25",
"ConfigTabButtonFontSize": "16", "ConfigUpdateButtonFontSize": "14",
"SearchBarWidth": "200", "SearchBarWidth": "200",
"SearchBarHeight": "26", "SearchBarHeight": "26",
"SearchBarTextBoxFontSize": "12", "SearchBarTextBoxFontSize": "12",
@ -38,13 +43,16 @@
"ButtonCornerRadius": "2" "ButtonCornerRadius": "2"
}, },
"Light": { "Light": {
"AppInstallUnselectedColor": "#F7F7F7",
"AppInstallHighlightedColor": "#CFCFCF",
"AppInstallSelectedColor": "#C2C2C2",
"ComboBoxForegroundColor": "#232629", "ComboBoxForegroundColor": "#232629",
"ComboBoxBackgroundColor": "#F7F7F7", "ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#232629", "LabelboxForegroundColor": "#232629",
"MainForegroundColor": "#232629", "MainForegroundColor": "#232629",
"MainBackgroundColor": "#F7F7F7", "MainBackgroundColor": "#F7F7F7",
"LabelBackgroundColor": "#F7F7F7", "LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#232629", "LinkForegroundColor": "#484848",
"LinkHoverForegroundColor": "#232629", "LinkHoverForegroundColor": "#232629",
"ScrollBarBackgroundColor": "#4A4D52", "ScrollBarBackgroundColor": "#4A4D52",
"ScrollBarHoverColor": "#5A5D62", "ScrollBarHoverColor": "#5A5D62",
@ -68,11 +76,15 @@
"ButtonForegroundColor": "#232629", "ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"ToggleButtonOffColor": "#707070", "ToggleButtonOffColor": "#707070",
"ToolTipBackgroundColor": "#F7F7F7",
"BorderColor": "#232629", "BorderColor": "#232629",
"BorderOpacity": "0.2" "BorderOpacity": "0.2"
}, },
"Dark": { "Dark": {
"AppInstallUnselectedColor": "#232629",
"AppInstallHighlightedColor": "#3C3C3C",
"AppInstallSelectedColor": "#4C4C4C",
"ComboBoxForegroundColor": "#F7F7F7", "ComboBoxForegroundColor": "#F7F7F7",
"ComboBoxBackgroundColor": "#1E3747", "ComboBoxBackgroundColor": "#1E3747",
"LabelboxForegroundColor": "#0567ff", "LabelboxForegroundColor": "#0567ff",
@ -103,6 +115,7 @@
"ButtonForegroundColor": "#F7F7F7", "ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"ToggleButtonOffColor": "#707070", "ToggleButtonOffColor": "#707070",
"ToolTipBackgroundColor": "#2F373D",
"BorderColor": "#2F373D", "BorderColor": "#2F373D",
"BorderOpacity": "0.2" "BorderOpacity": "0.2"
} }

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
#### **Run the latest pre-release** #### **Run the latest pre-release**
```ps1 ```ps1
irm christitus.com/windev | iex irm https://christitus.com/windev | iex
``` ```
!!! bug "Keep in mind" !!! bug "Keep in mind"

View File

@ -1,18 +1,27 @@
### Launch Issues: ## 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. ### Blocked by anti-virus
- If possible: Allow script in Anti-Virus software settings. Windows Security (formerly Defender) and other anti-virus software are known to block the script. The script gets flagged due to the fact that it requires administrator privileges & makes drastic system changes.
- If you are having TLS 1.2 issues, or are having trouble resolving `christitus.com/win` then run with the following command: To resolve this, allow/whitelist the script in your anti-virus software settings, or temporarily disable real-time protection. Since the project is open source, you may audit the code if security is a concern.
### Download not working
If `https://christitus.com/win` is not working, or you want to download the code from GitHub directly, you can use the direct download link:
```ps1 ```ps1
[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;iex(New-Object Net.WebClient).DownloadString('https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1') irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex
``` ```
- 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. If you are seeing errors referencing TLS or security, you may be running an older version of Windows where TLS 1.2 is not the default security protocol used for network connections. The following commands will force .NET to use TLS 1.2, and download the script directly using .NET instead of PowerShell:
- Source: <https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms>
If you are still having issues try using a **VPN**, or changing your **DNS provider** to one of following two providers: ```ps1
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
iex (New-Object Net.WebClient).DownloadString('https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1')
```
If it still isn't working and you live in India, it might be due to India blocking GitHub's content domain and preventing downloads. See more on [Times of India](https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms).
If you are still having issues, try using a **VPN**, or changing your **DNS provider** to one of following two providers:
| Provider | Primary DNS | Secondary DNS | | Provider | Primary DNS | Secondary DNS |
|:------------:|:------------:|:-------------:| |:------------:|:------------:|:-------------:|
@ -20,160 +29,186 @@ If you are still having issues try using a **VPN**, or changing your **DNS provi
| Google | `8.8.8.8` | `8.8.4.4` | | Google | `8.8.8.8` | `8.8.4.4` |
### Script blocked by Execution Policy
1. Ensure you are running PowerShell as admin: Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
2. In the PowerShell window, type this to allow unsigned code to execute and run the installation script:
```ps1
Set-ExecutionPolicy Unrestricted -Scope Process -Force
irm https://christitus.com/win | iex
```
- Script doesn't run/PowerShell crashes: ## Runtime Issues
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: ### WinGet configuration
If you have not installed anything using PowerShell before, you may be prompted to configure WinGet. This requires user interaction on first run. You will need to manually type `y` into the PowerShell console and press enter to continue. Once you do it the first time, you will not be prompted again.
### MicroWin: 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.
3. **Check for System Corruption:**
Run the System File Checker (SFC) utility to scan and repair system files that may be corrupted.
```powershell
sfc /scannow
```
4. **Update Your System:**
Make sure your operating system is up-to-date. Check for Windows updates and install any pending updates.
5. **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".
6. **Check for Security Software Interference:**
Security software can sometimes interfere with WMI operations. Temporarily disable your anti-virus or security software and check if the issue persists. WMI is a common attack/infection vector, so many anti-virus programs will limit its usage.
7. **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.
8. **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.
## Windows Issues
### Windows takes longer to shut down
This could be for a number of reasons:
- Turn on fast startup: Press `Windows key`+`R`, then type:
```bat
control /name Microsoft.PowerOptions /page pageGlobalSettings
```
- If that doesn't work, disable Hibernation:
- Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
- In the PowerShell window, type:
```bat
powercfg /H off
```
Related issue: [#69](https://github.com/ChrisTitusTech/winutil/issues/69)
### Windows Search does not work
Enable Background Apps. Related issues: [#69](https://github.com/ChrisTitusTech/winutil/issues/69) [95](https://github.com/ChrisTitusTech/winutil/issues/95) [#232](https://github.com/ChrisTitusTech/winutil/issues/232)
### Xbox Game Bar Activation Broken
Set the Xbox Accessory Management Service to Automatic:
- 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 ```ps1
Get-Service -Name "XboxGipSvc" | Set-Service -StartupType Automatic 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 Related issue: [#198](https://github.com/ChrisTitusTech/winutil/issues/198)
- (Windows 11) Quick Settings no longer works: Launch the Script and click 'Enable Action Center'
- Explorer no longer launches: Go to Control Panel, File Explorer Options, Change the 'Open File Explorer to' option to 'This PC'. ### Windows 11: Quick Settings no longer works
Launch the Script and click *Enable Action Center*.
### Battery drains too fast. ### Explorer (file browser) no longer launches
* When your battery on the laptop drains too fast, please perform these steps and report the results back to the Winutil community. - Press `Windows key`+`R` then type:
```bat
control /name Microsoft.FolderOptions
```
- Change the *Open File Explorer to* option to *This PC*.
### Battery drains too fast
If you're using a laptop or tablet and find your battery drains too fast, please try the below troubleshooting steps, and report the results back to the Winutil community.
1. **Check Battery Health:** 1. **Check Battery Health:**
- Open a Command Prompt as an administrator. - Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
- Run the following command to generate a battery report: - Run the following command to generate a battery report:
```powershell ```powershell
powercfg /batteryreport /output "C:\battery_report.html" powercfg /batteryreport /output "C:\battery_report.html"
``` ```
- Open the generated HTML report to review information about battery health and usage. - Open the generated HTML report to review information about battery health and usage. A battery with poor health may hold less charge, discharge faster, or cause other issues.
2. **Review Power Settings:** 2. **Review Power Settings:**
- Go to "Settings" > "System" > "Power & sleep." - Open the Settings app, and go to *System* > *Power & sleep*.
- Adjust power plan settings based on your preferences and usage patterns. - Adjust power plan settings based on your preferences and usage patterns.
- Click on "Additional power settings" to access advanced power settings. - Click on *Additional power settings* to access advanced power settings that may help.
3. **Identify Power-Hungry Apps:** 3. **Identify Power-Hungry Apps:**
- Right-click on the taskbar and select "Task Manager." - Right-click on the taskbar and select *Task Manager*.
- Navigate to the "Processes" tab to identify applications with high CPU or memory usage. - Navigate to the *Processes* tab to identify applications with high CPU or memory usage.
- Consider closing unnecessary background applications. - Consider reconfiguring, closing, disabling, or uninstalling applications that use a lot of resources.
4. **Update Drivers:** 4. **Update Drivers:**
- Visit your laptop manufacturer's website or use Windows Update to check for driver updates. - Visit your device manufacturer's website or use Windows Update to check for driver updates.
- Ensure graphics, chipset, and other essential drivers are up to date. - Ensure graphics, chipset, and other essential drivers are up to date.
5. **Check for Windows Updates:** 5. **Check for Windows Updates:**
- Go to "Settings" > "Update & Security" > "Windows Update." - Open the Settings app, and go to *Update & Security* > *Windows Update*.
- Check for and install any available updates for your operating system. - Check for and install any available updates for your operating system.
6. **Reduce Screen Brightness:** 6. **Reduce Screen Brightness:**
- Adjust screen brightness based on your preferences and lighting conditions. - Open the Settings app, and go to *System* > *Display*.
- Go to "Settings" > "System" > "Display" to adjust brightness. - Adjust screen brightness based on your preferences and lighting conditions.
7. **Battery Saver Mode:** 7. **Enable Battery Saver:**
- Go to "Settings" > "System" > "Battery." - Open the Settings app, and go to *System* > *Battery*.
- Turn on "Battery saver" to limit background activity and conserve power. - Turn on *Battery saver* to limit background activity and conserve power.
8. **Check Power Usage in Settings:** 8. **Check Power Usage in Settings:**
- Go to "Settings" > "System" > "Battery" > "Battery usage by app." - Open the Settings app, and go to *System* > *Battery* > *Battery usage by app*.
- Review the list of apps and their power usage. - Review the list of apps and their power usage. Disable or uninstall any you don't need.
9. **Check Background Apps:** 9. **Check Background Apps:**
- Go to "Settings" > "Privacy" > "Background apps." - Open the Settings app, and go to *Privacy* > *Background apps*.
- Disable unnecessary apps running in the background. - Disable or uninstall unnecessary apps running in the background.
10. **Use Powercfg for Analysis:** 10. **Use `powercfg` for Analysis:**
- Open a Command Prompt as an administrator. - Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
- Run the following command to analyze energy usage and generate a report: - Run the following command to analyze energy usage and generate a report:
```powershell ```powershell
powercfg /energy /output "C:\energy_report.html" powercfg /energy /output "C:\energy_report.html"
``` ```
- Open the generated HTML report to identify energy consumption patterns. - Open the generated HTML report to identify energy consumption patterns.
11. **Review Event Viewer:** 11. **Review Event Logs:**
- Open Event Viewer by searching for it in the Start menu. - Open Event Viewer by searching for it in the Start menu.
- Navigate to "Windows Logs" > "System." - Navigate to *Windows Logs* > *System*.
- Look for events with the source "Power-Troubleshooter" to identify power-related events. - Look for events with the source *Power-Troubleshooter* to identify power-related events. These may highlight battery, input power, and other issues.
12. **Check Wake-up Sources:** 12. **Check Wake-up Sources:**
- Open a Command Prompt as an administrator. - Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11.
- Use the command `powercfg /requests` to identify processes preventing sleep. - Use the command `powercfg /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. - Use the command `powercfg /waketimers` to view active wake timers.
- Check Task Scheduler to see if any of the discovered processes are scheduled to start on boot or at regular intervals.
13. **Resource Monitor:** 13. **Advanced Identification of Power-Hungry Apps:**
- Open Resource Monitor from the Start menu. - Open Resource Monitor from the Start menu.
- Navigate to the "CPU" tab and identify processes with high CPU usage. - Navigate to the *CPU*, *Memory*, *Network*, and other tabs to identify processes with high resource usage.
- Consider reconfiguring, closing, disabling, or uninstalling applications that use a lot of resources.
14. **Windows Settings - Activity History:** 14. **Disable Activity History:**
- In "Settings," go to "Privacy" > "Activity history." - Open the Settings app, and go to *Privacy* > *Activity history*.
- Turn off "Let Windows collect my activities from this PC." - Turn off *Let Windows collect my activities from this PC*.
15. **Network Adapters:** 15. **Prevent Network Adapters From Waking PC:**
- Open Device Manager by searching for it in the Start menu. - Open Device Manager by searching for it in the Start menu.
- Locate your network adapter, right-click, and go to "Properties." - 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. - Under the *Power Management* tab, uncheck the option that allows the device to wake the computer.
16. **Review Installed Applications:** 16. **Review Installed Applications:**
- Manually review installed applications by searching for "Add or remove programs" in the Start menu. - 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. - Check settings/preferences of individual applications for power-related options.
- Uninstall unnecessary or problematic software. - 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. These troubleshooting steps are generic, but should help in most situations. You should have these key takeaways:
- Battery health is the most significant limiter on your device's runtime. A battery in poor health usually cannot be made to last like it used to, simply by closing some applications. Consider replacing your battery.
### Troubleshoot errors during Microwin usage - Background applications that use CPU and memory, make lots of or large network requests, read/write to disk frequently, or that keep your PC awake when it could be conserving energy are the next major concern. Avoid installing programs you don't need, only use programs you trust, and configure applications to use as little power and run as infrequently as possible.
- Windows performs a lot of tasks that may affect battery life by default. Changing settings, stopping scheduled tasks, and disabling features can help the system stay in lower power states to conserve battery.
#### Error `0x80041031` - Bad chargers, inconsistent power input, and high temperatures will cause batteries to degrade and discharge faster. Use trusted high-quality chargers, ensure input power is steady, clean any fans or airflow ports, and keep the battery/PC cool.
* 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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -36,7 +36,7 @@ Disables MS Recall built into Windows since 24H2.
"InvokeScript": [ "InvokeScript": [
" "
Write-Host \"Disable Recall\" Write-Host \"Disable Recall\"
DISM /Online /Disable-Feature /FeatureName:Recall DISM /Online /Disable-Feature /FeatureName:Recall
" "
], ],
"UndoScript": [ "UndoScript": [
@ -45,7 +45,7 @@ Disables MS Recall built into Windows since 24H2.
DISM /Online /Enable-Feature /FeatureName:Recall DISM /Online /Enable-Feature /FeatureName:Recall
" "
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall" "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
}, },
``` ```
@ -56,7 +56,7 @@ Disables MS Recall built into Windows since 24H2.
```powershell ```powershell
Write-Host "Disable Recall" Write-Host "Disable Recall"
DISM /Online /Disable-Feature /FeatureName:Recall DISM /Online /Disable-Feature /FeatureName:Recall
``` ```

View File

@ -1,113 +0,0 @@
# Create WinUtil Shortcut
Last Updated: 2024-08-07
!!! info
The Development Documentation is auto generated for every compilation of WinUtil, meaning a part of it will always stay up-to-date. **Developers do have the ability to add custom content, which won't be updated automatically.**
<!-- BEGIN CUSTOM CONTENT -->
<!-- END CUSTOM CONTENT -->
<details>
<summary>Preview Code</summary>
```json
{
"Content": "Create WinUtil Shortcut",
"category": "Shortcuts",
"panel": "2",
"Order": "a082_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/tweaks/Shortcuts/Shortcut"
}
```
</details>
## Function: Invoke-WPFShortcut
```powershell
function Invoke-WPFShortcut {
<#
.SYNOPSIS
Creates a shortcut and prompts for a save location
.PARAMETER ShortcutToAdd
The name of the shortcut to add
.PARAMETER RunAsAdmin
A boolean value to make 'Run as administrator' property on (true) or off (false), defaults to off
#>
param(
$ShortcutToAdd,
[bool]$RunAsAdmin = $false
)
# Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon.
Switch ($ShortcutToAdd) {
"WinUtil" {
# Use Powershell 7 if installed and fallback to PS5 if not
if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
$shell = "pwsh.exe"
} else {
$shell = "powershell.exe"
}
$shellArgs = "-ExecutionPolicy Bypass -Command `"Start-Process $shell -verb runas -ArgumentList `'-Command `"irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex`"`'"
$DestinationName = "WinUtil.lnk"
}
}
# Show a File Dialog Browser, to let the User choose the Name and Location of where to save the Shortcut
$FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
$FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$FileBrowser.Filter = "Shortcut Files (*.lnk)|*.lnk"
$FileBrowser.FileName = $DestinationName
# Do an Early Return if the Save Operation was canceled by User's Input.
$FileBrowserResult = $FileBrowser.ShowDialog()
$DialogResultEnum = New-Object System.Windows.Forms.DialogResult
if (-not ($FileBrowserResult -eq $DialogResultEnum::OK)) {
return
}
# Prepare the Shortcut paramter
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
$Shortcut.TargetPath = $shell
$Shortcut.Arguments = $shellArgs
if (Test-Path -Path $winutildir["logo.ico"]) {
$shortcut.IconLocation = $winutildir["logo.ico"]
}
# Save the Shortcut to disk
$Shortcut.Save()
if ($RunAsAdmin -eq $true) {
$bytes = [System.IO.File]::ReadAllBytes($FileBrowser.FileName)
# 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($FileBrowser.FileName, $bytes)
}
Write-Host "Shortcut for $ShortcutToAdd has been saved to $($FileBrowser.FileName) with 'Run as administrator' set to $RunAsAdmin"
}
```
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/tweaks.json)

View File

@ -5,104 +5,104 @@
### Essential-Tweaks ### Essential-Tweaks
- [Change Windows Terminal default: PowerShell 5 -> PowerShell 7](../docs/dev/tweaks/Essential-Tweaks/Powershell7.md) - [Change Windows Terminal default: PowerShell 5 -> PowerShell 7](../dev/tweaks/Essential-Tweaks/Powershell7/)
- [Create Restore Point](../docs/dev/tweaks/Essential-Tweaks/RestorePoint.md) - [Create Restore Point](../dev/tweaks/Essential-Tweaks/RestorePoint/)
- [Debloat Edge](../docs/dev/tweaks/Essential-Tweaks/EdgeDebloat.md) - [Debloat Edge](../dev/tweaks/Essential-Tweaks/EdgeDebloat/)
- [Delete Temporary Files](../docs/dev/tweaks/Essential-Tweaks/DeleteTempFiles.md) - [Delete Temporary Files](../dev/tweaks/Essential-Tweaks/DeleteTempFiles/)
- [Disable Activity History](../docs/dev/tweaks/Essential-Tweaks/AH.md) - [Disable Activity History](../dev/tweaks/Essential-Tweaks/AH/)
- [Disable ConsumerFeatures](../docs/dev/tweaks/Essential-Tweaks/ConsumerFeatures.md) - [Disable ConsumerFeatures](../dev/tweaks/Essential-Tweaks/ConsumerFeatures/)
- [Disable GameDVR](../docs/dev/tweaks/Essential-Tweaks/DVR.md) - [Disable GameDVR](../dev/tweaks/Essential-Tweaks/DVR/)
- [Disable Hibernation](../docs/dev/tweaks/Essential-Tweaks/Hiber.md) - [Disable Hibernation](../dev/tweaks/Essential-Tweaks/Hiber/)
- [Disable Homegroup](../docs/dev/tweaks/Essential-Tweaks/Home.md) - [Disable Homegroup](../dev/tweaks/Essential-Tweaks/Home/)
- [Disable Location Tracking](../docs/dev/tweaks/Essential-Tweaks/Loc.md) - [Disable Location Tracking](../dev/tweaks/Essential-Tweaks/Loc/)
- [Disable Powershell 7 Telemetry](../docs/dev/tweaks/Essential-Tweaks/Powershell7Tele.md) - [Disable Powershell 7 Telemetry](../dev/tweaks/Essential-Tweaks/Powershell7Tele/)
- [Disable Storage Sense](../docs/dev/tweaks/Essential-Tweaks/Storage.md) - [Disable Storage Sense](../dev/tweaks/Essential-Tweaks/Storage/)
- [Disable Telemetry](../docs/dev/tweaks/Essential-Tweaks/Tele.md) - [Disable Telemetry](../dev/tweaks/Essential-Tweaks/Tele/)
- [Disable Wifi-Sense](../docs/dev/tweaks/Essential-Tweaks/Wifi.md) - [Disable Wifi-Sense](../dev/tweaks/Essential-Tweaks/Wifi/)
- [Enable End Task With Right Click](../docs/dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar.md) - [Enable End Task With Right Click](../dev/tweaks/Essential-Tweaks/EndTaskOnTaskbar/)
- [Prefer IPv4 over IPv6](../docs/dev/tweaks/Essential-Tweaks/IPv46.md) - [Prefer IPv4 over IPv6](../dev/tweaks/Essential-Tweaks/IPv46/)
- [Run Disk Cleanup](../docs/dev/tweaks/Essential-Tweaks/DiskCleanup.md) - [Run Disk Cleanup](../dev/tweaks/Essential-Tweaks/DiskCleanup/)
- [Set Hibernation as default (good for laptops)](../docs/dev/tweaks/Essential-Tweaks/LaptopHibernation.md) - [Set Hibernation as default (good for laptops)](../dev/tweaks/Essential-Tweaks/LaptopHibernation/)
- [Set Services to Manual](../docs/dev/tweaks/Essential-Tweaks/Services.md) - [Set Services to Manual](../dev/tweaks/Essential-Tweaks/Services/)
### Shortcuts ### Shortcuts
- [Create WinUtil Shortcut](../docs/dev/tweaks/Shortcuts/Shortcut.md) - [Create WinUtil Shortcut](../dev/tweaks/Shortcuts/Shortcut/)
### z--Advanced-Tweaks---CAUTION ### z--Advanced-Tweaks---CAUTION
- [Adobe Debloat](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe.md) - [Adobe Debloat](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DebloatAdobe/)
- [Adobe Network Block](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet.md) - [Adobe Network Block](../dev/tweaks/z--Advanced-Tweaks---CAUTION/BlockAdobeNet/)
- [Disable Background Apps](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps.md) - [Disable Background Apps](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableBGapps/)
- [Disable Fullscreen Optimizations](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO.md) - [Disable Fullscreen Optimizations](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableFSO/)
- [Disable Intel MM (vPro LMS)](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1.md) - [Disable Intel MM (vPro LMS)](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableLMS1/)
- [Disable IPv6](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix.md) - [Disable IPv6](../dev/tweaks/z--Advanced-Tweaks---CAUTION/Disableipsix/)
- [Disable Microsoft Copilot](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot.md) - [Disable Microsoft Copilot](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot/)
- [Disable Notification Tray/Calendar](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications.md) - [Disable Notification Tray/Calendar](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DisableNotifications/)
- [Disable Teredo](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo.md) - [Disable Teredo](../dev/tweaks/z--Advanced-Tweaks---CAUTION/Teredo/)
- [DNS](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns.md) - [DNS](../dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns/)
- [Remove ALL MS Store Apps - NOT RECOMMENDED](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat.md) - [Remove ALL MS Store Apps - NOT RECOMMENDED](../dev/tweaks/z--Advanced-Tweaks---CAUTION/DeBloat/)
- [Remove Home and Gallery from explorer](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery.md) - [Remove Home and Gallery from explorer](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveHomeGallery/)
- [Remove Microsoft Edge](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge.md) - [Remove Microsoft Edge](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveEdge/)
- [Remove OneDrive](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive.md) - [Remove OneDrive](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive/)
- [Run OO Shutup 10](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton.md) - [Run OO Shutup 10](../dev/tweaks/z--Advanced-Tweaks---CAUTION/OOSUbutton/)
- [Set Classic Right-Click Menu ](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu.md) - [Set Classic Right-Click Menu ](../dev/tweaks/z--Advanced-Tweaks---CAUTION/RightClickMenu/)
- [Set Display for Performance](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/Display.md) - [Set Display for Performance](../dev/tweaks/z--Advanced-Tweaks---CAUTION/Display/)
- [Set Time to UTC (Dual Boot)](../docs/dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC.md) - [Set Time to UTC (Dual Boot)](../dev/tweaks/z--Advanced-Tweaks---CAUTION/UTC/)
### Customize-Preferences ### Customize-Preferences
- [Bing Search in Start Menu](../docs/dev/tweaks/Customize-Preferences/BingSearch.md) - [Bing Search in Start Menu](../dev/tweaks/Customize-Preferences/BingSearch/)
- [Center Taskbar Items](../docs/dev/tweaks/Customize-Preferences/TaskbarAlignment.md) - [Center Taskbar Items](../dev/tweaks/Customize-Preferences/TaskbarAlignment/)
- [Dark Theme for Windows](../docs/dev/tweaks/Customize-Preferences/DarkMode.md) - [Dark Theme for Windows](../dev/tweaks/Customize-Preferences/DarkMode/)
- [Detailed BSoD](../docs/dev/tweaks/Customize-Preferences/DetailedBSoD.md) - [Detailed BSoD](../dev/tweaks/Customize-Preferences/DetailedBSoD/)
- [Mouse Acceleration](../docs/dev/tweaks/Customize-Preferences/MouseAcceleration.md) - [Mouse Acceleration](../dev/tweaks/Customize-Preferences/MouseAcceleration/)
- [NumLock on Startup](../docs/dev/tweaks/Customize-Preferences/NumLock.md) - [NumLock on Startup](../dev/tweaks/Customize-Preferences/NumLock/)
- [Search Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskbarSearch.md) - [Search Button in Taskbar](../dev/tweaks/Customize-Preferences/TaskbarSearch/)
- [Show File Extensions](../docs/dev/tweaks/Customize-Preferences/ShowExt.md) - [Show File Extensions](../dev/tweaks/Customize-Preferences/ShowExt/)
- [Show Hidden Files](../docs/dev/tweaks/Customize-Preferences/HiddenFiles.md) - [Show Hidden Files](../dev/tweaks/Customize-Preferences/HiddenFiles/)
- [Snap Assist Flyout](../docs/dev/tweaks/Customize-Preferences/SnapFlyout.md) - [Snap Assist Flyout](../dev/tweaks/Customize-Preferences/SnapFlyout/)
- [Snap Assist Suggestion](../docs/dev/tweaks/Customize-Preferences/SnapSuggestion.md) - [Snap Assist Suggestion](../dev/tweaks/Customize-Preferences/SnapSuggestion/)
- [Snap Window](../docs/dev/tweaks/Customize-Preferences/SnapWindow.md) - [Snap Window](../dev/tweaks/Customize-Preferences/SnapWindow/)
- [Sticky Keys](../docs/dev/tweaks/Customize-Preferences/StickyKeys.md) - [Sticky Keys](../dev/tweaks/Customize-Preferences/StickyKeys/)
- [Task View Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskView.md) - [Task View Button in Taskbar](../dev/tweaks/Customize-Preferences/TaskView/)
- [Verbose Messages During Logon](../docs/dev/tweaks/Customize-Preferences/VerboseLogon.md) - [Verbose Messages During Logon](../dev/tweaks/Customize-Preferences/VerboseLogon/)
- [Widgets Button in Taskbar](../docs/dev/tweaks/Customize-Preferences/TaskbarWidgets.md) - [Widgets Button in Taskbar](../dev/tweaks/Customize-Preferences/TaskbarWidgets/)
### Performance-Plans ### Performance-Plans
- [Add and Activate Ultimate Performance Profile](../docs/dev/tweaks/Performance-Plans/AddUltPerf.md) - [Add and Activate Ultimate Performance Profile](../dev/tweaks/Performance-Plans/AddUltPerf/)
- [Remove Ultimate Performance Profile](../docs/dev/tweaks/Performance-Plans/RemoveUltPerf.md) - [Remove Ultimate Performance Profile](../dev/tweaks/Performance-Plans/RemoveUltPerf/)
## Features ## Features
### Fixes ### Fixes
- [Remove Adobe Creative Cloud](../docs/dev/features/Fixes/RunAdobeCCCleanerTool.md) - [Remove Adobe Creative Cloud](../dev/features/Fixes/RunAdobeCCCleanerTool/)
- [Reset Network](../docs/dev/features/Fixes/Network.md) - [Reset Network](../dev/features/Fixes/Network/)
- [Reset Windows Update](../docs/dev/features/Fixes/Update.md) - [Reset Windows Update](../dev/features/Fixes/Update/)
- [Set Up Autologin](../docs/dev/features/Fixes/Autologin.md) - [Set Up Autologin](../dev/features/Fixes/Autologin/)
- [System Corruption Scan](../docs/dev/features/Fixes/DISM.md) - [System Corruption Scan](../dev/features/Fixes/DISM/)
- [WinGet Reinstall](../docs/dev/features/Fixes/Winget.md) - [WinGet Reinstall](../dev/features/Fixes/Winget/)
### Legacy-Windows-Panels ### Legacy-Windows-Panels
- [Control Panel](../docs/dev/features/Legacy-Windows-Panels/control.md) - [Control Panel](../dev/features/Legacy-Windows-Panels/control/)
- [Network Connections](../docs/dev/features/Legacy-Windows-Panels/network.md) - [Network Connections](../dev/features/Legacy-Windows-Panels/network/)
- [Power Panel](../docs/dev/features/Legacy-Windows-Panels/power.md) - [Power Panel](../dev/features/Legacy-Windows-Panels/power/)
- [Printer Settings](../docs/dev/features/Legacy-Windows-Panels/printer.md) - [Printer Settings](../dev/features/Legacy-Windows-Panels/printer/)
- [Region](../docs/dev/features/Legacy-Windows-Panels/region.md) - [Region](../dev/features/Legacy-Windows-Panels/region/)
- [Sound Settings](../docs/dev/features/Legacy-Windows-Panels/sound.md) - [Sound Settings](../dev/features/Legacy-Windows-Panels/sound/)
- [System Properties](../docs/dev/features/Legacy-Windows-Panels/system.md) - [System Properties](../dev/features/Legacy-Windows-Panels/system/)
- [User Accounts](../docs/dev/features/Legacy-Windows-Panels/user.md) - [User Accounts](../dev/features/Legacy-Windows-Panels/user/)
### Features ### Features
- [All .Net Framework (2,3,4)](../docs/dev/features/Features/dotnet.md) - [All .Net Framework (2,3,4)](../dev/features/Features/dotnet/)
- [Disable Legacy F8 Boot Recovery](../docs/dev/features/Features/DisableLegacyRecovery.md) - [Disable Legacy F8 Boot Recovery](../dev/features/Features/DisableLegacyRecovery/)
- [Disable Search Box Web Suggestions in Registry(explorer restart)](../docs/dev/features/Features/DisableSearchSuggestions.md) - [Disable Search Box Web Suggestions in Registry(explorer restart)](../dev/features/Features/DisableSearchSuggestions/)
- [Enable Daily Registry Backup Task 12.30am](../docs/dev/features/Features/RegBackup.md) - [Enable Daily Registry Backup Task 12.30am](../dev/features/Features/RegBackup/)
- [Enable Legacy F8 Boot Recovery](../docs/dev/features/Features/EnableLegacyRecovery.md) - [Enable Legacy F8 Boot Recovery](../dev/features/Features/EnableLegacyRecovery/)
- [Enable Search Box Web Suggestions in Registry(explorer restart)](../docs/dev/features/Features/EnableSearchSuggestions.md) - [Enable Search Box Web Suggestions in Registry(explorer restart)](../dev/features/Features/EnableSearchSuggestions/)
- [HyperV Virtualization](../docs/dev/features/Features/hyperv.md) - [HyperV Virtualization](../dev/features/Features/hyperv/)
- [Install Features](../docs/dev/features/Features/Install.md) - [Install Features](../dev/features/Features/Install/)
- [Legacy Media (WMP, DirectPlay)](../docs/dev/features/Features/legacymedia.md) - [Legacy Media (WMP, DirectPlay)](../dev/features/Features/legacymedia/)
- [NFS - Network File System](../docs/dev/features/Features/nfs.md) - [NFS - Network File System](../dev/features/Features/nfs/)
- [Windows Sandbox](../docs/dev/features/Features/Sandbox.md) - [Windows Sandbox](../dev/features/Features/Sandbox/)
- [Windows Subsystem for Linux](../docs/dev/features/Features/wsl.md) - [Windows Subsystem for Linux](../dev/features/Features/wsl/)

View File

@ -11,7 +11,7 @@ Welcome to the official documentation for WinUtil, your go-to utility for optimi
* You will first need to start a Powershell terminal **as Admin**. * You will first need to start a Powershell terminal **as Admin**.
* Now you can run the following command: * Now you can run the following command:
```ps1 ```ps1
irm christitus.com/win | iex irm https://christitus.com/win | iex
``` ```
!!! info !!! info

View File

@ -77,13 +77,17 @@ The utility provides a convenient DNS selection feature, allowing users to choos
* **Default**: Uses the default DNS settings configured by your ISP or network. * **Default**: Uses the default DNS settings configured by your ISP or network.
* **DHCP**: Automatically acquires DNS settings from the DHCP server. * **DHCP**: Automatically acquires DNS settings from the DHCP server.
* [**Google**](https://developers.google.com/speed/public-dns?hl=de): A reliable and fast DNS service provided by Google. * [**Google**](https://developers.google.com/speed/public-dns?hl=en): A reliable and fast DNS service provided by Google.
* [**Cloudflare**](https://developers.cloudflare.com/1.1.1.1/): Known for speed and privacy, Cloudflare DNS is a popular choice for enhancing internet performance. * [**Cloudflare**](https://developers.cloudflare.com/1.1.1.1/): Known for speed and privacy, Cloudflare DNS is a popular choice for enhancing internet performance.
* [**Cloudflare_Malware**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malicious%20content%3A): Provides additional protection by blocking malware sites. * [**Cloudflare_Malware**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malicious%20content%3A): Provides additional protection by blocking malware sites.
* [**Cloudflare_Malware_Adult**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malware%20and%20adult%20content%3A): Blocks both malware and adult content, offering more comprehensive filtering. * [**Cloudflare_Malware_Adult**](https://developers.cloudflare.com/1.1.1.1/setup/#:~:text=Use%20the%20following%20DNS%20resolvers%20to%20block%20malware%20and%20adult%20content%3A): Blocks both malware and adult content, offering more comprehensive filtering.
* [**Level3**](https://www.lumen.com/): Another fast and reliable DNS service option.
* [**Open_DNS**](https://www.opendns.com/setupguide/#familyshield): Offers customizable filtering and enhanced security features. * [**Open_DNS**](https://www.opendns.com/setupguide/#familyshield): Offers customizable filtering and enhanced security features.
* [**Quad9**](https://quad9.net/): Focuses on security by blocking known malicious domains. * [**Quad9**](https://quad9.net/): Focuses on security by blocking known malicious domains.
* [**AdGuard_Ads_Trackers**](https://adguard-dns.io/en/welcome.html) AdGuard DNS will block ads, trackers, or any other DNS requests. Visit website and login for a dashboard, statistics and customize your experience in the server settings.
* [**AdGuard_Ads_Trackers_Malware_Adult**](https://adguard-dns.io/en/welcome.html) AdGuard DNS will block ads, trackers, adult content, and enable Safe Search and Safe Mode, where possible.
* [**dns0.eu_Open**](https://www.dns0.eu/) The European public DNS that makes your Internet safer. Offers general-purpose filtering to block malware, phishing, and tracking domains for enhanced privacy and security.
* [**dns0.eu_ZERO**](https://www.dns0.eu/zero) Provides advanced security with robust filters for highly sensitive environments, blocking high-risk domains using threat intelligence and sophisticated heuristics like Newly Registered Domains (NRD) and Domain Generation Algorithms (DGA).
* [**dns0.eu_KIDS**](https://www.dns0.eu/kids) A child-safe DNS that blocks adult content, explicit search results, mature videos, dating sites, piracy, and ads, creating a secure internet experience for children on any device or network.
### Customize Preferences ### Customize Preferences
@ -254,6 +258,6 @@ With MicroWin, you can also configure your user before proceeding if you don't w
* On any supported Windows machine, open PowerShell **as Admin** and run the following command to automatically apply tweaks and install apps from the config file. * On any supported Windows machine, open PowerShell **as Admin** and run the following command to automatically apply tweaks and install apps from the config file.
```ps1 ```ps1
iex "& { $(irm christitus.com/win) } -Config [path-to-your-config] -Run" iex "& { $(irm https://christitus.com/win) } -Config [path-to-your-config] -Run"
``` ```
* Have a cup of coffee! Come back when it's done. * Have a cup of coffee! Come back when it's done.

View File

@ -1,4 +1,4 @@
function Invoke-WPFMicrowin { function Invoke-Microwin {
<# <#
.DESCRIPTION .DESCRIPTION
Invoke MicroWin routines... Invoke MicroWin routines...
@ -55,6 +55,8 @@ public class PowerManagement {
$injectDrivers = $sync.MicrowinInjectDrivers.IsChecked $injectDrivers = $sync.MicrowinInjectDrivers.IsChecked
$importDrivers = $sync.MicrowinImportDrivers.IsChecked $importDrivers = $sync.MicrowinImportDrivers.IsChecked
$importVirtIO = $sync.MicrowinCopyVirtIO.IsChecked
$mountDir = $sync.MicrowinMountDir.Text $mountDir = $sync.MicrowinMountDir.Text
$scratchDir = $sync.MicrowinScratchDir.Text $scratchDir = $sync.MicrowinScratchDir.Text
@ -76,9 +78,10 @@ public class PowerManagement {
} }
$imgVersion = (Get-WindowsImage -ImagePath $mountDir\sources\install.wim -Index $index).Version $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 # Detect image version to avoid performing MicroWin processing on Windows 8 and earlier
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,10240,0))) -eq $false) { 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." $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." $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 Write-Host $msg
@ -88,7 +91,7 @@ public class PowerManagement {
} }
# Detect whether the image to process contains Windows 10 and show warning # Detect whether the image to process contains Windows 10 and show warning
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) { 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." $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 $dlg_msg = $msg
Write-Host $msg Write-Host $msg
@ -108,7 +111,7 @@ public class PowerManagement {
Write-Host "Mounting Windows image. This may take a while." Write-Host "Mounting Windows image. This may take a while."
Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir" Mount-WindowsImage -ImagePath "$mountDir\sources\install.wim" -Index $index -Path "$scratchDir"
if ($?) { if ($?) {
Write-Host "Mounting complete! Performing removal of applications..." Write-Host "The Windows image has been mounted successfully. Continuing processing..."
} else { } else {
Write-Host "Could not mount image. Exiting..." Write-Host "Could not mount image. Exiting..."
Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning" Set-WinUtilTaskbaritem -state "Error" -value 1 -overlay "warning"
@ -154,29 +157,28 @@ public class PowerManagement {
} }
} }
if ($importVirtIO) {
Write-Host "Copying VirtIO drivers..."
Microwin-CopyVirtIO
}
Write-Host "Remove Features from the image" Write-Host "Remove Features from the image"
Remove-Features Microwin-RemoveFeatures -UseCmdlets $true
Write-Host "Removing features complete!" Write-Host "Removing features complete!"
Write-Host "Removing OS packages" Write-Host "Removing OS packages"
Remove-Packages Microwin-RemovePackages -UseCmdlets $true
Write-Host "Removing Appx Bloat" Write-Host "Removing Appx Bloat"
Remove-ProvisionedPackages Microwin-RemoveProvisionedPackages -UseCmdlets $true
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling # Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) {
{ try {
try if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf) {
{
if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf)
{
# Found the culprit. Do the following: # Found the culprit. Do the following:
# 1. Take ownership of the file, from TrustedInstaller to Administrators # 1. Take ownership of the file, from TrustedInstaller to Administrators
takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A
# 2. Set ACLs so that we can write to it # 2. Set ACLs so that we can write to it
icacls "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /grant "$(Get-LocalizedUsers -admins $true):(M)" | Out-Host 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 # 3. Open the file and do the modification
$appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" $appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml"
$originalLine = $appxManifest[13] $originalLine = $appxManifest[13]
@ -185,46 +187,44 @@ public class PowerManagement {
Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8 Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8
} }
} }
catch catch {
{ # Fall back to what we used to do: delayed disablement
Enable-WindowsOptionalFeature -Path "$scratchDir" -FeatureName "Recall"
} }
} }
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe" Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe"
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Photo Viewer" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Photo Viewer" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Mail" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Internet Explorer" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Mail" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Internet Explorer" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Internet Explorer" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\GameBarPresenceWriter"
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Internet Explorer" -Directory Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDriveSetup.exe"
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\GameBarPresenceWriter" Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDrive.ico"
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDriveSetup.exe" Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*narratorquickstart*" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDrive.ico" Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*narratorquickstart*" -Directory
Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
Write-Host "Removal complete!" Write-Host "Removal complete!"
Write-Host "Create unattend.xml" Write-Host "Create unattend.xml"
#New-Unattend
if ($sync.MicrowinUserName.Text -eq "") if ($sync.MicrowinUserName.Text -eq "")
{ {
New-Unattend -userName "User" Microwin-NewUnattend -userName "User"
} }
else else
{ {
if ($sync.MicrowinUserPassword.Password -eq "") if ($sync.MicrowinUserPassword.Password -eq "")
{ {
New-Unattend -userName "$($sync.MicrowinUserName.Text)" Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)"
} }
else else
{ {
New-Unattend -userName "$($sync.MicrowinUserName.Text)" -userPassword "$($sync.MicrowinUserPassword.Password)" Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)" -userPassword "$($sync.MicrowinUserPassword.Password)"
} }
} }
Write-Host "Done Create unattend.xml" Write-Host "Done Create unattend.xml"
@ -237,7 +237,7 @@ public class PowerManagement {
Write-Host "Done Copy unattend.xml" Write-Host "Done Copy unattend.xml"
Write-Host "Create FirstRun" Write-Host "Create FirstRun"
New-FirstRun Microwin-NewFirstRun
Write-Host "Done create FirstRun" Write-Host "Done create FirstRun"
Write-Host "Copy FirstRun.ps1 into the ISO" Write-Host "Copy FirstRun.ps1 into the ISO"
Copy-Item "$env:temp\FirstStartup.ps1" "$($scratchDir)\Windows\FirstStartup.ps1" -force Copy-Item "$env:temp\FirstStartup.ps1" "$($scratchDir)\Windows\FirstStartup.ps1" -force
@ -249,7 +249,7 @@ public class PowerManagement {
dism /English /image:$($scratchDir) /set-profilepath:"$($scratchDir)\Windows\Users\Default" dism /English /image:$($scratchDir) /set-profilepath:"$($scratchDir)\Windows\Users\Default"
Write-Host "Copy checkinstall.cmd into the ISO" Write-Host "Copy checkinstall.cmd into the ISO"
New-CheckInstall Microwin-NewCheckInstall
Copy-Item "$env:temp\checkinstall.cmd" "$($scratchDir)\Windows\checkinstall.cmd" -force Copy-Item "$env:temp\checkinstall.cmd" "$($scratchDir)\Windows\checkinstall.cmd" -force
Write-Host "Done copy checkinstall.cmd" Write-Host "Done copy checkinstall.cmd"
@ -286,20 +286,22 @@ public class PowerManagement {
reg add "HKLM\zSYSTEM\Setup\LabConfig" /v "BypassTPMCheck" /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 reg add "HKLM\zSYSTEM\Setup\MoSetup" /v "AllowUpgradesWithUnsupportedTPMOrCPU" /t REG_DWORD /d 1 /f
# Prevent Windows Update Installing so called Expedited Apps # 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', 'EdgeUpdate',
'OutlookUpdate', 'DevHomeUpdate',
'CrossDeviceUpdate' 'OutlookUpdate',
) | ForEach-Object { 'CrossDeviceUpdate'
Write-Host "Removing Windows Expedited App: $_" ) | ForEach-Object {
Write-Host "Removing Windows Expedited App: $_"
# Copied here After Installation (Online) # Copied here After Installation (Online)
# reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null # reg delete "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\$_" /f | Out-Null
# When in Offline Image # When in Offline Image
reg delete "HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\$_" /f | Out-Null 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 reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "SearchboxTaskbarMode" /t REG_DWORD /d 0 /f
@ -325,7 +327,7 @@ public class PowerManagement {
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 "AppsUseLightTheme" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "SystemUsesLightTheme" /t REG_DWORD /d 0 /f reg add "HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" /v "SystemUsesLightTheme" /t REG_DWORD /d 0 /f
if ((Test-CompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) { 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, # 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) # 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)
@ -336,6 +338,7 @@ public class PowerManagement {
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /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\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\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 { } catch {
@ -437,7 +440,7 @@ public class PowerManagement {
if ($copyToUSB) { if ($copyToUSB) {
Write-Host "Copying target ISO to the USB drive" Write-Host "Copying target ISO to the USB drive"
Copy-ToUSB("$($SaveDialog.FileName)") Microwin-CopyToUSB("$($SaveDialog.FileName)")
if ($?) { Write-Host "Done Copying target ISO to USB drive!" } else { Write-Host "ISO copy failed." } if ($?) { Write-Host "Done Copying target ISO to USB drive!" } else { Write-Host "ISO copy failed." }
} }

View File

@ -1,4 +1,4 @@
function Invoke-WPFGetIso { function Invoke-MicrowinGetIso {
<# <#
.DESCRIPTION .DESCRIPTION
Function to get the path to Iso file for MicroWin, unpack that isom=, read basic information and populate the UI Options Function to get the path to Iso file for MicroWin, unpack that isom=, read basic information and populate the UI Options
@ -50,7 +50,7 @@ function Invoke-WPFGetIso {
return return
} else { } 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.") [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.")
Get-Oscdimg -oscdimgPath $oscdimgPath Microwin-GetOscdimg -oscdimgPath $oscdimgPath
$oscdImgFound = Test-Path $oscdimgPath -PathType Leaf $oscdImgFound = Test-Path $oscdimgPath -PathType Leaf
if (!$oscdImgFound) { if (!$oscdImgFound) {
$msg = "oscdimg was not downloaded can not proceed" $msg = "oscdimg was not downloaded can not proceed"
@ -100,7 +100,7 @@ function Invoke-WPFGetIso {
Set-Location -Path $env:temp 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 # 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) { $lang = if ($sync["ISOLanguage"].SelectedIndex -eq 0) {
Get-FidoLangFromCulture -langName (Get-Culture).Name Microwin-GetLangFromCulture -langName (Get-Culture).Name
} else { } else {
$sync["ISOLanguage"].SelectedItem $sync["ISOLanguage"].SelectedItem
} }
@ -169,7 +169,7 @@ function Invoke-WPFGetIso {
try { try {
Write-Host "Mounting Iso. Please wait." Write-Host "Mounting Iso. Please wait."
$mountedISO = Mount-DiskImage -PassThru "$filePath" $mountedISO = Mount-DiskImage -PassThru "$filePath"
Write-Host "Done mounting Iso $mountedISO" Write-Host "Done mounting Iso `"$($mountedISO.ImagePath)`""
$driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter $driveLetter = (Get-Volume -DiskImage $mountedISO).DriveLetter
Write-Host "Iso mounted to '$driveLetter'" Write-Host "Iso mounted to '$driveLetter'"
} catch { } catch {
@ -189,7 +189,7 @@ function Invoke-WPFGetIso {
$sync.MicrowinScratchDirBox.Text ="" $sync.MicrowinScratchDirBox.Text =""
} }
$UseISOScratchDir = $sync.WPFMicrowinISOScratchDir.IsChecked $UseISOScratchDir = $sync.WPFMicrowinISOScratchDir.IsChecked
if ($UseISOScratchDir) { if ($UseISOScratchDir) {
$sync.MicrowinScratchDirBox.Text=$mountedISOPath $sync.MicrowinScratchDirBox.Text=$mountedISOPath
@ -220,10 +220,10 @@ function Invoke-WPFGetIso {
$sync.BusyText.Text=" - Mounting" $sync.BusyText.Text=" - Mounting"
Write-Host "Mounting Iso. Please wait." Write-Host "Mounting Iso. Please wait."
if ($sync.MicrowinScratchDirBox.Text -eq "") { if ($sync.MicrowinScratchDirBox.Text -eq "") {
$mountDir = Join-Path $env:TEMP $randomMicrowin $mountDir = Join-Path $env:TEMP $randomMicrowin
$scratchDir = Join-Path $env:TEMP $randomMicrowinScratch $scratchDir = Join-Path $env:TEMP $randomMicrowinScratch
} else { } else {
$scratchDir = $sync.MicrowinScratchDirBox.Text+"Scrach" $scratchDir = $sync.MicrowinScratchDirBox.Text+"Scratch"
$mountDir = $sync.MicrowinScratchDirBox.Text+"micro" $mountDir = $sync.MicrowinScratchDirBox.Text+"micro"
} }
@ -242,8 +242,8 @@ function Invoke-WPFGetIso {
# xcopy we can verify files and also not copy files that already exist, but hard to measure # xcopy we can verify files and also not copy files that already exist, but hard to measure
# xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null # xcopy.exe /E /I /H /R /Y /J $DriveLetter":" $mountDir >$null
$totalTime = Measure-Command { Copy-Files "$($driveLetter):" $mountDir -Recurse -Force } $totalTime = Measure-Command { Copy-Files "$($driveLetter):" "$mountDir" -Recurse -Force }
Write-Host "Copy complete! Total Time: $($totalTime.Minutes)m$($totalTime.Seconds)s" Write-Host "Copy complete! Total Time: $($totalTime.Minutes) minutes, $($totalTime.Seconds) seconds"
$wimFile = "$mountDir\sources\install.wim" $wimFile = "$mountDir\sources\install.wim"
Write-Host "Getting image information $wimFile" Write-Host "Getting image information $wimFile"

View 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
}
}

View 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"
}

View 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"
}
}

View 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" }
}
}

View 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
}
}

View File

@ -1,10 +1,10 @@
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( param(

View 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
}

View 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
}

View 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&gt;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&gt;c:\windows\csup.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>CMD /C echo GG&gt;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
}

View 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
}
}

View 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
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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)
}

View File

@ -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 (
@ -23,7 +29,7 @@ function Copy-Files {
foreach ($file in $files) { foreach ($file in $files) {
$status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name $status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name
Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100) Write-Progress -Activity "Copy disc image 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) {
@ -35,7 +41,7 @@ function Copy-Files {
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-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow
Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow

View 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
}
}
}
}
}

View 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 }
}
}
}

View 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."
$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."
$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
}

View File

@ -13,75 +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
return $app -eq 0 -and $system -eq 0
}
if($ToggleSwitch -eq "WPFToggleBingSearch") {
$bingsearch = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search').BingSearchEnabled
return $bingsearch -ne 0
}
if($ToggleSwitch -eq "WPFToggleNumLock") {
$numlockvalue = (Get-ItemProperty -path 'HKCU:\Control Panel\Keyboard').InitialKeyboardIndicators
return $numlockvalue -eq 2
}
if($ToggleSwitch -eq "WPFToggleVerboseLogon") {
$VerboseStatusvalue = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System').VerboseStatus
return $VerboseStatusvalue -eq 1
}
if($ToggleSwitch -eq "WPFToggleShowExt") {
$hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt
return $hideextvalue -eq 0
}
if($ToggleSwitch -eq "WPFToggleSnapWindow") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Control Panel\Desktop').WindowArrangementActive
return $hidesnap -ne 0
}
if($ToggleSwitch -eq "WPFToggleSnapFlyout") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout
return $hidesnap -ne 0
}
if($ToggleSwitch -eq "WPFToggleSnapSuggestion") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').SnapAssist
return $hidesnap -ne 0
}
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
return $MouseSpeed -eq 1 -and $MouseThreshold1 -eq 6 -and $MouseThreshold2 -eq 10 $ToggleSwitchReg = $sync.configs.tweaks.$ToggleSwitch.registry
}
if($ToggleSwitch -eq "WPFToggleTaskbarSearch") { try {
$SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode if (($ToggleSwitchReg.path -imatch "hku") -and !(Get-PSDrive -Name HKU -ErrorAction SilentlyContinue)) {
return $SearchButton -ne 0 $null = (New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS)
} if (Get-PSDrive -Name HKU -ErrorAction SilentlyContinue) {
if ($ToggleSwitch -eq "WPFToggleStickyKeys") { Write-Debug "HKU drive created successfully"
$StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags } else {
return $StickyKeys -ne 58 Write-Debug "Failed to create HKU drive"
} }
if ($ToggleSwitch -eq "WPFToggleTaskView") { }
$TaskView = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').ShowTaskViewButton } catch {
return $TaskView -ne 0 Write-Error "An error occurred regarding the HKU Drive: $_"
return $false
} }
if ($ToggleSwitch -eq "WPFToggleHiddenFiles") { if ($ToggleSwitchReg) {
$HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden $count = 0
return $HiddenFiles -ne 0
}
if ($ToggleSwitch -eq "WPFToggleTaskbarWidgets") { foreach ($regentry in $ToggleSwitchReg) {
$TaskbarWidgets = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskBarDa try {
return $TaskbarWidgets -ne 0 if (!(Test-Path $regentry.Path)) {
} New-Item -Path $regentry.Path -Force | Out-Null
if ($ToggleSwitch -eq "WPFToggleTaskbarAlignment") { }
$TaskbarAlignment = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskbarAl $regstate = (Get-ItemProperty -path $regentry.Path).$($regentry.Name)
return $TaskbarAlignment -ne 0 if ($regstate -eq $regentry.Value) {
} $count += 1
if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") { Write-Debug "$($regentry.Name) is true (state: $regstate, value: $($regentry.Value), original: $($regentry.OriginalValue))"
$DetailedBSoD1 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters } else {
$DetailedBSoD2 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisableEmoticon Write-Debug "$($regentry.Name) is false (state: $regstate, value: $($regentry.Value), original: $($regentry.OriginalValue))"
return !(($DetailedBSoD1 -eq 0) -or ($DetailedBSoD2 -eq 0) -or !$DetailedBSoD1 -or !$DetailedBSoD2) }
if (!$regstate) {
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
}
}
}
} catch {
Write-Error "An unexpected error occurred: $_"
}
}
if ($count -eq $ToggleSwitchReg.Count) {
Write-Debug "$($ToggleSwitchReg.Name) is true (count: $count)"
return $true
} else {
Write-Debug "$($ToggleSwitchReg.Name) is false (count: $count)"
return $false
}
} else {
return $false
} }
} }

View File

@ -1,26 +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
}

View File

@ -1,28 +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')
}
}

View 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
}

View File

@ -0,0 +1,45 @@
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
.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")
# 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
## 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'
# 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)
$scrollViewer.Content = $itemsControl
$Border.Child = $scrollViewer
$null = $targetGrid.Children.Add($Border)
return $itemsControl
}

View 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 $_)
}
}
}

View File

@ -44,7 +44,7 @@ function Install-WinUtilProgramChoco {
New-Item -ItemType File -Path $filePath | Out-Null New-Item -ItemType File -Path $filePath | Out-Null
} }
function Run-ChocoCommand { function Invoke-ChocoCommand {
<# <#
.SYNOPSIS .SYNOPSIS
Executes a Chocolatey command with the specified arguments and returns the exit code. Executes a Chocolatey command with the specified arguments and returns the exit code.
@ -60,14 +60,14 @@ function Install-WinUtilProgramChoco {
The exit code of the Chocolatey command. The exit code of the Chocolatey command.
.EXAMPLE .EXAMPLE
$exitCode = Run-ChocoCommand -arguments "install 7zip -y" $exitCode = Invoke-ChocoCommand -arguments "install 7zip -y"
#> #>
param ($arguments) param ($arguments)
return (Start-Process -FilePath "choco" -ArgumentList $arguments -Wait -PassThru).ExitCode return (Start-Process -FilePath "choco" -ArgumentList $arguments -Wait -PassThru).ExitCode
} }
function Check-UpgradeNeeded { function Test-UpgradeNeeded {
<# <#
.SYNOPSIS .SYNOPSIS
Checks if an upgrade is needed for a Chocolatey package based on the content of a log file. Checks if an upgrade is needed for a Chocolatey package based on the content of a log file.
@ -83,7 +83,7 @@ function Install-WinUtilProgramChoco {
True if the log file indicates that an upgrade is needed; otherwise, false. True if the log file indicates that an upgrade is needed; otherwise, false.
.EXAMPLE .EXAMPLE
$isUpgradeNeeded = Check-UpgradeNeeded -filePath "C:\temp\install-output.txt" $isUpgradeNeeded = Test-UpgradeNeeded -filePath "C:\temp\install-output.txt"
#> #>
param ($filePath) param ($filePath)
@ -149,11 +149,11 @@ function Install-WinUtilProgramChoco {
Write-Host "Starting installation of $Program with Chocolatey." Write-Host "Starting installation of $Program with Chocolatey."
try { try {
$installStatusCode = Run-ChocoCommand "install $Program -y --log-file $installOutputFile" $installStatusCode = Invoke-ChocoCommand "install $Program -y --log-file $installOutputFile"
if ($installStatusCode -eq 0) { if ($installStatusCode -eq 0) {
if (Check-UpgradeNeeded $installOutputFile) { if (Test-UpgradeNeeded $installOutputFile) {
$upgradeStatusCode = Run-ChocoCommand "upgrade $Program -y" $upgradeStatusCode = Invoke-ChocoCommand "upgrade $Program -y"
Write-Host "$Program was" $(if ($upgradeStatusCode -eq 0) { "upgraded successfully." } else { "not upgraded." }) Write-Host "$Program was" $(if ($upgradeStatusCode -eq 0) { "upgraded successfully." } else { "not upgraded." })
} }
else { else {
@ -207,7 +207,7 @@ function Install-WinUtilProgramChoco {
if ($chocoPackages) { if ($chocoPackages) {
Write-Host "Starting uninstallation of $chocoPackages with Chocolatey." Write-Host "Starting uninstallation of $chocoPackages with Chocolatey."
try { try {
$uninstallStatusCode = Run-ChocoCommand "uninstall $chocoPackages -y" $uninstallStatusCode = Invoke-ChocoCommand "uninstall $chocoPackages -y"
Write-Host "$Program" $(if ($uninstallStatusCode -eq 0) { "uninstalled successfully." } else { "failed to uninstall." }) Write-Host "$Program" $(if ($uninstallStatusCode -eq 0) { "uninstalled successfully." } else { "failed to uninstall." })
} }
catch { catch {

View File

@ -33,36 +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
Write-Host "Downloading Winget Prerequsites`n"
Get-WinUtilWingetPrerequisites
Write-Host "Downloading Winget and License File`r"
Get-WinUtilWingetLatest
Write-Host "Installing Winget w/ Prerequsites`r"
Add-AppxProvisionedPackage -Online -PackagePath $ENV:TEMP\Microsoft.DesktopAppInstaller.msixbundle -DependencyPackagePath $ENV:TEMP\Microsoft.VCLibs.x64.Desktop.appx, $ENV:TEMP\Microsoft.UI.Xaml.x64.appx -LicensePath $ENV:TEMP\License1.xml
Write-Host "Manually adding Winget Sources, from Winget CDN."
Add-AppxPackage -Path https://cdn.winget.microsoft.com/cache/source.msix #Seems some installs of Winget don't add the repo source, this should makes sure that it's installed every time.
Write-Host "Winget Installed" -ForegroundColor Green
Write-Host "Enabling NuGet and Module..."
Install-PackageProvider -Name NuGet -Force
Install-Module -Name Microsoft.WinGet.Client -Force
# Winget only needs a refresh of the environment variables to be used.
Write-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
} catch {
Write-Host "Failure detected while installing via GitHub method. Continuing with Chocolatey method as fallback." -ForegroundColor Red
# In case install fails via GitHub method.
try { try {
# Install Choco if not already present $wingetCmd = Get-Command winget -ErrorAction Stop
Install-WinUtilChoco Write-Information "Attempting to update WinGet using WinGet..."
Start-Process -Verb runas -FilePath powershell.exe -ArgumentList "choco install winget-cli" $result = Start-Process -FilePath "`"$($wingetCmd.Source)`"" -ArgumentList "install -e --accept-source-agreements --accept-package-agreements Microsoft.AppInstaller" -Wait -NoNewWindow -PassThru
Write-Host "Winget Installed" -ForegroundColor Green if ($result.ExitCode -ne 0) {
Write-Output "Refreshing Environment Variables...`n" throw "WinGet update failed with exit code: $($result.ExitCode)"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") }
Write-Output "Refreshing Environment Variables...`n"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
return
} catch { } catch {
throw [WingetFailedInstall]::new('Failed to install!') Write-Information "WinGet not found or update failed. Attempting to install from Microsoft Store..."
} }
} try {
Write-Host "Attempting to repair WinGet using Repair-WinGetPackageManager..." -ForegroundColor Yellow
# 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"
$ENV:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
return
} catch {
Write-Error "All installation methods failed. Unable to install WinGet."
throw
}
} catch {
Write-Error "An error occurred during WinGet installation: $_"
throw
}
} }

View File

@ -1,30 +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
}
}

View File

@ -43,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 {

View File

@ -1,37 +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
Invoke-WinUtilExplorerRefresh
# Update Winutil Theme if the Theme Button shows the Icon for Auto
if ($sync.ThemeButton.Content -eq [char]0xF08C) {
Invoke-WinutilThemeChange -theme "Auto"
}
} 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
}
}

View File

@ -1,34 +0,0 @@
Function Invoke-WinUtilDetailedBSoD {
<#
.SYNOPSIS
Enables/Disables Detailed BSoD
(Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name 'DisplayParameters').DisplayParameters
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Detailed BSoD"
$value = 1
} else {
Write-Host "Disabling Detailed BSoD"
$value =0
}
$Path = "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl"
$dwords = ("DisplayParameters", "DisableEmoticon")
foreach ($name in $dwords) {
Set-ItemProperty -Path $Path -Name $name -Value $value
}
Set-ItemProperty -Path $Path -Name DisplayParameters -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
}
}

View File

@ -1,33 +0,0 @@
function Invoke-WinUtilExplorerRefresh {
<#
.SYNOPSIS
Refreshes the Windows Explorer
#>
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))
}
}

View 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"
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilHiddenFiles {
<#
.SYNOPSIS
Enable/Disable Hidden Files
.PARAMETER Enabled
Indicates whether to enable or disable Hidden Files
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Hidden Files"
$value = 1
} else {
Write-Host "Disabling Hidden Files"
$value = 0
}
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Set-ItemProperty -Path $Path -Name Hidden -Value $value
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -0,0 +1,103 @@
function Invoke-WinUtilInstallPSProfile {
<#
.SYNOPSIS
Backs up your original profile then installs and applies the CTT PowerShell profile.
#>
Invoke-WPFRunspace -ArgumentList $PROFILE -DebugPreference $DebugPreference -ScriptBlock {
# Remap the automatic built-in $PROFILE variable to the parameter named $PSProfile.
param ($PSProfile)
function Invoke-PSSetup {
# Define the URL used to download Chris Titus Tech's PowerShell profile.
$url = "https://raw.githubusercontent.com/ChrisTitusTech/powershell-profile/main/Microsoft.PowerShell_profile.ps1"
# Get the file hash for the user's current PowerShell profile.
$OldHash = Get-FileHash $PSProfile -ErrorAction SilentlyContinue
# Download Chris Titus Tech's PowerShell profile to the 'TEMP' folder.
Invoke-RestMethod $url -OutFile "$env:TEMP/Microsoft.PowerShell_profile.ps1"
# Get the file hash for Chris Titus Tech's PowerShell profile.
$NewHash = Get-FileHash "$env:TEMP/Microsoft.PowerShell_profile.ps1"
# Store the file hash of Chris Titus Tech's PowerShell profile.
if (!(Test-Path "$PSProfile.hash")) {
$NewHash.Hash | Out-File "$PSProfile.hash"
}
# Check if the new profile's hash doesn't match the old profile's hash.
if ($NewHash.Hash -ne $OldHash.Hash) {
# Check if oldprofile.ps1 exists and use it as a profile backup source.
if (Test-Path "$env:USERPROFILE\oldprofile.ps1") {
Write-Host "===> Backup File Exists... <===" -ForegroundColor Yellow
Write-Host "===> Moving Backup File... <===" -ForegroundColor Yellow
Copy-Item "$env:USERPROFILE\oldprofile.ps1" "$PSProfile.bak"
Write-Host "===> Profile Backup: Done. <===" -ForegroundColor Yellow
} else {
# If oldprofile.ps1 does not exist use $PSProfile as a profile backup source.
# Check if the profile backup file has not already been created on the disk.
if ((Test-Path $PSProfile) -and (-not (Test-Path "$PSProfile.bak"))) {
# Let the user know their PowerShell profile is being backed up.
Write-Host "===> Backing Up Profile... <===" -ForegroundColor Yellow
# Copy the user's current PowerShell profile to the backup file path.
Copy-Item -Path $PSProfile -Destination "$PSProfile.bak"
# Let the user know the profile backup has been completed successfully.
Write-Host "===> Profile Backup: Done. <===" -ForegroundColor Yellow
}
}
# Let the user know Chris Titus Tech's PowerShell profile is being installed.
Write-Host "===> Installing Profile... <===" -ForegroundColor Yellow
# Start a new hidden PowerShell instance because setup.ps1 does not work in runspaces.
Start-Process -FilePath "pwsh" -ArgumentList "-ExecutionPolicy Bypass -NoProfile -Command `"Invoke-Expression (Invoke-WebRequest `'https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1`')`"" -WindowStyle Hidden -Wait
# Let the user know Chris Titus Tech's PowerShell profile has been installed successfully.
Write-Host "Profile has been installed. Please restart your shell to reflect the changes!" -ForegroundColor Magenta
# Let the user know Chris Titus Tech's PowerShell profile has been setup successfully.
Write-Host "===> Finished Profile Setup <===" -ForegroundColor Yellow
} else {
# Let the user know Chris Titus Tech's PowerShell profile is already fully up-to-date.
Write-Host "Profile is up to date" -ForegroundColor Magenta
}
}
# Check if PowerShell Core is currently installed as a program and is available as a command.
if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
# Check if the version of PowerShell Core currently in use is version 7 or higher.
if ($PSVersionTable.PSVersion.Major -ge 7) {
# Invoke the PowerShell Profile setup script to install Chris Titus Tech's PowerShell Profile.
Invoke-PSSetup
} else {
# Let the user know that PowerShell 7 is installed but is not currently in use.
Write-Host "This profile requires Powershell 7, which is currently installed but not used!" -ForegroundColor Red
# Load the necessary .NET library required to use Windows Forms to show dialog boxes.
Add-Type -AssemblyName System.Windows.Forms
# Display the message box asking if the user wants to install PowerShell 7 or not.
$question = [System.Windows.Forms.MessageBox]::Show(
"Profile requires Powershell 7, which is currently installed but not used! Do you want to install the profile for Powershell 7?",
"Question",
[System.Windows.Forms.MessageBoxButtons]::YesNo,
[System.Windows.Forms.MessageBoxIcon]::Question
)
# Proceed with the installation and setup of the profile as the user pressed the 'Yes' button.
if ($question -eq [System.Windows.Forms.DialogResult]::Yes) {
Invoke-PSSetup
} else {
# Let the user know the setup of the profile will not proceed as they pressed the 'No' button.
Write-Host "Not proceeding with the profile setup!" -ForegroundColor Magenta
}
}
} else {
# Let the user know that the profile requires PowerShell Core but it is not currently installed.
Write-Host "This profile requires Powershell Core, which is currently not installed!" -ForegroundColor Red
}
}
}

View File

@ -1,858 +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, position=0)]
[string]$imgVersion,
[Parameter(Mandatory, position=1)]
[Version]$desiredVersion
)
try {
$version = [Version]$imgVersion
return $version -ge $desiredVersion
} catch {
return $False
}
}
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
}
}
function Get-FidoLangFromCulture {
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" }
}
}
function Remove-Features() {
<#
.SYNOPSIS
Removes certain features from ISO image
.PARAMETER Name
No Params
.EXAMPLE
Remove-Features
#>
try {
$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"
}
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
}
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. MicroWin processing will continue, but features will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
}
}
function Remove-Packages {
try {
$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 "*DirectPlay*" -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*" -AND
$_ -NotLike "*Ethernet*" -AND
$_ -NotLike "*Wifi*" -AND
$_ -NotLike "*FodMetadata*" -AND
$_ -NotLike "*Foundation*" -AND
$_ -NotLike "*LanguageFeatures*" -AND
$_ -NotLike "*VBSCRIPT*" -AND
$_ -NotLike "*License*"
}
$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
}
}
Write-Progress -Activity "Removing Packages" -Status "Ready" -Completed
if ($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. MicroWin processing will continue, but packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
}
}
function Remove-ProvisionedPackages() {
<#
.SYNOPSIS
Removes AppX packages from a Windows image during MicroWin processing
.PARAMETER Name
No Params
.EXAMPLE
Remove-ProvisionedPackages
#>
try
{
$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*"
}
$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
}
catch
{
# This can happen if getting AppX packages fails
Write-Host "Unable to get information about the AppX packages. MicroWin processing will continue, but AppX packages will not be processed"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
}
}
function Get-LocalizedUsers
{
<#
.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
Get-LocalizedUsers -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
}
}
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."
$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 {
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&gt;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>true</PlainText>
</Password>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<AutoLogon>
<Username>USER-REPLACEME</Username>
<Enabled>true</Enabled>
<LogonCount>1</LogonCount>
<Password>
<Value>PW-REPLACEME</Value>
<PlainText>true</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&gt;c:\windows\csup.txt</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>CMD /C echo GG&gt;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>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\remove-packages.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>
'@
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()
}
# Replace default User and Password values with the provided parameters
$unattend = $unattend.Replace("USER-REPLACEME", $userName).Trim()
$unattend = $unattend.Replace("PW-REPLACEME", $userPassword).Trim()
# Save unattended answer file with UTF-8 encoding
$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 "%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
}
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."
}
}
"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"
# ************************************************
# 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 "$env:HOMEDRIVE\Windows\cttlogo.png") {
$shortcut.IconLocation = "$env:HOMEDRIVE\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
# ************************************************
try
{
if ((Get-WindowsOptionalFeature -Online | Where-Object { $_.FeatureName -like "Recall" }).Count -gt 0)
{
Disable-WindowsOptionalFeature -Online -FeatureName "Recall" -Remove
}
}
catch
{
}
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}

View File

@ -1,38 +0,0 @@
Function Invoke-WinUtilMouseAcceleration {
<#
.SYNOPSIS
Enables/Disables Mouse Acceleration
.PARAMETER DarkMoveEnabled
Indicates the current Mouse Acceleration State
#>
Param($MouseAccelerationEnabled)
try {
if ($MouseAccelerationEnabled -eq $false) {
Write-Host "Enabling Mouse Acceleration"
$MouseSpeed = 1
$MouseThreshold1 = 6
$MouseThreshold2 = 10
} else {
Write-Host "Disabling Mouse Acceleration"
$MouseSpeed = 0
$MouseThreshold1 = 0
$MouseThreshold2 = 0
}
$Path = "HKCU:\Control Panel\Mouse"
Set-ItemProperty -Path $Path -Name MouseSpeed -Value $MouseSpeed
Set-ItemProperty -Path $Path -Name MouseThreshold1 -Value $MouseThreshold1
Set-ItemProperty -Path $Path -Name MouseThreshold2 -Value $MouseThreshold2
} 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
}
}

View File

@ -1,31 +0,0 @@
function Invoke-WinUtilNumLock {
<#
.SYNOPSIS
Disables/Enables NumLock on startup
.PARAMETER Enabled
Indicates whether to enable or disable Numlock on startup
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Numlock on startup"
$value = 2
} else {
Write-Host "Disabling Numlock on startup"
$value = 0
}
New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS
$HKUPath = "HKU:\.Default\Control Panel\Keyboard"
$HKCUPath = "HKCU:\Control Panel\Keyboard"
Set-ItemProperty -Path $HKUPath -Name InitialKeyboardIndicators -Value $value
Set-ItemProperty -Path $HKCUPath -Name InitialKeyboardIndicators -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
}
}

View File

@ -1,27 +0,0 @@
function Invoke-WinUtilShowExt {
<#
.SYNOPSIS
Disables/Enables Show file Extentions
.PARAMETER Enabled
Indicates whether to enable or disable Show file extentions
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Showing file extentions"
$value = 0
} else {
Write-Host "hiding file extensions"
$value = 1
}
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Set-ItemProperty -Path $Path -Name HideFileExt -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
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilSnapFlyout {
<#
.SYNOPSIS
Disables/Enables Snap Assist Flyout on startup
.PARAMETER Enabled
Indicates whether to enable or disable Snap Assist Flyout on startup
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Snap Assist Flyout On startup"
$value = 1
} else {
Write-Host "Disabling Snap Assist Flyout On startup"
$value = 0
}
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
taskkill.exe /F /IM "explorer.exe"
Set-ItemProperty -Path $Path -Name EnableSnapAssistFlyout -Value $value
Start-Process "explorer.exe"
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilSnapSuggestion {
<#
.SYNOPSIS
Disables/Enables Snap Assist Suggestions on startup
.PARAMETER Enabled
Indicates whether to enable or disable Snap Assist Suggestions on startup
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Snap Assist Suggestion On startup"
$value = 1
} else {
Write-Host "Disabling Snap Assist Suggestion On startup"
$value = 0
}
# taskkill.exe /F /IM "explorer.exe"
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
taskkill.exe /F /IM "explorer.exe"
Set-ItemProperty -Path $Path -Name SnapAssist -Value $value
Start-Process "explorer.exe"
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -1,27 +0,0 @@
function Invoke-WinUtilSnapWindow {
<#
.SYNOPSIS
Disables/Enables Snapping Windows on startup
.PARAMETER Enabled
Indicates whether to enable or disable Snapping Windows on startup
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Snap Windows On startup | Relogin Required"
$value = 1
} else {
Write-Host "Disabling Snap Windows On startup | Relogin Required"
$value = 0
}
$Path = "HKCU:\Control Panel\Desktop"
Set-ItemProperty -Path $Path -Name WindowArrangementActive -Value $value
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -1,27 +0,0 @@
Function Invoke-WinUtilStickyKeys {
<#
.SYNOPSIS
Disables/Enables Sticky Keyss on startup
.PARAMETER Enabled
Indicates whether to enable or disable Sticky Keys on startup
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Sticky Keys On startup"
$value = 510
} else {
Write-Host "Disabling Sticky Keys On startup"
$value = 58
}
$Path = "HKCU:\Control Panel\Accessibility\StickyKeys"
Set-ItemProperty -Path $Path -Name Flags -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
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilTaskView {
<#
.SYNOPSIS
Enable/Disable Task View
.PARAMETER Enabled
Indicates whether to enable or disable Task View
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Task View"
$value = 1
} else {
Write-Host "Disabling Task View"
$value = 0
}
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Set-ItemProperty -Path $Path -Name ShowTaskViewButton -Value $value
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilTaskbarAlignment {
<#
.SYNOPSIS
Switches between Center & Left Taskbar Alignment
.PARAMETER Enabled
Indicates whether to make Taskbar Alignment Center or Left
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Making Taskbar Alignment to the Center"
$value = 1
} else {
Write-Host "Making Taskbar Alignment to the Left"
$value = 0
}
$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Set-ItemProperty -Path $Path -Name "TaskbarAl" -Value $value
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilTaskbarSearch {
<#
.SYNOPSIS
Enable/Disable Taskbar Search Button.
.PARAMETER Enabled
Indicates whether to enable or disable Taskbar Search Button.
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Search Button"
$value = 1
} else {
Write-Host "Disabling Search Button"
$value = 0
}
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search\"
Set-ItemProperty -Path $Path -Name SearchboxTaskbarMode -Value $value
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -1,30 +0,0 @@
function Invoke-WinUtilTaskbarWidgets {
<#
.SYNOPSIS
Enable/Disable Taskbar Widgets
.PARAMETER Enabled
Indicates whether to enable or disable Taskbar Widgets
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Taskbar Widgets"
$value = 1
} else {
Write-Host "Disabling Taskbar Widgets"
$value = 0
}
$Path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"
Set-ItemProperty -Path $Path -Name TaskbarDa -Value $value
} catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord
} catch {
Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace
}
}

View File

@ -21,6 +21,10 @@ function Invoke-WinUtilTweaks {
$KeepServiceStartup = $true $KeepServiceStartup = $true
) )
if ($Checkbox -contains "Toggle") {
$CheckBox = $sync.configs.tweaks.$CheckBox
}
Write-Debug "Tweaks: $($CheckBox)" Write-Debug "Tweaks: $($CheckBox)"
if($undo) { if($undo) {
$Values = @{ $Values = @{
@ -73,6 +77,14 @@ function Invoke-WinUtilTweaks {
if($sync.configs.tweaks.$CheckBox.registry) { if($sync.configs.tweaks.$CheckBox.registry) {
$sync.configs.tweaks.$CheckBox.registry | ForEach-Object { $sync.configs.tweaks.$CheckBox.registry | ForEach-Object {
Write-Debug "$($psitem.Name) and state is $($psitem.$($values.registry))" Write-Debug "$($psitem.Name) and state is $($psitem.$($values.registry))"
if (($psitem.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"
}
}
Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry) Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry)
} }
} }

View File

@ -0,0 +1,231 @@
function Invoke-WinUtilUninstallPSProfile {
<#
.SYNOPSIS
# Uninstalls the CTT PowerShell profile then restores the original profile.
#>
Invoke-WPFRunspace -ArgumentList $PROFILE -DebugPreference $DebugPreference -ScriptBlock {
# Remap the automatic built-in $PROFILE variable to the parameter named $PSProfile.
param ($PSProfile)
# Helper function used to uninstall a specific Nerd Fonts font package.
function Uninstall-NerdFonts {
# Define the parameters block for the Uninstall-NerdFonts function.
param (
[string]$FontsPath = "$env:LOCALAPPDATA\Microsoft\Windows\Fonts",
[string]$FontFamilyName = "CaskaydiaCoveNerdFont"
)
# Get the list of installed fonts as specified by the FontFamilyName parameter.
$Fonts = Get-ChildItem $FontsPath -Recurse -Filter "*.ttf" | Where-Object { $_.Name -match $FontFamilyName }
# Check if the specified fonts are currently installed on the system.
if ($Fonts) {
# Let the user know that the Nerd Fonts are currently being uninstalled.
Write-Host "===> Uninstalling: Nerd Fonts... <===" -ForegroundColor Yellow
# Loop over the font files and remove each installed font file one-by-one.
$Fonts | ForEach-Object {
# Check if the font file exists on the disk before attempting to remove it.
if (Test-Path "$($_.FullName)") {
# Remove the found font files from the disk; uninstalling the font.
Remove-Item "$($_.FullName)"
}
}
}
# Let the user know that the Nerd Fonts package has been uninstalled from the system.
if (-not $Fonts) {
Write-Host "===> Successfully Uninstalled: Nerd Fonts. <===" -ForegroundColor Yellow
}
}
# Helper function used to uninstall a specific Nerd Fonts font corresponding registry keys.
function Uninstall-NerdFontRegKeys {
# Define the parameters block for the Uninstall-NerdFontsRegKey function.
param (
[string]$FontsRegPath = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts",
[string]$FontFamilyName = "CaskaydiaCove"
)
try {
# Get all properties (font registrations) from the registry path
$registryProperties = Get-ItemProperty -Path $FontsRegPath
# Filter and remove properties that match the font family name
$registryProperties.PSObject.Properties |
Where-Object { $_.Name -match $FontFamilyName } |
ForEach-Object {
If ($_.Name -like "*$FontFamilyName*") {
Remove-ItemProperty -path $FontsRegPath -Name $_.Name -ErrorAction SilentlyContinue
}
}
} catch {
Write-Host "Error removing registry keys: $($_.exception.message)" -ForegroundColor Red
}
}
# Check if Chris Titus Tech's PowerShell profile is currently available in the PowerShell profile folder.
if (Test-Path $PSProfile -PathType Leaf) {
# Set the GitHub repo path used for looking up the name of Chris Titus Tech's powershell-profile repo.
$GitHubRepoPath = "ChrisTitusTech/powershell-profile"
# Get the unique identifier used to test for the presence of Chris Titus Tech's PowerShell profile.
$PSProfileIdentifier = (Invoke-RestMethod "https://api.github.com/repos/$GitHubRepoPath").full_name
# Check if Chris Titus Tech's PowerShell profile is currently installed in the PowerShell profile folder.
if ((Get-Content $PSProfile) -match $PSProfileIdentifier) {
# Attempt to uninstall Chris Titus Tech's PowerShell profile from the PowerShell profile folder.
try {
# Get the content of the backup PowerShell profile and store it in-memory.
$PSProfileContent = Get-Content "$PSProfile.bak"
# Store the flag used to check if OhMyPosh is in use by the backup PowerShell profile.
$OhMyPoshInUse = $PSProfileContent -match "oh-my-posh init"
# Check if OhMyPosh is not currently in use by the backup PowerShell profile.
if (-not $OhMyPoshInUse) {
# If OhMyPosh is currently installed attempt to uninstall it from the system.
if (Get-Command oh-my-posh -ErrorAction SilentlyContinue) {
# Let the user know that OhMyPosh is currently being uninstalled from their system.
Write-Host "===> Uninstalling: OhMyPosh... <===" -ForegroundColor Yellow
# Attempt to uninstall OhMyPosh from the system with the WinGet package manager.
winget uninstall -e --id JanDeDobbeleer.OhMyPosh
}
} else {
# Let the user know that the uninstallation of OhMyPosh has been skipped because it is in use.
Write-Host "===> Skipped Uninstall: OhMyPosh In-Use. <===" -ForegroundColor Yellow
}
} catch {
# Let the user know that an error was encountered when uninstalling OhMyPosh.
Write-Host "Failed to uninstall OhMyPosh. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the specified Nerd Fonts package from the system.
try {
# Specify the directory that the specified font package will be uninstalled from.
[string]$FontsPath = "$env:LOCALAPPDATA\Microsoft\Windows\Fonts"
# Specify the name of the font package that is to be uninstalled from the system.
[string]$FontFamilyName = "CaskaydiaCoveNerdFont"
# Call the function used to uninstall the specified Nerd Fonts package from the system.
Uninstall-NerdFonts -FontsPath $FontsPath -FontFamilyName $FontFamilyName
} catch {
# Let the user know that an error was encountered when uninstalling Nerd Fonts.
Write-Host "Failed to uninstall Nerd Fonts. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the specified Nerd Fonts registry keys from the system.
try {
# Specify the registry path that the specified font registry keys will be uninstalled from.
[string]$FontsRegPath = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
# Specify the name of the font registry keys that is to be uninstalled from the system.
[string]$FontFamilyName = "CaskaydiaCove"
# Call the function used to uninstall the specified Nerd Fonts registry keys from the system.
Uninstall-NerdFontRegKeys -FontsPath $FontsRegPath -FontFamilyName $FontFamilyName
} catch {
# Let the user know that an error was encountered when uninstalling Nerd Font registry keys.
Write-Host "Failed to uninstall Nerd Font Registry Keys. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the Terminal-Icons PowerShell module from the system.
try {
# Get the content of the backup PowerShell profile and store it in-memory.
$PSProfileContent = Get-Content "$PSProfile.bak"
# Store the flag used to check if Terminal-Icons is in use by the backup PowerShell profile.
$TerminalIconsInUse = $PSProfileContent -match "Import-Module" -and $PSProfileContent -match "Terminal-Icons"
# Check if Terminal-Icons is not currently in use by the backup PowerShell profile.
if (-not $TerminalIconsInUse) {
# If Terminal-Icons is currently installed attempt to uninstall it from the system.
if (Get-Module -ListAvailable Terminal-Icons) {
# Let the user know that Terminal-Icons is currently being uninstalled from their system.
Write-Host "===> Uninstalling: Terminal-Icons... <===" -ForegroundColor Yellow
# Attempt to uninstall Terminal-Icons from the system with Uninstall-Module.
Uninstall-Module -Name Terminal-Icons
}
} else {
# Let the user know that the uninstallation of Terminal-Icons has been skipped because it is in use.
Write-Host "===> Skipped Uninstall: Terminal-Icons In-Use. <===" -ForegroundColor Yellow
}
} catch {
# Let the user know that an error was encountered when uninstalling Terminal-Icons.
Write-Host "Failed to uninstall Terminal-Icons. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the Zoxide application from the system.
try {
# Get the content of the backup PowerShell profile and store it in-memory.
$PSProfileContent = Get-Content "$PSProfile.bak"
# Store the flag used to check if Zoxide is in use by the backup PowerShell profile.
$ZoxideInUse = $PSProfileContent -match "zoxide init"
# Check if Zoxide is not currently in use by the backup PowerShell profile.
if (-not $ZoxideInUse) {
# If Zoxide is currently installed attempt to uninstall it from the system.
if (Get-Command zoxide -ErrorAction SilentlyContinue) {
# Let the user know that Zoxide is currently being uninstalled from their system.
Write-Host "===> Uninstalling: Zoxide... <===" -ForegroundColor Yellow
# Attempt to uninstall Zoxide from the system with the WinGet package manager.
winget uninstall -e --id ajeetdsouza.zoxide
}
} else {
# Let the user know that the uninstallation of Zoxide been skipped because it is in use.
Write-Host "===> Skipped Uninstall: Zoxide In-Use. <===" -ForegroundColor Yellow
}
} catch {
# Let the user know that an error was encountered when uninstalling Zoxide.
Write-Host "Failed to uninstall Zoxide. Error: $_" -ForegroundColor Red
}
# Attempt to uninstall the CTT PowerShell profile from the system.
try {
# Try and remove the CTT PowerShell Profile file from the disk with Remove-Item.
Remove-Item $PSProfile
# Let the user know that the CTT PowerShell profile has been uninstalled from the system.
Write-Host "Profile has been uninstalled. Please restart your shell to reflect the changes!" -ForegroundColor Magenta
} catch {
# Let the user know that an error was encountered when uninstalling the profile.
Write-Host "Failed to uninstall profile. Error: $_" -ForegroundColor Red
}
# Attempt to move the user's original PowerShell profile backup back to its original location.
try {
# Check if the backup PowerShell profile exists before attempting to restore the backup.
if (Test-Path "$PSProfile.bak") {
# Restore the backup PowerShell profile and move it to its original location.
Move-Item "$PSProfile.bak" $PSProfile
# Let the user know that their PowerShell profile backup has been successfully restored.
Write-Host "===> Restored Profile Backup. <===" -ForegroundColor Yellow
}
} catch {
# Let the user know that an error was encountered when restoring the profile backup.
Write-Host "Failed to restore profile backup. Error: $_" -ForegroundColor Red
}
# Silently cleanup the oldprofile.ps1 file that was created when the CTT PowerShell profile was installed.
Remove-Item "$env:USERPROFILE\oldprofile.ps1" | Out-Null
} else {
# Let the user know that the CTT PowerShell profile is not installed and that the uninstallation was skipped.
Write-Host "===> Chris Titus Tech's PowerShell Profile Not Found. Skipped Uninstallation. <===" -ForegroundColor Magenta
}
} else {
# Let the user know that no PowerShell profile was found and that the uninstallation was skipped.
Write-Host "===> No PowerShell Profile Found. Skipped Uninstallation. <===" -ForegroundColor Magenta
}
}
}

View File

@ -1,27 +0,0 @@
function Invoke-WinUtilVerboseLogon {
<#
.SYNOPSIS
Disables/Enables VerboseLogon Messages
.PARAMETER Enabled
Indicates whether to enable or disable VerboseLogon messages
#>
Param($Enabled)
try {
if ($Enabled -eq $false) {
Write-Host "Enabling Verbose Logon Messages"
$value = 1
} else {
Write-Host "Disabling Verbose Logon Messages"
$value = 0
}
$Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
Set-ItemProperty -Path $Path -Name VerboseStatus -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
}
}

View File

@ -1,50 +0,0 @@
function Invoke-WinUtilpsProfile {
<#
.SYNOPSIS
Installs & applies the CTT Powershell Profile
#>
Invoke-WPFRunspace -Argumentlist $PROFILE -DebugPreference $DebugPreference -ScriptBlock {
param ( $psprofile)
function Invoke-PSSetup {
$url = "https://raw.githubusercontent.com/ChrisTitusTech/powershell-profile/main/Microsoft.PowerShell_profile.ps1"
$oldhash = Get-FileHash $psprofile -ErrorAction SilentlyContinue
Invoke-RestMethod $url -OutFile "$env:temp/Microsoft.PowerShell_profile.ps1"
$newhash = Get-FileHash "$env:temp/Microsoft.PowerShell_profile.ps1"
if ($newhash.Hash -ne $oldhash.Hash) {
write-host "===> Installing Profile.. <===" -ForegroundColor Yellow
# Starting new hidden shell process bc setup does not work in a runspace
Start-Process -FilePath "pwsh" -ArgumentList "-ExecutionPolicy Bypass -NoProfile -Command `"Invoke-Expression (Invoke-WebRequest `'https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1`')`"" -WindowStyle Hidden -Wait
Write-Host "Profile has been installed. Please restart your shell to reflect changes!" -ForegroundColor Magenta
write-host "===> Finished <===" -ForegroundColor Yellow
} else {
Write-Host "Profile is up to date" -ForegroundColor Green
}
}
if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
if ($PSVersionTable.PSVersion.Major -ge 7) {
Invoke-PSSetup
}
else {
write-host "Profile requires Powershell 7, which is currently installed but not used!" -ForegroundColor Red
# Load the necessary assembly for Windows Forms
Add-Type -AssemblyName System.Windows.Forms
# Display the Yes/No message box
$question = [System.Windows.Forms.MessageBox]::Show("Profile requires Powershell 7, which is currently installed but not used! Do you want to install Profile for Powershell 7?", "Question",
[System.Windows.Forms.MessageBoxButtons]::YesNo,
[System.Windows.Forms.MessageBoxIcon]::Question)
# Check the result
if ($question -eq [System.Windows.Forms.DialogResult]::Yes) {
Invoke-PSSetup
}
else {
Write-Host "Not proceeding with the profile setup!"
}
}
}
else {
write-host "Profile requires Powershell 7, which is not installed!" -ForegroundColor Red
}
}
}

View File

@ -0,0 +1,43 @@
function Set-PackageManagerPreference {
<#
.SYNOPSIS
Sets the currently selected package manager to global "ManagerPreference" in sync.
Also persists preference across Winutil restarts via preference.ini.
Reads from preference.ini if no argument sent.
.PARAMETER preferedPackageManager
The PackageManager that was selected.
#>
param(
[Parameter(Position=0, Mandatory=$false)]
[PackageManagers]$preferedPackageManager
)
$preferencePath = "$env:LOCALAPPDATA\winutil\preferences.ini"
$oldChocoPath = "$env:LOCALAPPDATA\winutil\preferChocolatey.ini"
#Try loading from file if no argument given.
if ($null -eq $preferedPackageManager) {
# Backwards compat for preferChocolatey.ini
if (Test-Path -Path $oldChocoPath) {
$preferedPackageManager = [PackageManagers]::Choco
Remove-Item -Path $oldChocoPath
}
elseif (Test-Path -Path $preferencePath) {
$potential = Get-Content -Path $preferencePath -TotalCount 1
$preferedPackageManager = [PackageManagers]$potential
}
else {
Write-Debug "Creating new preference file, defaulting to winget."
$preferedPackageManager = [PackageManagers]::Winget
}
}
$sync["ManagerPreference"] = [PackageManagers]::$preferedPackageManager
Write-Debug "Manager Preference changed to '$($sync["ManagerPreference"])'"
# Write preference to file to persist across restarts.
Out-File -FilePath $preferencePath -InputObject $sync["ManagerPreference"]
}

View File

@ -35,17 +35,20 @@ function Set-WinUtilRegistry {
New-Item -Path $Path -Force -ErrorAction Stop | Out-Null New-Item -Path $Path -Force -ErrorAction Stop | Out-Null
} }
Write-Host "Set $Path\$Name to $Value"
if ($Value -ne "<RemoveEntry>") { if ($Value -ne "<RemoveEntry>") {
Write-Host "Set $Path\$Name to $Value"
Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null
} }
else{ else{
Write-Host "Remove $Path\$Name"
Remove-ItemProperty -Path $Path -Name $Name -Force -ErrorAction Stop | Out-Null Remove-ItemProperty -Path $Path -Name $Name -Force -ErrorAction Stop | Out-Null
} }
} catch [System.Security.SecurityException] { } catch [System.Security.SecurityException] {
Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception" Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception"
} catch [System.Management.Automation.ItemNotFoundException] { } catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning $psitem.Exception.ErrorRecord Write-Warning $psitem.Exception.ErrorRecord
} catch [System.UnauthorizedAccessException] {
Write-Warning $psitem.Exception.Message
} catch { } catch {
Write-Warning "Unable to set $Name due to unhandled exception" Write-Warning "Unable to set $Name due to unhandled exception"
Write-Warning $psitem.Exception.StackTrace Write-Warning $psitem.Exception.StackTrace

View File

@ -6,6 +6,9 @@ function Show-CustomDialog {
.DESCRIPTION .DESCRIPTION
This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background. This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background.
.PARAMETER Title
The Title to use for the dialog window's Title Bar, this will not be visible by the user, as window styling is set to None.
.PARAMETER Message .PARAMETER Message
The message to be displayed in the dialog box. The message to be displayed in the dialog box.
@ -16,60 +19,102 @@ function Show-CustomDialog {
The height of the custom dialog window. The height of the custom dialog window.
.PARAMETER FontSize .PARAMETER FontSize
The Font Size for text shown inside the custom dialog window. The Font Size of message shown inside custom dialog window.
.PARAMETER HeaderFontSize .PARAMETER HeaderFontSize
The Font Size for the Header of the custom dialog window. The Font Size for the Header of custom dialog window.
.PARAMETER IconSize .PARAMETER LogoSize
The Size to use for Icon inside the custom dialog window. The Size of the Logo used inside the custom dialog window.
.PARAMETER ForegroundColor
The Foreground Color of dialog window title & message.
.PARAMETER BackgroundColor
The Background Color of dialog window.
.PARAMETER BorderColor
The Color for dialog window border.
.PARAMETER ButtonBackgroundColor
The Background Color for Buttons in dialog window.
.PARAMETER ButtonForegroundColor
The Foreground Color for Buttons in dialog window.
.PARAMETER ShadowColor
The Color used when creating the Drop-down Shadow effect for dialog window.
.PARAMETER LogoColor
The Color of WinUtil Text found next to WinUtil's Logo inside dialog window.
.PARAMETER LinkForegroundColor
The Foreground Color for Links inside dialog window.
.PARAMETER LinkHoverForegroundColor
The Foreground Color for Links when the mouse pointer hovers over them inside dialog window.
.PARAMETER EnableScroll .PARAMETER EnableScroll
A flag indicating whether to enable scrolling if the content exceeds the window size. A flag indicating whether to enable scrolling if the content exceeds the window size.
.EXAMPLE .EXAMPLE
Show-CustomDialog -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200 Show-CustomDialog -Title "My Custom Dialog" -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200
Makes a new Custom Dialog with the title 'My Custom Dialog' and a message 'This is a custom dialog with a message and an image above.', with dimensions of 300 by 200 pixels.
Other styling options are grabbed from '$sync.Form.Resources' global variable.
.EXAMPLE
$foregroundColor = New-Object System.Windows.Media.SolidColorBrush("#0088e5")
$backgroundColor = New-Object System.Windows.Media.SolidColorBrush("#1e1e1e")
$linkForegroundColor = New-Object System.Windows.Media.SolidColorBrush("#0088e5")
$linkHoverForegroundColor = New-Object System.Windows.Media.SolidColorBrush("#005289")
Show-CustomDialog -Title "My Custom Dialog" -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200 -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor -LinkForegroundColor $linkForegroundColor -LinkHoverForegroundColor $linkHoverForegroundColor
Makes a new Custom Dialog with the title 'My Custom Dialog' and a message 'This is a custom dialog with a message and an image above.', with dimensions of 300 by 200 pixels, with a link foreground (and general foreground) colors of '#0088e5', background color of '#1e1e1e', and Link Color on Hover of '005289', all of which are in Hexadecimal (the '#' Symbol is required by SolidColorBrush Constructor).
Other styling options are grabbed from '$sync.Form.Resources' global variable.
#> #>
param( param(
[string]$Title,
[string]$Message, [string]$Message,
[int]$Width = $sync.Form.Resources.CustomDialogWidth, [int]$Width = $sync.Form.Resources.CustomDialogWidth,
[int]$Height = $sync.Form.Resources.CustomDialogHeight, [int]$Height = $sync.Form.Resources.CustomDialogHeight,
[System.Windows.Media.FontFamily]$FontFamily = $sync.Form.Resources.FontFamily,
[int]$FontSize = $sync.Form.Resources.CustomDialogFontSize, [int]$FontSize = $sync.Form.Resources.CustomDialogFontSize,
[int]$HeaderFontSize = $sync.Form.Resources.CustomDialogFontSizeHeader, [int]$HeaderFontSize = $sync.Form.Resources.CustomDialogFontSizeHeader,
[int]$IconSize = $sync.Form.Resources.CustomDialogLogoSize, [int]$LogoSize = $sync.Form.Resources.CustomDialogLogoSize,
[System.Windows.Media.Color]$ShadowColor = "#AAAAAAAA",
[System.Windows.Media.SolidColorBrush]$LogoColor = $sync.Form.Resources.LabelboxForegroundColor,
[System.Windows.Media.SolidColorBrush]$BorderColor = $sync.Form.Resources.BorderColor,
[System.Windows.Media.SolidColorBrush]$ForegroundColor = $sync.Form.Resources.MainForegroundColor,
[System.Windows.Media.SolidColorBrush]$BackgroundColor = $sync.Form.Resources.MainBackgroundColor,
[System.Windows.Media.SolidColorBrush]$ButtonForegroundColor = $sync.Form.Resources.ButtonInstallForegroundColor,
[System.Windows.Media.SolidColorBrush]$ButtonBackgroundColor = $sync.Form.Resources.ButtonInstallBackgroundColor,
[System.Windows.Media.SolidColorBrush]$LinkForegroundColor = $sync.Form.Resources.LinkForegroundColor,
[System.Windows.Media.SolidColorBrush]$LinkHoverForegroundColor = $sync.Form.Resources.LinkHoverForegroundColor,
[bool]$EnableScroll = $false [bool]$EnableScroll = $false
) )
Add-Type -AssemblyName PresentationFramework
# Define theme colors
$foregroundColor = $sync.Form.Resources.MainForegroundColor
$backgroundColor = $sync.Form.Resources.MainBackgroundColor
$font = New-Object Windows.Media.FontFamily("Consolas")
$borderColor = $sync.Form.Resources.BorderColor # ButtonInstallBackgroundColor
$buttonBackgroundColor = $sync.Form.Resources.ButtonInstallBackgroundColor
$buttonForegroundColor = $sync.Form.Resources.ButtonInstallForegroundColor
$shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA")
$logocolor = $sync.Form.Resources.LabelboxForegroundColor
# Create a custom dialog window # Create a custom dialog window
$dialog = New-Object Windows.Window $dialog = New-Object Windows.Window
$dialog.Title = "About" $dialog.Title = $Title
$dialog.Height = $Height $dialog.Height = $Height
$dialog.Width = $Width $dialog.Width = $Width
$dialog.Margin = New-Object Windows.Thickness(10) # Add margin to the entire dialog box $dialog.Margin = New-Object Windows.Thickness(10) # Add margin to the entire dialog box
$dialog.WindowStyle = [Windows.WindowStyle]::None # Remove title bar and window controls $dialog.WindowStyle = [Windows.WindowStyle]::None # Remove title bar and window controls
$dialog.ResizeMode = [Windows.ResizeMode]::NoResize # Disable resizing $dialog.ResizeMode = [Windows.ResizeMode]::NoResize # Disable resizing
$dialog.WindowStartupLocation = [Windows.WindowStartupLocation]::CenterScreen # Center the window $dialog.WindowStartupLocation = [Windows.WindowStartupLocation]::CenterScreen # Center the window
$dialog.Foreground = $foregroundColor $dialog.Foreground = $ForegroundColor
$dialog.Background = $backgroundColor $dialog.Background = $BackgroundColor
$dialog.FontFamily = $font $dialog.FontFamily = $FontFamily
$dialog.FontSize = $FontSize $dialog.FontSize = $FontSize
# Create a Border for the green edge with rounded corners # Create a Border for the green edge with rounded corners
$border = New-Object Windows.Controls.Border $border = New-Object Windows.Controls.Border
$border.BorderBrush = $borderColor $border.BorderBrush = $BorderColor
$border.BorderThickness = New-Object Windows.Thickness(1) # Adjust border thickness as needed $border.BorderThickness = New-Object Windows.Thickness(1) # Adjust border thickness as needed
$border.CornerRadius = New-Object Windows.CornerRadius(10) # Adjust the radius for rounded corners $border.CornerRadius = New-Object Windows.CornerRadius(10) # Adjust the radius for rounded corners
@ -89,7 +134,7 @@ function Show-CustomDialog {
$grid = New-Object Windows.Controls.Grid $grid = New-Object Windows.Controls.Grid
$border.Child = $grid $border.Child = $grid
# Add the following line to show gridlines # Uncomment the following line to show gridlines
#$grid.ShowGridLines = $true #$grid.ShowGridLines = $true
# Add the following line to set the background color of the grid # Add the following line to set the background color of the grid
@ -102,7 +147,6 @@ function Show-CustomDialog {
$border.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch $border.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch
$border.VerticalAlignment = [Windows.VerticalAlignment]::Stretch $border.VerticalAlignment = [Windows.VerticalAlignment]::Stretch
# Set up Row Definitions # Set up Row Definitions
$row0 = New-Object Windows.Controls.RowDefinition $row0 = New-Object Windows.Controls.RowDefinition
$row0.Height = [Windows.GridLength]::Auto $row0.Height = [Windows.GridLength]::Auto
@ -129,17 +173,18 @@ function Show-CustomDialog {
[Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index) [Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index)
# Add SVG path to the stack panel # Add SVG path to the stack panel
$stackPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size 25)) $stackPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size $LogoSize))
# Add "Winutil" text # Add "Winutil" text
$winutilTextBlock = New-Object Windows.Controls.TextBlock $winutilTextBlock = New-Object Windows.Controls.TextBlock
$winutilTextBlock.Text = "Winutil" $winutilTextBlock.Text = "Winutil"
$winutilTextBlock.FontSize = $HeaderFontSize $winutilTextBlock.FontSize = $HeaderFontSize
$winutilTextBlock.Foreground = $logocolor $winutilTextBlock.Foreground = $LogoColor
$winutilTextBlock.Margin = New-Object Windows.Thickness(10, 10, 10, 5) # Add margins around the text block $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 10, 10, 5) # Add margins around the text block
$stackPanel.Children.Add($winutilTextBlock) $stackPanel.Children.Add($winutilTextBlock)
# Add TextBlock for information with text wrapping and margins # Add TextBlock for information with text wrapping and margins
$messageTextBlock = New-Object Windows.Controls.TextBlock $messageTextBlock = New-Object Windows.Controls.TextBlock
$messageTextBlock.FontSize = $FontSize
$messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping $messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping
$messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left $messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left
$messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top $messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top
@ -162,7 +207,7 @@ function Show-CustomDialog {
$hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value) $hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value)
$hyperlink.Inlines.Add($match.Groups[2].Value) $hyperlink.Inlines.Add($match.Groups[2].Value)
$hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline $hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline
$hyperlink.Foreground = $sync.Form.Resources.LinkForegroundColor $hyperlink.Foreground = $LinkForegroundColor
$hyperlink.Add_Click({ $hyperlink.Add_Click({
param($sender, $args) param($sender, $args)
@ -170,11 +215,15 @@ function Show-CustomDialog {
}) })
$hyperlink.Add_MouseEnter({ $hyperlink.Add_MouseEnter({
param($sender, $args) param($sender, $args)
$sender.Foreground = $sync.Form.Resources.LinkHoverForegroundColor $sender.Foreground = $LinkHoverForegroundColor
$sender.FontSize = ($FontSize + ($FontSize / 4))
$sender.FontWeight = "SemiBold"
}) })
$hyperlink.Add_MouseLeave({ $hyperlink.Add_MouseLeave({
param($sender, $args) param($sender, $args)
$sender.Foreground = $sync.Form.Resources.LinkForegroundColor $sender.Foreground = $LinkForegroundColor
$sender.FontSize = $FontSize
$sender.FontWeight = "Normal"
}) })
$messageTextBlock.Inlines.Add($hyperlink) $messageTextBlock.Inlines.Add($hyperlink)
@ -218,7 +267,7 @@ function Show-CustomDialog {
$okButton.Margin = New-Object Windows.Thickness(0, 0, 0, 10) $okButton.Margin = New-Object Windows.Thickness(0, 0, 0, 10)
$okButton.Background = $buttonBackgroundColor $okButton.Background = $buttonBackgroundColor
$okButton.Foreground = $buttonForegroundColor $okButton.Foreground = $buttonForegroundColor
$okButton.BorderBrush = $borderColor $okButton.BorderBrush = $BorderColor
$okButton.Add_Click({ $okButton.Add_Click({
$dialog.Close() $dialog.Close()
}) })

View File

@ -23,14 +23,22 @@ function Test-WinUtilPackageManager {
# Check if Winget is available while getting it's Version if it's available # Check if Winget is available while getting it's Version if it's available
$wingetExists = $true $wingetExists = $true
try { try {
$wingetVersionFull = winget --version $wingetInfo = winget --info
# Extract the package version from the output
$wingetVersionFull = ($wingetInfo | Select-String -Pattern 'Microsoft\.DesktopAppInstaller v\d+\.\d+\.\d+\.\d+').Matches.Value
if ($wingetVersionFull) {
$wingetVersionFull = $wingetVersionFull.Split(' ')[-1].TrimStart('v')
} else {
# Fallback in case the pattern isn't found
$wingetVersionFull = ($wingetInfo | Select-String -Pattern 'Package Manager v\d+\.\d+\.\d+').Matches.Value.Split(' ')[-1]
}
} catch [System.Management.Automation.CommandNotFoundException], [System.Management.Automation.ApplicationFailedException] { } catch [System.Management.Automation.CommandNotFoundException], [System.Management.Automation.ApplicationFailedException] {
Write-Warning "Winget was not found due to un-availablity reasons" Write-Warning "Winget was not found due to un-availablity reasons"
$wingetExists = $false $wingetExists = $false
} catch { } catch {
Write-Warning "Winget was not found due to un-known reasons, The Stack Trace is:`n$($psitem.Exception.StackTrace)" Write-Warning "Winget was not found due to un-known reasons, The Stack Trace is:`n$($psitem.Exception.StackTrace)"
$wingetExists = $false $wingetExists = $false
} }
# If Winget is available, Parse it's Version and give proper information to Terminal Output. # If Winget is available, Parse it's Version and give proper information to Terminal Output.
# If it isn't available, the return of this funtion will be "not-installed", indicating that # If it isn't available, the return of this funtion will be "not-installed", indicating that
@ -48,13 +56,14 @@ function Test-WinUtilPackageManager {
# Check if Winget's Version is too old. # Check if Winget's Version is too old.
$wingetCurrentVersion = [System.Version]::Parse($wingetVersion.Trim('v')) $wingetCurrentVersion = [System.Version]::Parse($wingetVersion.Trim('v'))
# Grabs the latest release of Winget from the Github API for version check process. # Grabs the latest release of Winget from the Github API for version check process.
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/microsoft/Winget-cli/releases/latest" -Method Get -ErrorAction Stop $response = winget search -e Microsoft.AppInstaller --accept-source-agreements
$wingetLatestVersion = [System.Version]::Parse(($response.tag_name).Trim('v')) #Stores version number of latest release. $wingetLatestVersion = ($response | Select-String -Pattern '\d+\.\d+\.\d+\.\d+').Matches.Value
$wingetOutdated = $wingetCurrentVersion -lt $wingetLatestVersion Write-Host "Latest Search Version: $wingetLatestVersion" -ForegroundColor White
Write-Host "Current Installed Version: $wingetCurrentVersion" -ForegroundColor White
$wingetOutdated = $wingetCurrentVersion -lt [System.Version]::Parse($wingetLatestVersion)
Write-Host "===========================================" -ForegroundColor Green Write-Host "===========================================" -ForegroundColor Green
Write-Host "--- Winget is installed ---" -ForegroundColor Green Write-Host "--- Winget is installed ---" -ForegroundColor Green
Write-Host "===========================================" -ForegroundColor Green Write-Host "===========================================" -ForegroundColor Green
Write-Host "Version: $wingetVersionFull" -ForegroundColor White
if (!$wingetPreview) { if (!$wingetPreview) {
Write-Host " - Winget is a release version." -ForegroundColor Green Write-Host " - Winget is a release version." -ForegroundColor Green

View File

@ -0,0 +1,120 @@
function Initialize-WPFUI {
[OutputType([void])]
param(
[Parameter(Mandatory)]
[string]$TargetGridName
)
switch ($TargetGridName) {
"appscategory"{
# TODO
# Switch UI generation of the sidebar to this function
# $sync.ItemsControl = Initialize-InstallAppArea -TargetElement $TargetGridName
# ...
# Create and configure a popup for displaying selected apps
$selectedAppsPopup = New-Object Windows.Controls.Primitives.Popup
$selectedAppsPopup.IsOpen = $false
$selectedAppsPopup.PlacementTarget = $sync.WPFselectedAppsButton
$selectedAppsPopup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Bottom
$selectedAppsPopup.AllowsTransparency = $true
# Style the popup with a border and background
$selectedAppsBorder = New-Object Windows.Controls.Border
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "MainBackgroundColor")
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderBrushProperty, "MainForegroundColor")
$selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderThicknessProperty, "ButtonBorderThickness")
$selectedAppsBorder.Width = 200
$selectedAppsBorder.Padding = 5
$selectedAppsPopup.Child = $selectedAppsBorder
$sync.selectedAppsPopup = $selectedAppsPopup
# Add a stack panel inside the popup's border to organize its child elements
$sync.selectedAppsstackPanel = New-Object Windows.Controls.StackPanel
$selectedAppsBorder.Child = $sync.selectedAppsstackPanel
# Close selectedAppsPopup when mouse leaves both button and selectedAppsPopup
$sync.WPFselectedAppsButton.Add_MouseLeave({
if (-not $sync.selectedAppsPopup.IsMouseOver) {
$sync.selectedAppsPopup.IsOpen = $false
}
})
$selectedAppsPopup.Add_MouseLeave({
if (-not $sync.WPFselectedAppsButton.IsMouseOver) {
$sync.selectedAppsPopup.IsOpen = $false
}
})
# Creates the popup that is displayed when the user right-clicks on an app entry
# This popup contains buttons for installing, uninstalling, and viewing app information
$appPopup = New-Object Windows.Controls.Primitives.Popup
$appPopup.StaysOpen = $false
$appPopup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Bottom
$appPopup.AllowsTransparency = $true
# Store the popup globally so the position can be set later
$sync.appPopup = $appPopup
$appPopupStackPanel = New-Object Windows.Controls.StackPanel
$appPopupStackPanel.Orientation = "Horizontal"
$appPopupStackPanel.Add_MouseLeave({
$sync.appPopup.IsOpen = $false
})
$appPopup.Child = $appPopupStackPanel
$appButtons = @(
[PSCustomObject]@{ Name = "Install"; Icon = [char]0xE118 },
[PSCustomObject]@{ Name = "Uninstall"; Icon = [char]0xE74D },
[PSCustomObject]@{ Name = "Info"; Icon = [char]0xE946 }
)
foreach ($button in $appButtons) {
$newButton = New-Object Windows.Controls.Button
$newButton.Style = $sync.Form.Resources.AppEntryButtonStyle
$newButton.Content = $button.Icon
$appPopupStackPanel.Children.Add($newButton) | Out-Null
# Dynamically load the selected app object so the buttons can be reused and do not need to be created for each app
switch ($button.Name) {
"Install" {
$newButton.Add_MouseEnter({
$appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp)
$this.ToolTip = "Install or Upgrade $($appObject.content)"
})
$newButton.Add_Click({
$appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp)
Invoke-WPFInstall -PackagesToInstall $appObject
})
}
"Uninstall" {
$newButton.Add_MouseEnter({
$appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp)
$this.ToolTip = "Uninstall $($appObject.content)"
})
$newButton.Add_Click({
$appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp)
Invoke-WPFUnInstall -PackagesToUninstall $appObject
})
}
"Info" {
$newButton.Add_MouseEnter({
$appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp)
$this.ToolTip = "Open the application's website in your default browser`n$($appObject.link)"
})
$newButton.Add_Click({
$appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp)
Start-Process $appObject.link
})
}
}
}
}
"appspanel" {
$sync.ItemsControl = Initialize-InstallAppArea -TargetElement $TargetGridName
Initialize-InstallCategoryAppList -TargetElement $sync.ItemsControl -Apps $sync.configs.applicationsHashtable
}
default {
Write-Output "$TargetGridName not yet implemented"
}
}
}

View File

@ -33,7 +33,7 @@ function Invoke-WPFButton {
"WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"} "WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance -State "Disable"}
"WPFundoall" {Invoke-WPFundoall} "WPFundoall" {Invoke-WPFundoall}
"WPFFeatureInstall" {Invoke-WPFFeatureInstall} "WPFFeatureInstall" {Invoke-WPFFeatureInstall}
"WPFPanelDISM" {Invoke-WPFPanelDISM} "WPFPanelDISM" {Invoke-WPFSystemRepair}
"WPFPanelAutologin" {Invoke-WPFPanelAutologin} "WPFPanelAutologin" {Invoke-WPFPanelAutologin}
"WPFPanelcontrol" {Invoke-WPFControlPanel -Panel $button} "WPFPanelcontrol" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelnetwork" {Invoke-WPFControlPanel -Panel $button} "WPFPanelnetwork" {Invoke-WPFControlPanel -Panel $button}
@ -43,7 +43,8 @@ function Invoke-WPFButton {
"WPFPanelprinter" {Invoke-WPFControlPanel -Panel $button} "WPFPanelprinter" {Invoke-WPFControlPanel -Panel $button}
"WPFPanelsystem" {Invoke-WPFControlPanel -Panel $button} "WPFPanelsystem" {Invoke-WPFControlPanel -Panel $button}
"WPFPaneluser" {Invoke-WPFControlPanel -Panel $button} "WPFPaneluser" {Invoke-WPFControlPanel -Panel $button}
"WPFUpdatesdefault" {Invoke-WPFUpdatesdefault} "WPFPanelGodMode" {Invoke-WPFControlPanel -Panel $button}
"WPFUpdatesdefault" {Invoke-WPFFixesUpdate}
"WPFFixesUpdate" {Invoke-WPFFixesUpdate} "WPFFixesUpdate" {Invoke-WPFFixesUpdate}
"WPFFixesWinget" {Invoke-WPFFixesWinget} "WPFFixesWinget" {Invoke-WPFFixesWinget}
"WPFRunAdobeCCCleanerTool" {Invoke-WPFRunAdobeCCCleanerTool} "WPFRunAdobeCCCleanerTool" {Invoke-WPFRunAdobeCCCleanerTool}
@ -53,11 +54,13 @@ function Invoke-WPFButton {
"WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true} "WPFWinUtilShortcut" {Invoke-WPFShortcut -ShortcutToAdd "WinUtil" -RunAsAdmin $true}
"WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"} "WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"}
"WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"} "WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"}
"WPFGetIso" {Invoke-WPFGetIso} "WPFGetIso" {Invoke-MicrowinGetIso}
"WPFMicrowin" {Invoke-WPFMicrowin} "WPFMicrowin" {Invoke-Microwin}
"WPFCloseButton" {Invoke-WPFCloseButton} "WPFCloseButton" {Invoke-WPFCloseButton}
"MicrowinScratchDirBT" {Invoke-ScratchDialog} "MicrowinScratchDirBT" {Invoke-ScratchDialog}
"WPFWinUtilPSProfile" {Invoke-WinUtilpsProfile} "WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
"WPFWinUtilSSHServer" {Invoke-WinUtilSSHServer} "WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
"WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen}
} }
} }

View File

@ -19,5 +19,6 @@ function Invoke-WPFControlPanel {
"WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"} "WPFPanelprinter" {Start-Process "shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}"}
"WPFPanelsystem" {cmd /c sysdm.cpl} "WPFPanelsystem" {cmd /c sysdm.cpl}
"WPFPaneluser" {cmd /c "control userpasswords2"} "WPFPaneluser" {cmd /c "control userpasswords2"}
"WPFPanelGodMode" {Start-Process "shell:::{ED7BA470-8E54-465E-825C-99712043E01C}"}
} }
} }

View File

@ -6,19 +6,7 @@ function Invoke-WPFFixesUpdate {
Performs various tasks in an attempt to repair Windows Update Performs various tasks in an attempt to repair Windows Update
.DESCRIPTION .DESCRIPTION
1. (Aggressive Only) Scans the system for corruption using chkdsk, SFC, and DISM 1. (Aggressive Only) Scans the system for corruption using the Invoke-WPFSystemRepair function
Steps:
1. Runs chkdsk /scan /perf
/scan - Runs an online scan on the volume
/perf - Uses more system resources to complete a scan as fast as possible
2. Runs SFC /scannow
/scannow - Scans integrity of all protected system files and repairs files with problems when possible
3. Runs DISM /Online /Cleanup-Image /RestoreHealth
/Online - Targets the running operating system
/Cleanup-Image - Performs cleanup and recovery operations on the image
/RestoreHealth - Scans the image for component store corruption and attempts to repair the corruption using Windows Update
4. Runs SFC /scannow
Ran twice in case DISM repaired SFC
2. Stops Windows Update Services 2. Stops Windows Update Services
3. Remove the QMGR Data file, which stores BITS jobs 3. Remove the QMGR Data file, which stores BITS jobs
4. (Aggressive Only) Renames the DataStore and CatRoot2 folders 4. (Aggressive Only) Renames the DataStore and CatRoot2 folders
@ -46,104 +34,7 @@ function Invoke-WPFFixesUpdate {
Start-Sleep -Milliseconds 200 Start-Sleep -Milliseconds 200
if ($Aggressive) { if ($Aggressive) {
# Scan system for corruption Invoke-WPFSystemRepair
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Scanning for corruption..." -PercentComplete 0
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk..." -PercentComplete 0
# 2>&1 redirects stdout, alowing iteration over the output
chkdsk.exe /scan /perf 2>&1 | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Get the index of the total percentage
$index = $_.IndexOf("Total:")
if (
# If the percent is found
($percent = try {(
$_.Substring(
$index + 6,
$_.IndexOf("%", $index) - $index - 6
)
).Trim()} catch {0}) `
<# And the current percentage is greater than the previous one #>`
-and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running chkdsk... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC..." -PercentComplete 0
$oldpercent = 0
# SFC has a bug when redirected which causes it to output only when the stdout buffer is full, causing the progress bar to move in chunks
sfc /scannow 2>&1 | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Filter for lines that contain a percentage that is greater than the previous one
if (
(
# Use a different method to get the percentage that accounts for SFC's Unicode output
[int]$percent = try {(
(
$_.Substring(
$_.IndexOf("n") + 2,
$_.IndexOf("%") - $_.IndexOf("n") - 2
).ToCharArray() | Where-Object {$_}
) -join ''
).TrimStart()} catch {0}
) -and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM..." -PercentComplete 0
$oldpercent = 0
DISM /Online /Cleanup-Image /RestoreHealth | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Filter for lines that contain a percentage that is greater than the previous one
if (
($percent = try {
[int]($_ -replace "\[" -replace "=" -replace " " -replace "%" -replace "\]")
} catch {0}) `
-and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running DISM... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC again..." -PercentComplete 0
$oldpercent = 0
sfc /scannow 2>&1 | ForEach-Object {
# Write stdout to the Verbose stream
Write-Verbose $_
# Filter for lines that contain a percentage that is greater than the previous one
if (
(
[int]$percent = try {(
(
$_.Substring(
$_.IndexOf("n") + 2,
$_.IndexOf("%") - $_.IndexOf("n") - 2
).ToCharArray() | Where-Object {$_}
) -join ''
).TrimStart()} catch {0}
) -and $percent -gt $oldpercent
) {
# Update the progress bar
$oldpercent = $percent
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Running SFC... ($percent%)" -PercentComplete $percent
}
}
Write-Progress -Id 1 -ParentId 0 -Activity "Scanning for corruption" -Status "Completed" -PercentComplete 100
} }
@ -187,9 +78,9 @@ function Invoke-WPFFixesUpdate {
# Reset the Security Descriptors on the Windows Update Services # Reset the Security Descriptors on the Windows Update Services
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting the WU Service Security Descriptors..." -PercentComplete 25 Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting the WU Service Security Descriptors..." -PercentComplete 25
Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the BITS Security Descriptor..." -PercentComplete 0 Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the BITS Security Descriptor..." -PercentComplete 0
Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "bits", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)" Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "bits", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)" -Wait
Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the wuauserv Security Descriptor..." -PercentComplete 50 Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the wuauserv Security Descriptor..." -PercentComplete 50
Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "wuauserv", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)" Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "wuauserv", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)" -Wait
Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Completed" -PercentComplete 100 Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Completed" -PercentComplete 100
} }
@ -221,19 +112,53 @@ function Invoke-WPFFixesUpdate {
if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate") { if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate") {
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing WSUS client settings..." -PercentComplete 60 Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing WSUS client settings..." -PercentComplete 60
Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -PercentComplete 0 Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -PercentComplete 0
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f" -RedirectStandardError $true Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f" -RedirectStandardError "NUL"
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f" -RedirectStandardError $true Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f" -RedirectStandardError "NUL"
Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f" -RedirectStandardError $true Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f" -RedirectStandardError "NUL"
Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -Status "Completed" -PercentComplete 100 Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -Status "Completed" -PercentComplete 100
} }
# Remove Group Policy Windows Update settings
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing Group Policy Windows Update settings..." -PercentComplete 60
Write-Progress -Id 7 -ParentId 0 -Activity "Removing Group Policy Windows Update settings" -PercentComplete 0
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ExcludeWUDriversInQualityUpdate" -ErrorAction SilentlyContinue
Write-Host "Defaulting driver offering through Windows Update..."
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Name "PreventDeviceMetadataFromNetwork" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontPromptForWindowsUpdate" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontSearchWindowsUpdate" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DriverUpdateWizardWuSearchEnabled" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ExcludeWUDriversInQualityUpdate" -ErrorAction SilentlyContinue
Write-Host "Defaulting Windows Update automatic restart..."
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoRebootWithLoggedOnUsers" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "AUPowerManagement" -ErrorAction SilentlyContinue
Write-Host "Clearing ANY Windows Update Policy settings..."
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "BranchReadinessLevel" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "DeferFeatureUpdatesPeriodInDays" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "DeferQualityUpdatesPeriodInDays" -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\WindowsSelfHost" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\Microsoft\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\WindowsStore\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\Microsoft\WindowsSelfHost" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\WindowsStore\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue
Start-Process -NoNewWindow -FilePath "secedit" -ArgumentList "/configure", "/cfg", "$env:windir\inf\defltbase.inf", "/db", "defltbase.sdb", "/verbose" -Wait
Start-Process -NoNewWindow -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicyUsers" -Wait
Start-Process -NoNewWindow -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicy" -Wait
Start-Process -NoNewWindow -FilePath "gpupdate" -ArgumentList "/force" -Wait
Write-Progress -Id 7 -ParentId 0 -Activity "Removing Group Policy Windows Update settings" -Status "Completed" -PercentComplete 100
# Reset WinSock # Reset WinSock
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting WinSock..." -PercentComplete 65 Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting WinSock..." -PercentComplete 65
Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Resetting WinSock..." -PercentComplete 0 Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Resetting WinSock..." -PercentComplete 0
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winsock", "reset" -RedirectStandardOutput $true Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winsock", "reset"
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winhttp", "reset", "proxy" -RedirectStandardOutput $true Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winhttp", "reset", "proxy"
Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "int", "ip", "reset" -RedirectStandardOutput $true Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "int", "ip", "reset"
Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Completed" -PercentComplete 100 Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Completed" -PercentComplete 100
@ -262,7 +187,11 @@ function Invoke-WPFFixesUpdate {
# Force Windows Update to check for updates # Force Windows Update to check for updates
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Forcing discovery..." -PercentComplete 95 Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Forcing discovery..." -PercentComplete 95
Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Forcing discovery..." -PercentComplete 0 Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Forcing discovery..." -PercentComplete 0
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow() try {
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
} catch {
Write-Warning "Failed to create Windows Update COM object: $_"
}
Start-Process -NoNewWindow -FilePath "wuauclt" -ArgumentList "/resetauthorization", "/detectnow" Start-Process -NoNewWindow -FilePath "wuauclt" -ArgumentList "/resetauthorization", "/detectnow"
Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Completed" -PercentComplete 100 Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Completed" -PercentComplete 100
Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Completed" -PercentComplete 100 Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Completed" -PercentComplete 100
@ -284,7 +213,7 @@ function Invoke-WPFFixesUpdate {
Write-Progress -Id 3 -Activity "Renaming/Removing Files" -Completed Write-Progress -Id 3 -Activity "Renaming/Removing Files" -Completed
Write-Progress -Id 4 -Activity "Resetting the WU Service Security Descriptors" -Completed Write-Progress -Id 4 -Activity "Resetting the WU Service Security Descriptors" -Completed
Write-Progress -Id 5 -Activity "Reregistering DLLs" -Completed Write-Progress -Id 5 -Activity "Reregistering DLLs" -Completed
Write-Progress -Id 6 -Activity "Removing WSUS client settings" -Completed Write-Progress -Id 6 -Activity "Removing Group Policy Windows Update settings" -Completed
Write-Progress -Id 7 -Activity "Resetting WinSock" -Completed Write-Progress -Id 7 -Activity "Resetting WinSock" -Completed
Write-Progress -Id 8 -Activity "Deleting BITS jobs" -Completed Write-Progress -Id 8 -Activity "Deleting BITS jobs" -Completed
Write-Progress -Id 9 -Activity "Starting Windows Update Services" -Completed Write-Progress -Id 9 -Activity "Starting Windows Update Services" -Completed

View File

@ -1,36 +0,0 @@
Function Invoke-WPFFormVariables {
<#
.SYNOPSIS
Prints the logo
#>
#If ($global:ReadmeDisplay -ne $true) { Write-Host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow; $global:ReadmeDisplay = $true }
Write-Host ""
Write-Host " CCCCCCCCCCCCCTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT "
Write-Host " CCC::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T "
Write-Host "CC:::::::::::::::CT:::::::::::::::::::::TT:::::::::::::::::::::T "
Write-Host "C:::::CCCCCCCC::::CT:::::TT:::::::TT:::::TT:::::TT:::::::TT:::::T "
Write-Host "C:::::C CCCCCCTTTTTT T:::::T TTTTTTTTTTTT T:::::T TTTTTT"
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C T:::::T T:::::T "
Write-Host "C:::::C CCCCCC T:::::T T:::::T "
Write-Host "C:::::CCCCCCCC::::C TT:::::::TT TT:::::::TT "
Write-Host "CC:::::::::::::::C T:::::::::T T:::::::::T "
Write-Host "CCC::::::::::::C T:::::::::T T:::::::::T "
Write-Host " CCCCCCCCCCCCC TTTTTTTTTTT TTTTTTTTTTT "
Write-Host ""
Write-Host "====Chris Titus Tech====="
Write-Host "=====Windows Toolbox====="
#====DEBUG GUI Elements====
#Write-Host "Found the following interactable elements from our form" -ForegroundColor Cyan
#get-variable WPF*
}

View File

@ -9,38 +9,39 @@ function Invoke-WPFGetInstalled {
#> #>
param($checkbox) param($checkbox)
if ($sync.ProcessRunning) {
if($sync.ProcessRunning) {
$msg = "[Invoke-WPFGetInstalled] Install process is currently running." $msg = "[Invoke-WPFGetInstalled] Install process is currently running."
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return return
} }
if(($sync.WPFpreferChocolatey.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") { if (($sync.ChocoRadioButton.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") {
return return
} }
$preferChoco = $sync.WPFpreferChocolatey.IsChecked $managerPreference = $sync["ManagerPreference"]
Invoke-WPFRunspace -ArgumentList $checkbox, $preferChoco -DebugPreference $DebugPreference -ScriptBlock {
param($checkbox, $preferChoco, $DebugPreference)
Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -DebugPreference $DebugPreference -ScriptBlock {
param (
[string]$checkbox,
[PackageManagers]$managerPreference
)
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" }) $sync.form.Dispatcher.Invoke([action] { Set-WinUtilTaskbaritem -state "Indeterminate" })
if($checkbox -eq "winget") { if ($checkbox -eq "winget") {
Write-Host "Getting Installed Programs..." Write-Host "Getting Installed Programs..."
switch ($managerPreference) {
"Choco"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"; break}
"Winget"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox; break}
}
} }
if($checkbox -eq "tweaks") { elseif ($checkbox -eq "tweaks") {
Write-Host "Getting Installed Tweaks..." Write-Host "Getting Installed Tweaks..."
}
if ($preferChoco -and $checkbox -eq "winget") {
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"
}
else{
$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox
} }
$sync.form.Dispatcher.invoke({ $sync.form.Dispatcher.invoke({
foreach($checkbox in $Checkboxes) { foreach ($checkbox in $Checkboxes) {
$sync.$checkbox.ischecked = $True $sync.$checkbox.ischecked = $True
} }
}) })

View File

@ -46,7 +46,7 @@ function Invoke-WPFImpex {
if ($Config) { if ($Config) {
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json $jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json
$jsonFile | Out-File $Config -Force $jsonFile | Out-File $Config -Force
"iex ""& { `$(irm christitus.com/win) } -Config '$Config'""" | Set-Clipboard "iex ""& { `$(irm https://christitus.com/win) } -Config '$Config'""" | Set-Clipboard
} }
} catch { } catch {
Write-Error "An error occurred while exporting: $_" Write-Error "An error occurred while exporting: $_"

View File

@ -1,4 +1,8 @@
function Invoke-WPFInstall { function Invoke-WPFInstall {
param (
[Parameter(Mandatory=$false)]
[PSObject[]]$PackagesToInstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ })
)
<# <#
.SYNOPSIS .SYNOPSIS
@ -12,51 +16,24 @@ function Invoke-WPFInstall {
return return
} }
$PackagesToInstall = (Get-WinUtilCheckBoxes)["Install"]
Write-Host $PackagesToInstall
if ($PackagesToInstall.Count -eq 0) { if ($PackagesToInstall.Count -eq 0) {
$WarningMsg = "Please select the program(s) to install or upgrade" $WarningMsg = "Please select the program(s) to install or upgrade"
[System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) [System.Windows.MessageBox]::Show($WarningMsg, $AppTitle, [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning)
return return
} }
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
}
$packagesWinget, $packagesChoco = {
$packagesWinget = [System.Collections.ArrayList]::new()
$packagesChoco = [System.Collections.ArrayList]::new()
foreach ($package in $PackagesToInstall) { $ManagerPreference = $sync["ManagerPreference"]
if ($ChocoPreference) {
if ($package.choco -eq "na") { Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -DebugPreference $DebugPreference -ScriptBlock {
$packagesWinget.add($package.winget) param($PackagesToInstall, $ManagerPreference, $DebugPreference)
Write-Host "Queueing $($package.winget) for Winget install"
} else { $packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference
$null = $packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install" $packagesWinget = $packagesSorted[[PackageManagers]::Winget]
} $packagesChoco = $packagesSorted[[PackageManagers]::Choco]
}
else {
if ($package.winget -eq "na") {
$packagesChoco.add($package.choco)
Write-Host "Queueing $($package.choco) for Chocolatey install"
} else {
$null = $packagesWinget.add($($package.winget))
Write-Host "Queueing $($package.winget) for Winget install"
}
}
}
return $packagesWinget, $packagesChoco
}.Invoke($PackagesToInstall)
try { try {
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
$errorPackages = @()
if($packagesWinget.Count -gt 0) { if($packagesWinget.Count -gt 0) {
Install-WinUtilWinget Install-WinUtilWinget
Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget

View File

@ -5,7 +5,7 @@ function Invoke-WPFInstallUpgrade {
Invokes the function that upgrades all installed programs Invokes the function that upgrades all installed programs
#> #>
if ($sync.WPFpreferChocolatey.IsChecked) { if ($sync.ChocoRadioButton.IsChecked) {
Install-WinUtilChoco Install-WinUtilChoco
$chocoUpgradeStatus = (Start-Process "choco" -ArgumentList "upgrade all -y" -Wait -PassThru -NoNewWindow).ExitCode $chocoUpgradeStatus = (Start-Process "choco" -ArgumentList "upgrade all -y" -Wait -PassThru -NoNewWindow).ExitCode
if ($chocoUpgradeStatus -eq 0) { if ($chocoUpgradeStatus -eq 0) {

View File

@ -1,30 +0,0 @@
function Invoke-WPFPanelDISM {
<#
.SYNOPSIS
Checks for system corruption using Chkdsk, SFC, and DISM
.DESCRIPTION
1. Chkdsk - Fixes disk and filesystem corruption
2. SFC Run 1 - Fixes system file corruption, and fixes DISM if it was corrupted
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
4. SFC Run 2 - Fixes system file corruption, this time with an almost guaranteed uncorrupted system image
.NOTES
Command Arguments:
1. Chkdsk
/Scan - Runs an online scan on the system drive, attempts to fix any corruption, and queues other corruption for fixing on reboot
2. SFC
/ScanNow - Performs a scan of the system files and fixes any corruption
3. DISM - Fixes system image corruption, and fixes SFC's system image if it was corrupted
/Online - Fixes the currently running system image
/Cleanup-Image - Performs cleanup operations on the image, could remove some unneeded temporary files
/Restorehealth - Performs a scan of the image and fixes any corruption
#>
Start-Process PowerShell -ArgumentList "Write-Host '(1/4) Chkdsk' -ForegroundColor Green; Chkdsk /scan;
Write-Host '`n(2/4) SFC - 1st scan' -ForegroundColor Green; sfc /scannow;
Write-Host '`n(3/4) DISM' -ForegroundColor Green; DISM /Online /Cleanup-Image /Restorehealth;
Write-Host '`n(4/4) SFC - 2nd scan' -ForegroundColor Green; sfc /scannow;
Read-Host '`nPress Enter to Continue'" -verb runas
}

View File

@ -0,0 +1,54 @@
function Invoke-WPFPopup {
param (
[ValidateSet("Show", "Hide", "Toggle")]
[string]$Action = "",
[string[]]$Popups = @(),
[ValidateScript({
$invalid = $_.GetEnumerator() | Where-Object { $_.Value -notin @("Show", "Hide", "Toggle") }
if ($invalid) {
throw "Found invalid Popup-Action pair(s): " + ($invalid | ForEach-Object { "$($_.Key) = $($_.Value)" } -join "; ")
}
$true
})]
[hashtable]$PopupActionTable = @{}
)
if (-not $PopupActionTable.Count -and (-not $Action -or -not $Popups.Count)) {
throw "Provide either 'PopupActionTable' or both 'Action' and 'Popups'."
}
if ($PopupActionTable.Count -and ($Action -or $Popups.Count)) {
throw "Use 'PopupActionTable' on its own, or 'Action' with 'Popups'."
}
# Collect popups and actions
$PopupsToProcess = if ($PopupActionTable.Count) {
$PopupActionTable.GetEnumerator() | ForEach-Object { [PSCustomObject]@{ Name = "$($_.Key)Popup"; Action = $_.Value } }
} else {
$Popups | ForEach-Object { [PSCustomObject]@{ Name = "$_`Popup"; Action = $Action } }
}
$PopupsNotFound = @()
# Apply actions
foreach ($popupEntry in $PopupsToProcess) {
$popupName = $popupEntry.Name
if (-not $sync.$popupName) {
$PopupsNotFound += $popupName
continue
}
$sync.$popupName.IsOpen = switch ($popupEntry.Action) {
"Show" { $true }
"Hide" { $false }
"Toggle" { -not $sync.$popupName.IsOpen }
}
}
if ($PopupsNotFound.Count -gt 0) {
throw "Could not find the following popups: $($PopupsNotFound -join ', ')"
}
}

View File

@ -0,0 +1,17 @@
function Invoke-WPFSSHServer {
<#
.SYNOPSIS
Invokes the OpenSSH Server install in a runspace
#>
Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
Invoke-WinUtilSSHServer
Write-Host "======================================="
Write-Host "-- OpenSSH Server installed! ---"
Write-Host "======================================="
}
}

View File

@ -0,0 +1,43 @@
function Invoke-WPFSelectedAppsUpdate {
<#
.SYNOPSIS
This is a helper function that is called by the Checked and Unchecked events of the Checkboxes on the install tab.
It Updates the "Selected Apps" selectedAppLabel on the Install Tab to represent the current collection
.PARAMETER type
Eigther: Add | Remove
.PARAMETER checkbox
should contain the current instance of the checkbox that triggered the Event.
Most of the time will be the automatic variable $this
.EXAMPLE
$checkbox.Add_Unchecked({Invoke-WPFSelectedAppsUpdate -type "Remove" -checkbox $this})
OR
Invoke-WPFSelectedAppsUpdate -type "Add" -checkbox $specificCheckbox
#>
param (
$type,
$checkbox
)
$selectedAppsButton = $sync.WPFselectedAppsButton
# Get the actual Name from the selectedAppLabel inside the Checkbox
$appKey = $checkbox.Parent.Tag
if ($type -eq "Add") {
$sync.selectedApps.Add($appKey)
# The List type needs to be specified again, because otherwise Sort-Object will convert the list to a string if there is only a single entry
[System.Collections.Generic.List[pscustomobject]]$sync.selectedApps = $sync.SelectedApps | Sort-Object
}
elseif ($type -eq "Remove") {
$sync.SelectedApps.Remove($appKey)
}
else{
Write-Error "Type: $type not implemented"
}
$count = $sync.SelectedApps.Count
$selectedAppsButton.Content = "Selected Apps: $count"
# On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way
$sync.selectedAppsstackPanel.Children.Clear()
$sync.SelectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ }
}

View File

@ -1,72 +0,0 @@
function Invoke-WPFShortcut {
<#
.SYNOPSIS
Creates a shortcut and prompts for a save location
.PARAMETER ShortcutToAdd
The name of the shortcut to add
.PARAMETER RunAsAdmin
A boolean value to make 'Run as administrator' property on (true) or off (false), defaults to off
#>
param(
$ShortcutToAdd,
[bool]$RunAsAdmin = $false
)
# Preper the Shortcut Fields and add an a Custom Icon if it's available, else don't add a Custom Icon.
Switch ($ShortcutToAdd) {
"WinUtil" {
# Use Powershell 7 if installed and fallback to PS5 if not
if (Get-Command "pwsh" -ErrorAction SilentlyContinue) {
$shell = "pwsh.exe"
} else {
$shell = "powershell.exe"
}
$shellArgs = "-ExecutionPolicy Bypass -Command `"Start-Process $shell -verb runas -ArgumentList `'-Command `"irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex`"`'"
$DestinationName = "WinUtil.lnk"
}
}
# Show a File Dialog Browser, to let the User choose the Name and Location of where to save the Shortcut
$FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
$FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$FileBrowser.Filter = "Shortcut Files (*.lnk)|*.lnk"
$FileBrowser.FileName = $DestinationName
# Do an Early Return if the Save Operation was canceled by User's Input.
$FileBrowserResult = $FileBrowser.ShowDialog()
$DialogResultEnum = New-Object System.Windows.Forms.DialogResult
if (-not ($FileBrowserResult -eq $DialogResultEnum::OK)) {
return
}
# Prepare the Shortcut paramter
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut($FileBrowser.FileName)
$Shortcut.TargetPath = $shell
$Shortcut.Arguments = $shellArgs
if (-NOT (Test-Path -Path $winutildir["logo.ico"])) {
Invoke-WebRequest -Uri "https://christitus.com/images/logo-full.ico" -OutFile $winutildir["logo.ico"]
}
if (Test-Path -Path $winutildir["logo.ico"]) {
$shortcut.IconLocation = $winutildir["logo.ico"]
}
# Save the Shortcut to disk
$Shortcut.Save()
if ($RunAsAdmin -eq $true) {
$bytes = [System.IO.File]::ReadAllBytes($FileBrowser.FileName)
# 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($FileBrowser.FileName, $bytes)
}
Write-Host "Shortcut for $ShortcutToAdd has been saved to $($FileBrowser.FileName) with 'Run as administrator' set to $RunAsAdmin"
}

Some files were not shown because too many files have changed in this diff Show More