Compare commits

..

1 Commits

Author SHA1 Message Date
9d5e681aac Runspace Change to fix Tweaks 2024-09-11 14:22:01 -05:00
65 changed files with 1728 additions and 2567 deletions

View File

@ -68,9 +68,9 @@ graph TD
### Fork the Repo ### Fork the Repo
* Fork the WinUtil Repository [here](https://github.com/ChrisTitusTech/winutil) to create a copy that will be available in your repository list. * Fork the WinUtil Repository [here](https://github.com/ChrisTitusTech/winutil) to create a copy that will be available in your repository list.
![Fork Image](assets/Fork-Button-Dark.png#only-dark#gh-dark-mode-only) ![Fork Image](assets/Fork-Button-Dark.png#only-dark)
![Fork Image](assets/Fork-Button-Light.png#only-light#gh-light-mode-only) ![Fork Image](assets/Fork-Button-Light.png#only-light)
### Clone the Fork ### Clone the Fork
!!! tip !!! tip

5
.github/mkdocs.yml vendored
View File

@ -5,15 +5,12 @@ 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: 'CONTRIBUTING.md' - Contributing Guide: 'contribute.md'
- Documentation: - Documentation:
- Dev Docs: 'devdocs.md' - Dev Docs: 'devdocs.md'
- Known Issues: 'KnownIssues.md' - Known Issues: 'KnownIssues.md'
- FAQ: 'faq.md' - FAQ: 'faq.md'
not_in_nav: |
dev/
theme: theme:
name: material name: material
custom_dir: '../overrides' custom_dir: '../overrides'

View File

@ -19,6 +19,10 @@ template: |
$CHANGES $CHANGES
## Contributors
$CONTRIBUTORS
change-title-escapes: '\<*_&"''' change-title-escapes: '\<*_&"'''
autolabeler: autolabeler:
- label: 'documentation' - label: 'documentation'

View File

@ -15,33 +15,18 @@ jobs:
contents: read contents: read
steps: steps:
- run: echo "command=false" >> $GITHUB_ENV - name: Check for /close comment
id: check_comment
- name: Check for /close command
id: check_close_command
run: | run: |
if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then if [[ "${{ contains(github.event.comment.body, '/close') }}" == "true" ]]; then
echo "command=true" >> $GITHUB_ENV echo "comment=true" >> $GITHUB_ENV
echo "close_command=true" >> $GITHUB_ENV
echo "reopen_command=false" >> $GITHUB_ENV
else else
echo "close_command=false" >> $GITHUB_ENV echo "comment=false" >> $GITHUB_ENV
fi
- name: Check for /open or /reopen command
id: check_reopen_command
run: |
if [[ "${{ contains(github.event.comment.body, '/open') }}" == "true" ]] || [[ "${{ contains(github.event.comment.body, '/reopen') }}" == "true" ]]; then
echo "command=true" >> $GITHUB_ENV
echo "reopen_command=true" >> $GITHUB_ENV
echo "close_command=false" >> $GITHUB_ENV
else
echo "reopen_command=false" >> $GITHUB_ENV
fi fi
- name: Check if the user is allowed - name: Check if the user is allowed
id: check_user id: check_user
if: env.command == 'true' if: env.comment == 'true'
run: | run: |
ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC") ALLOWED_USERS=("ChrisTitusTech" "og-mrk" "Marterich" "MyDrift-user" "Real-MullaC")
if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then if [[ " ${ALLOWED_USERS[@]} " =~ " ${{ github.event.comment.user.login }} " ]]; then
@ -51,23 +36,10 @@ jobs:
fi fi
- name: Close issue if conditions are met - name: Close issue if conditions are met
if: env.close_command == 'true' && env.user == 'true' if: env.comment == 'true' && env.user == 'true'
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }} ISSUE_NUMBER: ${{ github.event.issue.number }}
run: | run: |
echo Closing the issue... echo Closing the issue...
if [[ "${{ contains(github.event.comment.body, 'not planned') }}" == "true" ]]; then
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }} --reason 'not planned'
else
gh issue close $ISSUE_NUMBER --repo ${{ github.repository }} gh issue close $ISSUE_NUMBER --repo ${{ github.repository }}
fi
- name: Reopen issue if conditions are met
if: env.reopen_command == 'true' && env.user == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
echo Reopening the issue...
gh issue reopen $ISSUE_NUMBER --repo ${{ github.repository }}

View File

@ -73,8 +73,8 @@ Get-ChildItem "functions" -Recurse -File | ForEach-Object {
} }
Update-Progress "Adding: Config *.json" 40 Update-Progress "Adding: Config *.json" 40
Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object { Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-Object {
$json = (Get-Content $psitem.FullName -Raw) $json = (Get-Content $psitem.FullName).replace("'","''")
$jsonAsObject = $json | ConvertFrom-Json $jsonAsObject = $json | convertfrom-json
# Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file # Add 'WPFInstall' as a prefix to every entry-name in 'applications.json' file
if ($psitem.Name -eq "applications.json") { if ($psitem.Name -eq "applications.json") {
@ -85,13 +85,12 @@ Get-ChildItem "config" | Where-Object {$psitem.extension -eq ".json"} | ForEach-
} }
} }
# Line 90 requires no whitespace inside the here-strings, to keep formatting of the JSON in the final script. # The replace at the end is required, as without it the output of 'converto-json' will be somewhat weird for Multiline Strings
$json = @" # Most Notably is the scripts in some json files, making it harder for users who want to review these scripts, which're found in the compiled script
$($jsonAsObject | ConvertTo-Json -Depth 3) $json = ($jsonAsObject | convertto-json -Depth 3).replace('\r\n',"`r`n")
"@
$sync.configs.$($psitem.BaseName) = $json | ConvertFrom-Json $sync.configs.$($psitem.BaseName) = $json | convertfrom-json
$script_content.Add($(Write-Output "`$sync.configs.$($psitem.BaseName) = @'`r`n$json`r`n'@ `| ConvertFrom-Json" )) $script_content.Add($(Write-output "`$sync.configs.$($psitem.BaseName) = '$json' `| 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,12 +124,10 @@ 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 {
Get-Command -Syntax .\winutil.ps1 | Out-Null $null = Get-Command -Syntax .\winutil.ps1
} 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

File diff suppressed because one or more lines are too long

View File

@ -445,7 +445,7 @@
"category": "Utilities", "category": "Utilities",
"content": "Dual Monitor Tools", "content": "Dual Monitor Tools",
"link": "https://dualmonitortool.sourceforge.net/", "link": "https://dualmonitortool.sourceforge.net/",
"description": "Dual Monitor Tools (DMT) is a FOSS app that allows you to customize the handling of multiple monitors. Useful for fullscreen games and apps that handle a second monitor poorly and can improve your workflow." "description": "Dual Monitor Tools (DMT) is a FOSS app that customize handling multiple monitors and even lock the mouse on specific monitor. Useful for full screen games and apps that does not handle well a second monitor or helps the workflow."
}, },
"duplicati": { "duplicati": {
"category": "Utilities", "category": "Utilities",
@ -1892,7 +1892,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://www.glenn.delahoy.com/snappy-driver-installer-origin/", "link": "https://sourceforge.net/projects/snappy-driver-installer-origin",
"winget": "GlennDelahoy.SnappyDriverInstallerOrigin" "winget": "GlennDelahoy.SnappyDriverInstallerOrigin"
}, },
"session": { "session": {
@ -2855,6 +2855,14 @@
"link": "https://www.kicad.org/", "link": "https://www.kicad.org/",
"winget": "KiCad.KiCad" "winget": "KiCad.KiCad"
}, },
"FormatFactory": {
"category": "Utilities",
"choco": "formatfactory",
"content": "Format Factory",
"description":"FormatFactory is an ad-supported freeware multimedia converter that can convert video, audio, and picture files. It is also capable of ripping DVDs and CDs to other file formats, as well as creating .iso images. It can also join multiple video files together into one.",
"link": "http://www.pcfreetime.com/formatfactory/",
"winget": "na"
},
"dropox": { "dropox": {
"category": "Utilities", "category": "Utilities",
"choco": "na", "choco": "na",

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\Microwin-RemovePackages.ps1' -Raw | Invoke-Expression;"</Path> <Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\remove-packages.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\Microwin-RemovePackages.ps1"> <File path="C:\Windows\Temp\remove-packages.ps1">
$selectors = @( $selectors = @(
'Microsoft.Microsoft3DViewer'; 'Microsoft.Microsoft3DViewer';
'Microsoft.BingSearch'; 'Microsoft.BingSearch';
@ -359,7 +359,7 @@ $removeCommand = {
} }
}; };
$type = 'Package'; $type = 'Package';
$logfile = 'C:\Windows\Temp\Microwin-RemovePackages.log'; $logfile = 'C:\Windows\Temp\remove-packages.log';
&amp; { &amp; {
$installed = &amp; $getCommand; $installed = &amp; $getCommand;
foreach( $selector in $selectors ) { foreach( $selector in $selectors ) {

View File

@ -46,23 +46,5 @@
"Secondary": "94.140.15.16", "Secondary": "94.140.15.16",
"Primary6": "2a10:50c0::bad1:ff", "Primary6": "2a10:50c0::bad1:ff",
"Secondary6": "2a10:50c0::bad2:ff" "Secondary6": "2a10:50c0::bad2:ff"
},
"dns0.eu_Open":{
"Primary": "193.110.81.254",
"Secondary": "185.253.5.254",
"Primary6": "2a0f:fc80::ffff",
"Secondary6": "2a0f:fc81::ffff"
},
"dns0.eu_ZERO":{
"Primary": "193.110.81.9",
"Secondary": "185.253.5.9",
"Primary6": "2a0f:fc80::9",
"Secondary6": "2a0f:fc81::9"
},
"dns0.eu_KIDS":{
"Primary": "193.110.81.1",
"Secondary": "185.253.5.1",
"Primary6": "2a0f:fc80::1",
"Secondary6": "2a0f:fc81::1"
} }
} }

View File

@ -306,30 +306,12 @@
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/user" "link": "https://christitustech.github.io/winutil/dev/features/Legacy-Windows-Panels/user"
}, },
"WPFWinUtilInstallPSProfile": { "WPFWinUtilPSProfile": {
"Content": "Install CTT PowerShell Profile", "Content": "Install CTT PowerShell Profile",
"category": "Powershell Profile", "category": "Powershell Profile",
"panel": "2", "panel": "2",
"Order": "a083_", "Order": "a083_",
"Type": "Button", "Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileInstall"
},
"WPFWinUtilUninstallPSProfile": {
"Content": "Uninstall CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileUninstall"
},
"WPFWinUtilSSHServer": {
"Content": "Enable OpenSSH Server",
"category": "Remote Access",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300" "ButtonWidth": "300"
} }
} }

View File

@ -1,44 +1,36 @@
{ {
"shared":{ "_default": {
"CustomDialogFontSize": "12", "CustomDialogFontSize": "12",
"CustomDialogFontSizeHeader": "14", "CustomDialogFontSizeHeader": "14",
"CustomDialogIconSize": "25", "CustomDialogIconSize": "25",
"CustomDialogWidth": "400", "CustomDialogWidth": "400",
"CustomDialogHeight": "200", "CustomDialogHeight": "200",
"FontSize": "12", "FontSize": "12",
"FontFamily": "Arial", "FontFamily": "Arial",
"FontSizeHeading": "16", "FontSizeHeading": "16",
"HeaderFontFamily": "Consolas, Monaco", "HeaderFontFamily": "Consolas, Monaco",
"CheckBoxBulletDecoratorSize": "14", "CheckBoxBulletDecoratorSize": "14",
"CheckBoxMargin": "15,0,0,2", "CheckBoxMargin": "15,0,0,2",
"TabContentMargin": "5", "TabContentMargin": "5",
"TabButtonFontSize": "14", "TabButtonFontSize": "14",
"TabButtonWidth": "110", "TabButtonWidth": "100",
"TabButtonHeight": "26", "TabButtonHeight": "25",
"TabRowHeightInPixels": "50", "TabRowHeightInPixels": "50",
"IconFontSize": "14", "IconFontSize": "14",
"IconButtonSize": "35", "IconButtonSize": "35",
"SettingsIconFontSize": "18", "SettingsIconFontSize": "18",
"CloseIconFontSize": "18", "CloseIconFontSize": "18",
"MicroWinLogoSize": "10", "MicroWinLogoSize": "10",
"MicrowinCheckBoxMargin": "-10,5,0,0", "MicrowinCheckBoxMargin": "-10,5,0,0",
"GroupBorderBackgroundColor": "#232629",
"ButtonFontSize": "12", "ProgressBarForegroundColor": "#2e77ff",
"ButtonFontFamily": "Arial", "ProgressBarBackgroundColor": "Transparent",
"ButtonWidth": "200", "ProgressBarTextColor": "#232629",
"ButtonHeight": "25",
"ConfigTabButtonFontSize": "16",
"SearchBarWidth": "200",
"SearchBarHeight": "26",
"SearchBarTextBoxFontSize": "12",
"SearchBarClearButtonFontSize": "14",
"CheckboxMouseOverColor": "#999999",
"ButtonBorderThickness": "1",
"ButtonMargin": "1",
"ButtonCornerRadius": "2"
},
"Light": {
"ComboBoxForegroundColor": "#232629",
"ComboBoxBackgroundColor": "#F7F7F7", "ComboBoxBackgroundColor": "#F7F7F7",
"LabelboxForegroundColor": "#232629", "LabelboxForegroundColor": "#232629",
"MainForegroundColor": "#232629", "MainForegroundColor": "#232629",
@ -46,13 +38,20 @@
"LabelBackgroundColor": "#F7F7F7", "LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#232629", "LinkForegroundColor": "#232629",
"LinkHoverForegroundColor": "#232629", "LinkHoverForegroundColor": "#232629",
"ScrollBarBackgroundColor": "#4A4D52", "GroupBorderBackgroundColor": "#232629",
"ScrollBarHoverColor": "#5A5D62", "ComboBoxForegroundColor": "#232629",
"ScrollBarDraggingColor": "#6A6D72",
"ButtonFontSize": "12",
"ButtonFontFamily": "Arial",
"ButtonWidth": "200",
"ButtonHeight": "25",
"ConfigTabButtonFontSize": "16",
"SearchBarWidth": "200",
"SearchBarHeight": "25",
"SearchBarTextBoxFontSize": "12",
"SearchBarClearButtonFontSize": "14",
"ProgressBarForegroundColor": "#2e77ff",
"ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#232629",
"ButtonInstallBackgroundColor": "#F7F7F7", "ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#F7F7F7", "ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#F7F7F7", "ButtonConfigBackgroundColor": "#F7F7F7",
@ -63,31 +62,60 @@
"ButtonUpdatesForegroundColor": "#232629", "ButtonUpdatesForegroundColor": "#232629",
"ButtonBackgroundColor": "#F5F5F5", "ButtonBackgroundColor": "#F5F5F5",
"ButtonBackgroundPressedColor": "#1A1A1A", "ButtonBackgroundPressedColor": "#1A1A1A",
"CheckboxMouseOverColor": "#999999",
"ButtonBackgroundMouseoverColor": "#C2C2C2", "ButtonBackgroundMouseoverColor": "#C2C2C2",
"ButtonBackgroundSelectedColor": "#F0F0F0", "ButtonBackgroundSelectedColor": "#F0F0F0",
"ButtonForegroundColor": "#232629", "ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"ToggleButtonOffColor": "#707070",
"BorderColor": "#232629",
"BorderOpacity": "0.2"
"ButtonBorderThickness": "1",
"ButtonMargin": "1",
"ButtonCornerRadius": "2",
"BorderColor": "#232629",
"BorderOpacity": "0.2",
"ShadowPulse": "Forever"
}, },
"Dark": { "Classic": {
"ComboBoxForegroundColor": "#F7F7F7", "ComboBoxBackgroundColor": "#F7F7F7",
"ComboBoxBackgroundColor": "#1E3747", "LabelboxForegroundColor": "#232629",
"LabelboxForegroundColor": "#0567ff", "MainForegroundColor": "#232629",
"MainBackgroundColor": "#F7F7F7",
"LabelBackgroundColor": "#F7F7F7",
"LinkForegroundColor": "#232629",
"LinkHoverForegroundColor": "#232629",
"GroupBorderBackgroundColor": "#232629",
"ComboBoxForegroundColor": "#232629",
"ButtonInstallBackgroundColor": "#F7F7F7",
"ButtonTweaksBackgroundColor": "#F7F7F7",
"ButtonConfigBackgroundColor": "#F7F7F7",
"ButtonUpdatesBackgroundColor": "#F7F7F7",
"ButtonInstallForegroundColor": "#232629",
"ButtonTweaksForegroundColor": "#232629",
"ButtonConfigForegroundColor": "#232629",
"ButtonUpdatesForegroundColor": "#232629",
"ButtonBackgroundColor": "#F5F5F5",
"ButtonBackgroundPressedColor": "#1A1A1A",
"CheckboxMouseOverColor": "#999999",
"ButtonBackgroundMouseoverColor": "#C2C2C2",
"ButtonBackgroundSelectedColor": "#F0F0F0",
"ButtonForegroundColor": "#232629",
"ToggleButtonOnColor": "#2e77ff"
},
"Matrix": {
"ComboBoxBackgroundColor": "#232629",
"LabelboxForegroundColor": "#81a1c1",
"MainForegroundColor": "#F7F7F7", "MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#232629", "MainBackgroundColor": "#232629",
"LabelBackgroundColor": "#232629", "LabelBackgroundColor": "#232629",
"LinkForegroundColor": "#add8e6", "LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#F7F7F7", "LinkHoverForegroundColor": "#F7F7F7",
"ScrollBarBackgroundColor": "#2E3135", "ComboBoxForegroundColor": "#81a1c1",
"ScrollBarHoverColor": "#3B4252",
"ScrollBarDraggingColor": "#5E81AC",
"ProgressBarForegroundColor": "#222222", "ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent", "ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#cccccc", "ProgressBarTextColor": "#cccccc",
"ButtonInstallBackgroundColor": "#222222", "ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333", "ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444", "ButtonConfigBackgroundColor": "#444444",
@ -102,8 +130,40 @@
"ButtonBackgroundSelectedColor": "#5E81AC", "ButtonBackgroundSelectedColor": "#5E81AC",
"ButtonForegroundColor": "#F7F7F7", "ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff", "ToggleButtonOnColor": "#2e77ff",
"ToggleButtonOffColor": "#707070",
"BorderColor": "#2F373D", "BorderColor": "#0060CC",
"BorderOpacity": "0.2" "BorderOpacity": "0.2",
"ShadowPulse": "0:0:3"
},
"Dark": {
"ComboBoxBackgroundColor": "#232629",
"LabelboxForegroundColor": "#81a1c1",
"MainForegroundColor": "#F7F7F7",
"MainBackgroundColor": "#232629",
"LabelBackgroundColor": "#232629",
"LinkForegroundColor": "#add8e6",
"LinkHoverForegroundColor": "#F7F7F7",
"ComboBoxForegroundColor": "#81a1c1",
"ProgressBarForegroundColor": "#222222",
"ProgressBarBackgroundColor": "Transparent",
"ProgressBarTextColor": "#cccccc",
"ButtonInstallBackgroundColor": "#222222",
"ButtonTweaksBackgroundColor": "#333333",
"ButtonConfigBackgroundColor": "#444444",
"ButtonUpdatesBackgroundColor": "#555555",
"ButtonInstallForegroundColor": "#F7F7F7",
"ButtonTweaksForegroundColor": "#F7F7F7",
"ButtonConfigForegroundColor": "#F7F7F7",
"ButtonUpdatesForegroundColor": "#F7F7F7",
"ButtonBackgroundColor": "#1E3747",
"ButtonBackgroundPressedColor": "#00CFFF",
"ButtonBackgroundMouseoverColor": "#5E81AC",
"ButtonBackgroundSelectedColor": "#5E81AC",
"ButtonForegroundColor": "#F7F7F7",
"ToggleButtonOnColor": "#2e77ff",
"BorderColor": "#0b1215"
} }
} }

View File

@ -11,21 +11,21 @@
"Name": "EnableActivityFeed", "Name": "EnableActivityFeed",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System",
"Name": "PublishUserActivities", "Name": "PublishUserActivities",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System",
"Name": "UploadUserActivities", "Name": "UploadUserActivities",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
} }
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/AH" "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/AH"
@ -1598,126 +1598,147 @@
"Name": "CreateDesktopShortcutDefault", "Name": "CreateDesktopShortcutDefault",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeEnhanceImagesEnabled",
"Type": "DWord",
"Value": "0",
"OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "PersonalizationReportingEnabled", "Name": "PersonalizationReportingEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "ShowRecommendationsEnabled", "Name": "ShowRecommendationsEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "HideFirstRunExperience", "Name": "HideFirstRunExperience",
"Type": "DWord", "Type": "DWord",
"Value": "1", "Value": "1",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "0"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "UserFeedbackAllowed", "Name": "UserFeedbackAllowed",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "ConfigureDoNotTrack", "Name": "ConfigureDoNotTrack",
"Type": "DWord", "Type": "DWord",
"Value": "1", "Value": "1",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "0"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "AlternateErrorPagesEnabled", "Name": "AlternateErrorPagesEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeCollectionsEnabled", "Name": "EdgeCollectionsEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeFollowEnabled",
"Type": "DWord",
"Value": "0",
"OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeShoppingAssistantEnabled", "Name": "EdgeShoppingAssistantEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "MicrosoftEdgeInsiderPromotionEnabled", "Name": "MicrosoftEdgeInsiderPromotionEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "PersonalizationReportingEnabled", "Name": "PersonalizationReportingEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "ShowMicrosoftRewards", "Name": "ShowMicrosoftRewards",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "WebWidgetAllowed", "Name": "WebWidgetAllowed",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "DiagnosticData", "Name": "DiagnosticData",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeAssetDeliveryServiceEnabled", "Name": "EdgeAssetDeliveryServiceEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "EdgeCollectionsEnabled", "Name": "EdgeCollectionsEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "CryptoWalletEnabled", "Name": "CryptoWalletEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
},
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "ConfigureDoNotTrack",
"Type": "DWord",
"Value": "1",
"OriginalValue": "0"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge",
"Name": "WalletDonationEnabled", "Name": "WalletDonationEnabled",
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
} }
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/EdgeDebloat" "link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/EdgeDebloat"
@ -1731,7 +1752,7 @@
"registry": [ "registry": [
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CloudContent", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CloudContent",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "0",
"Name": "DisableWindowsConsumerFeatures", "Name": "DisableWindowsConsumerFeatures",
"Value": "1", "Value": "1",
"Type": "DWord" "Type": "DWord"
@ -1818,11 +1839,11 @@
"Type": "DWord", "Type": "DWord",
"Value": "0", "Value": "0",
"Name": "AllowTelemetry", "Name": "AllowTelemetry",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "1"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\DataCollection", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\DataCollection",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "1",
"Name": "AllowTelemetry", "Name": "AllowTelemetry",
"Value": "0", "Value": "0",
"Type": "DWord" "Type": "DWord"
@ -1906,21 +1927,21 @@
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\DataCollection", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\DataCollection",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "0",
"Name": "DoNotShowFeedbackNotifications", "Name": "DoNotShowFeedbackNotifications",
"Value": "1", "Value": "1",
"Type": "DWord" "Type": "DWord"
}, },
{ {
"Path": "HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CloudContent", "Path": "HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CloudContent",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "0",
"Name": "DisableTailoredExperiencesWithDiagnosticData", "Name": "DisableTailoredExperiencesWithDiagnosticData",
"Value": "1", "Value": "1",
"Type": "DWord" "Type": "DWord"
}, },
{ {
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\AdvertisingInfo", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\AdvertisingInfo",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "0",
"Name": "DisabledByGroupPolicy", "Name": "DisabledByGroupPolicy",
"Value": "1", "Value": "1",
"Type": "DWord" "Type": "DWord"
@ -2047,7 +2068,7 @@
}, },
{ {
"Path": "HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Feeds", "Path": "HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Feeds",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "1",
"Name": "EnableFeeds", "Name": "EnableFeeds",
"Value": "0", "Value": "0",
"Type": "DWord" "Type": "DWord"
@ -2061,7 +2082,7 @@
}, },
{ {
"Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "1",
"Name": "HideSCAMeetNow", "Name": "HideSCAMeetNow",
"Value": "1", "Value": "1",
"Type": "DWord" "Type": "DWord"
@ -2409,6 +2430,12 @@
"Order": "a001_", "Order": "a001_",
"InvokeScript": [ "InvokeScript": [
" "
# Check if the user has administrative privileges
if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host \"Please run this script as an administrator.\"
return
}
# Check if System Restore is enabled for the main drive # Check if System Restore is enabled for the main drive
try { try {
# Try getting restore points to check if System Restore is enabled # Try getting restore points to check if System Restore is enabled
@ -2553,14 +2580,14 @@
"Name": "TurnOffWindowsCopilot", "Name": "TurnOffWindowsCopilot",
"Type": "DWord", "Type": "DWord",
"Value": "1", "Value": "1",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "0"
}, },
{ {
"Path": "HKCU:\\Software\\Policies\\Microsoft\\Windows\\WindowsCopilot", "Path": "HKCU:\\Software\\Policies\\Microsoft\\Windows\\WindowsCopilot",
"Name": "TurnOffWindowsCopilot", "Name": "TurnOffWindowsCopilot",
"Type": "DWord", "Type": "DWord",
"Value": "1", "Value": "1",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "0"
}, },
{ {
"Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
@ -2584,36 +2611,6 @@
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot" "link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveCopilot"
}, },
"WPFTweaksRecallOff": {
"Content": "Disable Recall",
"Description": "Turn Recall off",
"category": "Essential Tweaks",
"panel": "1",
"Order": "a011_",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
"Name": "DisableAIDataAnalysis",
"Type": "DWord",
"Value": "1",
"OriginalValue": "<RemoveEntry>"
}
],
"InvokeScript": [
"
Write-Host \"Disable Recall\"
DISM /Online /Disable-Feature /FeatureName:Recall
"
],
"UndoScript": [
"
Write-Host \"Enable Recall\"
DISM /Online /Enable-Feature /FeatureName:Recall
"
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
},
"WPFTweaksDisableLMS1": { "WPFTweaksDisableLMS1": {
"Content": "Disable Intel MM (vPro LMS)", "Content": "Disable Intel MM (vPro LMS)",
"Description": "Intel LMS service is always listening on all ports and could be a huge security risk. There is no need to run LMS on home machines and even in the Enterprise there are better solutions.", "Description": "Intel LMS service is always listening on all ports and could be a huge security risk. There is no need to run LMS on home machines and even in the Enterprise there are better solutions.",
@ -2682,26 +2679,17 @@
" "
$OneDrivePath = $($env:OneDrive) $OneDrivePath = $($env:OneDrive)
Write-Host \"Removing OneDrive\" Write-Host \"Removing OneDrive\"
# Check both traditional and Microsoft Store installations
$regPath = \"HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OneDriveSetup.exe\" $regPath = \"HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OneDriveSetup.exe\"
$msStorePath = \"HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\Applications\\*OneDrive*\"
if (Test-Path $regPath) { if (Test-Path $regPath) {
$OneDriveUninstallString = Get-ItemPropertyValue \"$regPath\" -Name \"UninstallString\" $OneDriveUninstallString = Get-ItemPropertyValue \"$regPath\" -Name \"UninstallString\"
$OneDriveExe, $OneDriveArgs = $OneDriveUninstallString.Split(\" \") $OneDriveExe, $OneDriveArgs = $OneDriveUninstallString.Split(\" \")
Start-Process -FilePath $OneDriveExe -ArgumentList \"$OneDriveArgs /silent\" -NoNewWindow -Wait Start-Process -FilePath $OneDriveExe -ArgumentList \"$OneDriveArgs /silent\" -NoNewWindow -Wait
} elseif (Test-Path $msStorePath) {
Write-Host \"OneDrive appears to be installed via Microsoft Store\" -ForegroundColor Yellow
# Attempt to uninstall via winget
Start-Process -FilePath winget -ArgumentList \"uninstall -e --purge --accept-source-agreements Microsoft.OneDrive\" -NoNewWindow -Wait
} else { } else {
Write-Host \"OneDrive doesn't seem to be installed\" -ForegroundColor Red Write-Host \"Onedrive dosn't seem to be installed anymore\" -ForegroundColor Red
Write-Host \"Running cleanup if OneDrive path exists\" -ForegroundColor Red return
} }
# Check if OneDrive got Uninstalled
# Check if OneDrive got Uninstalled (both paths) if (-not (Test-Path $regPath)) {
if (Test-Path $OneDrivePath) {
Write-Host \"Copy downloaded Files from the OneDrive Folder to Root UserProfile\" Write-Host \"Copy downloaded Files from the OneDrive Folder to Root UserProfile\"
Start-Process -FilePath powershell -ArgumentList \"robocopy '$($OneDrivePath)' '$($env:USERPROFILE.TrimEnd())\\' /mov /e /xj\" -NoNewWindow -Wait Start-Process -FilePath powershell -ArgumentList \"robocopy '$($OneDrivePath)' '$($env:USERPROFILE.TrimEnd())\\' /mov /e /xj\" -NoNewWindow -Wait
@ -2767,7 +2755,7 @@
Write-Host \"If there are Files missing afterwards, please Login to Onedrive.com and Download them manually\" -ForegroundColor Yellow Write-Host \"If there are Files missing afterwards, please Login to Onedrive.com and Download them manually\" -ForegroundColor Yellow
Start-Sleep 5 Start-Sleep 5
} else { } else {
Write-Host \"Nothing to Cleanup with OneDrive\" -ForegroundColor Red Write-Host \"Something went Wrong during the Unistallation of OneDrive\" -ForegroundColor Red
} }
" "
], ],
@ -2779,48 +2767,6 @@
], ],
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive" "link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/RemoveOnedrive"
}, },
"WPFTweaksRazerBlock": {
"Content": "Block Razer Software Installs",
"Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.",
"category": "z__Advanced Tweaks - CAUTION",
"panel": "1",
"Order": "a031_",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DriverSearching",
"Name": "SearchOrderConfig",
"Value": "0",
"OriginalValue": "1",
"Type": "DWord"
},
{
"Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Device Installer",
"Name": "DisableCoInstallers",
"Value": "1",
"OriginalValue": "0",
"Type": "DWord"
}
],
"InvokeScript": [
"
$RazerPath = \"C:\\Windows\\Installer\\Razer\"
Remove-Item $RazerPath -Recurse -Force
New-Item -Path \"C:\\Windows\\Installer\\\" -Name \"Razer\" -ItemType \"directory\"
$Acl = Get-Acl $RazerPath
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule(\"NT AUTHORITY\\SYSTEM\",\"Write\",\"ContainerInherit,ObjectInherit\",\"None\",\"Deny\")
$Acl.SetAccessRule($Ar)
Set-Acl $RazerPath $Acl
"
],
"UndoScript": [
"
$RazerPath = \"C:\\Windows\\Installer\\Razer\"
Remove-Item $RazerPath -Recurse -Force
New-Item -Path \"C:\\Windows\\Installer\\\" -Name \"Razer\" -ItemType \"directory\"
"
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/RazerBlock"
},
"WPFTweaksDisableNotifications": { "WPFTweaksDisableNotifications": {
"Content": "Disable Notification Tray/Calendar", "Content": "Disable Notification Tray/Calendar",
"Description": "Disables all Notifications INCLUDING Calendar", "Description": "Disables all Notifications INCLUDING Calendar",
@ -2833,7 +2779,7 @@
"Name": "DisableNotificationCenter", "Name": "DisableNotificationCenter",
"Type": "DWord", "Type": "DWord",
"Value": "1", "Value": "1",
"OriginalValue": "<RemoveEntry>" "OriginalValue": "0"
}, },
{ {
"Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\PushNotifications", "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\PushNotifications",
@ -3192,7 +3138,7 @@
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\GameDVR", "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\GameDVR",
"Name": "AllowGameDVR", "Name": "AllowGameDVR",
"Value": "0", "Value": "0",
"OriginalValue": "<RemoveEntry>", "OriginalValue": "1",
"Type": "DWord" "Type": "DWord"
} }
], ],
@ -3453,7 +3399,7 @@
"panel": "1", "panel": "1",
"Order": "a040_", "Order": "a040_",
"Type": "Combobox", "Type": "Combobox",
"ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult dns0.eu_Open dns0.eu_ZERO dns0.eu_KIDS", "ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult",
"link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns" "link": "https://christitustech.github.io/winutil/dev/tweaks/z--Advanced-Tweaks---CAUTION/changedns"
}, },
"WPFAddUltPerf": { "WPFAddUltPerf": {
@ -3473,5 +3419,14 @@
"Type": "Button", "Type": "Button",
"ButtonWidth": "300", "ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/tweaks/Performance-Plans/RemoveUltPerf" "link": "https://christitustech.github.io/winutil/dev/tweaks/Performance-Plans/RemoveUltPerf"
},
"WPFWinUtilShortcut": {
"Content": "Create WinUtil Shortcut",
"category": "Shortcuts",
"panel": "2",
"Order": "a082_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/tweaks/Shortcuts/Shortcut"
} }
} }

View File

@ -1,27 +1,18 @@
## Launch Issues ### Launch Issues:
### Blocked by anti-virus - 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.
Windows Security (formerly Defender) and other anti-virus software are known to block the script. The script gets flagged due to the fact that it requires administrator privileges & makes drastic system changes. - If possible: Allow script in Anti-Virus software settings.
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. - If you are having TLS 1.2 issues, or are having trouble resolving `christitus.com/win` then run with the following command:
### Download not working
If `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
irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1 | iex [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12;iex(New-Object Net.WebClient).DownloadString('https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1')
``` ```
If you are seeing errors referencing TLS or security, you may be running an older version of Windows where TLS 1.2 is not the default security protocol used for network connections. The following commands will force .NET to use TLS 1.2, and download the script directly using .NET instead of PowerShell: - If you are unable to resolve `christitus.com/win` and are getting errors launching the tool, it might be due to India blocking GitHub's content domain and preventing downloads.
- Source: <https://timesofindia.indiatimes.com/gadgets-news/github-content-domain-blocked-for-these-indian-users-reports/articleshow/96687992.cms>
```ps1 If you are still having issues try using a **VPN**, or changing your **DNS provider** to one of following two providers:
[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 |
|:------------:|:------------:|:-------------:| |:------------:|:------------:|:-------------:|
@ -29,186 +20,160 @@ If you are still having issues, try using a **VPN**, or changing your **DNS prov
| 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. - Script doesn't run/PowerShell crashes:
2. In the PowerShell window, type this to allow unsigned code to execute and run the installation script: 1. Press Windows Key+X and select 'PowerShell (Admin)' (Windows 10) or 'Windows Terminal (Admin)' (Windows 11)
2. Run:
```ps1 ```ps1
Set-ExecutionPolicy Unrestricted -Scope Process -Force Set-ExecutionPolicy Unrestricted -Scope Process -Force
```
3. Run:
```ps1
irm christitus.com/win | iex irm christitus.com/win | iex
``` ```
## Runtime Issues ### Other Issues:
### WinGet configuration - Windows taking longer to shut down:
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. - [#69](https://github.com/ChrisTitusTech/winutil/issues/69) Turn on fast startup: Press Windows key + R, then type:
### 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 control /name Microsoft.PowerOptions /page pageGlobalSettings
``` ```
- If that doesn't work, disable Hibernation: - 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:
- Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11. ```ps1
- In the PowerShell window, type:
```bat
powercfg /H off powercfg /H off
``` ```
Related issue: [#69](https://github.com/ChrisTitusTech/winutil/issues/69) - [#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
### 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:
```ps1 ```ps1
Get-Service -Name "XboxGipSvc" | Set-Service -StartupType Automatic Get-Service -Name "XboxGipSvc" | Set-Service -StartupType Automatic
``` ```
Related issue: [#198](https://github.com/ChrisTitusTech/winutil/issues/198) - Winget requires interaction on first run: Manually type 'y' and 'enter' into the PowerShell console to continue
- (Windows 11) Quick Settings no longer works: Launch the Script and click 'Enable Action Center'
### Windows 11: Quick Settings no longer works - Explorer no longer launches: Go to Control Panel, File Explorer Options, Change the 'Open File Explorer to' option to 'This PC'.
Launch the Script and click *Enable Action Center*.
### Explorer (file browser) no longer launches ### Battery drains too fast.
- Press `Windows key`+`R` then type: * When your battery on the laptop drains too fast, please perform these steps and report the results back to the Winutil community.
```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:**
- Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11. - Open a Command Prompt as an administrator.
- 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. A battery with poor health may hold less charge, discharge faster, or cause other issues. - Open the generated HTML report to review information about battery health and usage.
2. **Review Power Settings:** 2. **Review Power Settings:**
- Open the Settings app, and go to *System* > *Power & sleep*. - Go to "Settings" > "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 that may help. - Click on "Additional power settings" to access advanced power settings.
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 reconfiguring, closing, disabling, or uninstalling applications that use a lot of resources. - Consider closing unnecessary background applications.
4. **Update Drivers:** 4. **Update Drivers:**
- Visit your device manufacturer's website or use Windows Update to check for driver updates. - Visit your laptop manufacturer's website or use Windows Update to check for driver updates.
- Ensure graphics, chipset, and other essential drivers are up to date. - Ensure graphics, chipset, and other essential drivers are up to date.
5. **Check for Windows Updates:** 5. **Check for Windows Updates:**
- Open the Settings app, and go to *Update & Security* > *Windows Update*. - Go to "Settings" > "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:**
- Open the Settings app, and go to *System* > *Display*.
- Adjust screen brightness based on your preferences and lighting conditions. - Adjust screen brightness based on your preferences and lighting conditions.
- Go to "Settings" > "System" > "Display" to adjust brightness.
7. **Enable Battery Saver:** 7. **Battery Saver Mode:**
- Open the Settings app, and go to *System* > *Battery*. - Go to "Settings" > "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:**
- Open the Settings app, and go to *System* > *Battery* > *Battery usage by app*. - Go to "Settings" > "System" > "Battery" > "Battery usage by app."
- Review the list of apps and their power usage. Disable or uninstall any you don't need. - Review the list of apps and their power usage.
9. **Check Background Apps:** 9. **Check Background Apps:**
- Open the Settings app, and go to *Privacy* > *Background apps*. - Go to "Settings" > "Privacy" > "Background apps."
- Disable or uninstall unnecessary apps running in the background. - Disable unnecessary apps running in the background.
10. **Use `powercfg` for Analysis:** 10. **Use Powercfg for Analysis:**
- Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11. - Open a Command Prompt as an administrator.
- 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 Logs:** 11. **Review Event Viewer:**
- 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. These may highlight battery, input power, and other issues. - Look for events with the source "Power-Troubleshooter" to identify power-related events.
12. **Check Wake-up Sources:** 12. **Check Wake-up Sources:**
- Press `Windows Key`+`X` and select *PowerShell (Admin)* in Windows 10, or `Windows Terminal (Admin)` in Windows 11. - Open a Command Prompt as an administrator.
- 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. **Advanced Identification of Power-Hungry Apps:** 13. **Resource Monitor:**
- Open Resource Monitor from the Start menu. - Open Resource Monitor from the Start menu.
- Navigate to the *CPU*, *Memory*, *Network*, and other tabs to identify processes with high resource usage. - Navigate to the "CPU" tab and identify processes with high CPU usage.
- Consider reconfiguring, closing, disabling, or uninstalling applications that use a lot of resources.
14. **Disable Activity History:** 14. **Windows Settings - Activity History:**
- Open the Settings app, and go to *Privacy* > *Activity history*. - In "Settings," 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. **Prevent Network Adapters From Waking PC:** 15. **Network Adapters:**
- 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.
These troubleshooting steps are generic, but should help in most situations. You should have these key takeaways: * 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.
- Battery health is the most significant limiter on your device's runtime. A battery in poor health usually cannot be made to last like it used to, simply by closing some applications. Consider replacing your battery.
- Background applications that use CPU and memory, make lots of or large network requests, read/write to disk frequently, or that keep your PC awake when it could be conserving energy are the next major concern. Avoid installing programs you don't need, only use programs you trust, and configure applications to use as little power and run as infrequently as possible. ### Troubleshoot errors during Microwin usage
- Windows performs a lot of tasks that may affect battery life by default. Changing settings, stopping scheduled tasks, and disabling features can help the system stay in lower power states to conserve battery.
- Bad chargers, inconsistent power input, and high temperatures will cause batteries to degrade and discharge faster. Use trusted high-quality chargers, ensure input power is steady, clean any fans or airflow ports, and keep the battery/PC cool. #### Error `0x80041031`
* This error code typically indicates an issue related to Windows Management Instrumentation (WMI). Here are a few steps you can try to resolve the issue:
1. **Reboot Your Computer:**
Sometimes, a simple reboot can resolve temporary issues. Restart your computer and try mounting the ISO again.
2. **Check for System Corruption:**
Run the System File Checker (SFC) utility to scan and repair system files that may be corrupted.
```powershell
sfc /scannow
```
3. **Update Your System:**
Make sure your operating system is up-to-date. Check for Windows updates and install any pending updates.
4. **Check WMI Service:**
Ensure that the Windows Management Instrumentation (WMI) service is running. You can do this through the Services application:
- Press `Win + R` to open the Run dialog.
- Type `services.msc` and press Enter.
- Locate "Windows Management Instrumentation" in the list.
- Make sure to set its status to "Running" and the startup type to "Automatic."
5. **Check for Security Software Interference:**
Security software can sometimes interfere with WMI operations. Temporarily disable your antivirus or security software and check if the issue persists.
6. **Event Viewer:**
Check the Event Viewer for more detailed error information. Look for entries related to the `80041031` error and check if there are any additional details that can help identify the cause.
- Press `Win + X` and select "Event Viewer."
- Navigate to "Windows Logs" -> "Application" or "System."
- Look for entries with the source related to WMI or the application use to mount the ISO.
7. **ISO File Integrity:**
Ensure that the ISO file you are trying to mount is uncorrupted. Try mounting a different ISO file to see if the issue persists.
* If the problem persists after trying these steps, additional troubleshooting is required. Consider seeking assistance from Microsoft support or community forums for more specific guidance based on your system configuration and the software you use to mount the ISO.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 339 KiB

3
docs/contribute.md Normal file
View File

@ -0,0 +1,3 @@
--8<-- ".github/CONTRIBUTING.md"
<!-- The content is sourced from "CONTRIBUTING.md," located in the root directory of the project. -->

View File

@ -1,38 +0,0 @@
# Install CTT PowerShell Profile
Last Updated: 2024-10-01
!!! 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": "Install CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a083_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileInstall"
}
```
</details>
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/feature.json)

View File

@ -1,38 +0,0 @@
# Uninstall CTT PowerShell Profile
Last Updated: 2024-10-01
!!! 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": "Uninstall CTT PowerShell Profile",
"category": "Powershell Profile",
"panel": "2",
"Order": "a084_",
"Type": "Button",
"ButtonWidth": "300",
"link": "https://christitustech.github.io/winutil/dev/features/Powershell-Profile/PSProfileUninstall"
}
```
</details>
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/feature.json)

View File

@ -1,91 +0,0 @@
# Disable Microsoft Recall
Last Updated: 2024-10-24
!!! 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.**
## Description
Disables MS Recall built into Windows since 24H2.
<!-- BEGIN CUSTOM CONTENT -->
<!-- END CUSTOM CONTENT -->
<details>
<summary>Preview Code</summary>
```json
"WPFTweaksRecallOff": {
"Content": "Disable Recall",
"Description": "Turn Recall off",
"category": "Essential Tweaks",
"panel": "1",
"Order": "a011_",
"registry": [
{
"Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\WindowsAI",
"Name": "DisableAIDataAnalysis",
"Type": "DWord",
"Value": "1",
"OriginalValue": "0"
}
],
"InvokeScript": [
"
Write-Host \"Disable Recall\"
DISM /Online /Disable-Feature /FeatureName:Recall
"
],
"UndoScript": [
"
Write-Host \"Enable Recall\"
DISM /Online /Enable-Feature /FeatureName:Recall
"
],
"link": "https://christitustech.github.io/winutil/dev/tweaks/Essential-Tweaks/DisableRecall"
},
```
</details>
## Invoke Script
```powershell
Write-Host "Disable Recall"
DISM /Online /Disable-Feature /FeatureName:Recall
```
## Undo Script
```powershell
Write-Host "Enable Recall"
DISM /Online /Enable-Feature /FeatureName:Recall
```
## Registry Changes
Applications and System Components store and retrieve configuration data to modify windows settings, so we can use the registry to change many settings in one place.
You can find information about the registry on [Wikipedia](https://www.wikiwand.com/en/Windows_Registry) and [Microsoft's Website](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry).
### Registry Key: DisableAIDataAnalysis
**Type:** DWord
**Original Value:** 0
**New Value:** 1
<!-- BEGIN SECOND CUSTOM CONTENT -->
<!-- END SECOND CUSTOM CONTENT -->
[View the JSON file](https://github.com/ChrisTitusTech/winutil/tree/main/config/tweaks.json)

View File

@ -0,0 +1,113 @@
# 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

@ -34,9 +34,8 @@
* By default Winutil will use winget to install/upgrade/remove packages and fallback to Chocolatey. This option reverses the preference. * By default Winutil will use winget to install/upgrade/remove packages and fallback to Chocolatey. This option reverses the preference.
* This preference will be used for all Buttons on the Install page and persist across Winutil restarts * This preference will be used for all Buttons on the Install page and persist across Winutil restarts
![Install Image](assets/Install-Tab-Dark.png#only-dark#gh-dark-mode-only) ![Install Image](assets/Install-Tab-Dark.png#only-dark)
![Install Image](assets/Install-Tab-Light.png#only-light#gh-light-mode-only) ![Install Image](assets/Install-Tab-Light.png#only-light)
!!! tip !!! tip
If you have trouble finding an application, press `ctrl + f` and search the name of it. Applications will filter depending on your input. If you have trouble finding an application, press `ctrl + f` and search the name of it. Applications will filter depending on your input.
@ -44,8 +43,8 @@
## Tweaks ## Tweaks
--- ---
![Tweaks Image](assets/Tweaks-Tab-Dark.png#only-dark#gh-dark-mode-only) ![Tweaks Image](assets/Tweaks-Tab-Dark.png#only-dark)
![Tweaks Image](assets/Tweaks-Tab-Light.png#only-light#gh-light-mode-only) ![Tweaks Image](assets/Tweaks-Tab-Light.png#only-light)
### Run Tweaks ### Run Tweaks
* **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application. * **Open Tweaks Tab**: Navigate to the 'Tweaks' tab in the application.
@ -77,17 +76,13 @@ 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=en): A reliable and fast DNS service provided by Google. * [**Google**](https://developers.google.com/speed/public-dns?hl=de): A reliable and fast DNS service provided by Google.
* [**Cloudflare**](https://developers.cloudflare.com/1.1.1.1/): Known for speed and privacy, Cloudflare DNS is a popular choice for enhancing internet performance. * [**Cloudflare**](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
@ -146,10 +141,6 @@ Open old-school Windows panels directly from WinUtil. Following Panels are avail
* System Properties * System Properties
* User Accounts * User Accounts
### Remote Access
Enables OpenSSH server on your windows machine.
## Updates ## Updates
--- ---
@ -184,8 +175,8 @@ The utility provides three distinct settings for managing Windows updates: Defau
* **MicroWin** lets you customize your Windows 10 and 11 installation images by debloating them however you want. * **MicroWin** lets you customize your Windows 10 and 11 installation images by debloating them however you want.
![Microwin](assets/Microwin-Dark.png#only-dark#gh-dark-mode-only) ![Microwin](assets/Microwin-Dark.png#only-dark)
![Microwin](assets/Microwin-Light.png#only-light#gh-light-mode-only) ![Microwin](assets/Microwin-Light.png#only-light)
#### Basic usage #### Basic usage
@ -243,12 +234,12 @@ With MicroWin, you can also configure your user before proceeding if you don't w
* Some features are available through automation. This allows you to save your config file, pass it to WinUtil, walk away and come back to a finished system. Here is how you can set it up currently with Winutil >24.01.15 * Some features are available through automation. This allows you to save your config file, pass it to WinUtil, walk away and come back to a finished system. Here is how you can set it up currently with Winutil >24.01.15
* On the Install Tab, click "Get Installed", this will get all installed apps **supported by Winutil** on the system. * On the Install Tab, click "Get Installed", this will get all installed apps **supported by Winutil** on the system.
![GetInstalled](assets/Get-Installed-Dark.png#only-dark#gh-dark-mode-only) ![GetInstalled](assets/Get-Installed-Dark.png#only-dark)
![GetInstalled](assets/Get-Installed-Light.png#only-light#gh-light-mode-only) ![GetInstalled](assets/Get-Installed-Light.png#only-light)
* Click on the Settings cog in the upper right corner and choose Export. Choose file file and location; this will export the setting file. * Click on the Settings cog in the upper right corner and choose Export. Choose file file and location; this will export the setting file.
![SettingsExport](assets/Settings-Export-Dark.png#only-dark#gh-dark-mode-only) ![SettingsExport](assets/Settings-Export-Dark.png#only-dark)
![SettingsExport](assets/Settings-Export-Light.png#only-light#gh-light-mode-only) ![SettingsExport](assets/Settings-Export-Light.png#only-light)
* Copy this file to a USB or somewhere you can use it after Windows installation. * Copy this file to a USB or somewhere you can use it after Windows installation.

View File

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

@ -1,23 +0,0 @@
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)"
return
}
}
Write-Host "Ventoy USB Key is not inserted"
}

View File

@ -1,49 +0,0 @@
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

@ -1,21 +0,0 @@
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,73 +0,0 @@
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

@ -1,68 +0,0 @@
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 { $_.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,40 +0,0 @@
function Microwin-RemoveFeatures() {
<#
.SYNOPSIS
Removes certain features from ISO image
.PARAMETER Name
No Params
.EXAMPLE
Microwin-RemoveFeatures
#>
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
}
}

View File

@ -1,42 +0,0 @@
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

@ -1,96 +0,0 @@
function Microwin-RemovePackages {
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
}
}

View File

@ -1,51 +0,0 @@
function Microwin-RemoveProvisionedPackages() {
<#
.SYNOPSIS
Removes AppX packages from a Windows image during MicroWin processing
.PARAMETER Name
No Params
.EXAMPLE
Microwin-RemoveProvisionedPackages
#>
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
}
}

View File

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

@ -19,10 +19,10 @@ function Copy-Files {
try { try {
$files = Get-ChildItem -Path $path -Recurse:$recurse $files = Get-ChildItem -Path $path -Recurse:$recurse
Write-Host "Copy $($files.Count) file(s) from $path to $destination" Write-Host "Copy $($files.Count)(s) from $path to $destination"
foreach ($file in $files) { foreach ($file in $files) {
$status = "Copying file {0} of {1}: {2}" -f $counter, $files.Count, $file.Name $status = "Copy files {0} on {1}: {2}" -f $counter, $files.Count, $file.Name
Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100) Write-Progress -Activity "Copy Windows files" -Status $status -PercentComplete ($counter++/$files.count*100)
$restpath = $file.FullName -Replace $path, '' $restpath = $file.FullName -Replace $path, ''
@ -37,11 +37,7 @@ function Copy-Files {
} }
Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed Write-Progress -Activity "Copy Windows files" -Status "Ready" -Completed
} catch { } catch {
Write-Host "Unable to Copy all the files due to an unhandled exception" -ForegroundColor Yellow Write-Warning "Unable to Copy all the files due to unhandled exception"
Write-Host "Error information: $($_.Exception.Message)`n" -ForegroundColor Yellow Write-Warning $psitem.Exception.StackTrace
Write-Host "Additional information:" -ForegroundColor Yellow
Write-Host $PSItem.Exception.StackTrace
# Write possible suggestions
Write-Host "`nIf you are using an antivirus, try configuring exclusions"
} }
} }

View File

@ -1,10 +1,10 @@
function Microwin-GetOscdimg { function Get-Oscdimg {
<# <#
.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
Microwin-GetOscdimg Get-Oscdimg
#> #>
param( param(

View File

@ -16,72 +16,136 @@ Function Get-WinUtilToggleStatus {
if($ToggleSwitch -eq "WPFToggleDarkMode") { if($ToggleSwitch -eq "WPFToggleDarkMode") {
$app = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme $app = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').AppsUseLightTheme
$system = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').SystemUsesLightTheme $system = (Get-ItemProperty -path 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize').SystemUsesLightTheme
return $app -eq 0 -and $system -eq 0 if($app -eq 0 -and $system -eq 0) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleBingSearch") { if($ToggleSwitch -eq "WPFToggleBingSearch") {
$bingsearch = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search').BingSearchEnabled $bingsearch = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search').BingSearchEnabled
return $bingsearch -ne 0 if($bingsearch -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleNumLock") { if($ToggleSwitch -eq "WPFToggleNumLock") {
$numlockvalue = (Get-ItemProperty -path 'HKCU:\Control Panel\Keyboard').InitialKeyboardIndicators $numlockvalue = (Get-ItemProperty -path 'HKCU:\Control Panel\Keyboard').InitialKeyboardIndicators
return $numlockvalue -eq 2 if($numlockvalue -eq 2) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleVerboseLogon") { if($ToggleSwitch -eq "WPFToggleVerboseLogon") {
$VerboseStatusvalue = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System').VerboseStatus $VerboseStatusvalue = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System').VerboseStatus
return $VerboseStatusvalue -eq 1 if($VerboseStatusvalue -eq 1) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleShowExt") { if($ToggleSwitch -eq "WPFToggleShowExt") {
$hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt $hideextvalue = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').HideFileExt
return $hideextvalue -eq 0 if($hideextvalue -eq 0) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleSnapWindow") { if($ToggleSwitch -eq "WPFToggleSnapWindow") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Control Panel\Desktop').WindowArrangementActive $hidesnap = (Get-ItemProperty -path 'HKCU:\Control Panel\Desktop').WindowArrangementActive
return $hidesnap -ne 0 if($hidesnap -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleSnapFlyout") { if($ToggleSwitch -eq "WPFToggleSnapFlyout") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout $hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').EnableSnapAssistFlyout
return $hidesnap -ne 0 if($hidesnap -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleSnapSuggestion") { if($ToggleSwitch -eq "WPFToggleSnapSuggestion") {
$hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').SnapAssist $hidesnap = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').SnapAssist
return $hidesnap -ne 0 if($hidesnap -eq 0) {
return $false
} else {
return $true
}
} }
if($ToggleSwitch -eq "WPFToggleMouseAcceleration") { if($ToggleSwitch -eq "WPFToggleMouseAcceleration") {
$MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed $MouseSpeed = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseSpeed
$MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1 $MouseThreshold1 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold1
$MouseThreshold2 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold2 $MouseThreshold2 = (Get-ItemProperty -path 'HKCU:\Control Panel\Mouse').MouseThreshold2
return $MouseSpeed -eq 1 -and $MouseThreshold1 -eq 6 -and $MouseThreshold2 -eq 10 if($MouseSpeed -eq 1 -and $MouseThreshold1 -eq 6 -and $MouseThreshold2 -eq 10) {
return $true
} else {
return $false
}
} }
if($ToggleSwitch -eq "WPFToggleTaskbarSearch") { if($ToggleSwitch -eq "WPFToggleTaskbarSearch") {
$SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode $SearchButton = (Get-ItemProperty -path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Search").SearchboxTaskbarMode
return $SearchButton -ne 0 if($SearchButton -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleStickyKeys") { if ($ToggleSwitch -eq "WPFToggleStickyKeys") {
$StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags $StickyKeys = (Get-ItemProperty -path 'HKCU:\Control Panel\Accessibility\StickyKeys').Flags
return $StickyKeys -ne 58 if($StickyKeys -eq 58) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleTaskView") { if ($ToggleSwitch -eq "WPFToggleTaskView") {
$TaskView = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').ShowTaskViewButton $TaskView = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').ShowTaskViewButton
return $TaskView -ne 0 if($TaskView -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleHiddenFiles") { if ($ToggleSwitch -eq "WPFToggleHiddenFiles") {
$HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden $HiddenFiles = (Get-ItemProperty -path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced').Hidden
return $HiddenFiles -ne 0 if($HiddenFiles -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleTaskbarWidgets") { if ($ToggleSwitch -eq "WPFToggleTaskbarWidgets") {
$TaskbarWidgets = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskBarDa $TaskbarWidgets = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskBarDa
return $TaskbarWidgets -ne 0 if($TaskbarWidgets -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleTaskbarAlignment") { if ($ToggleSwitch -eq "WPFToggleTaskbarAlignment") {
$TaskbarAlignment = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskbarAl $TaskbarAlignment = (Get-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced").TaskbarAl
return $TaskbarAlignment -ne 0 if($TaskbarAlignment -eq 0) {
return $false
} else {
return $true
}
} }
if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") { if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") {
$DetailedBSoD1 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters $DetailedBSoD1 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters
$DetailedBSoD2 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisableEmoticon $DetailedBSoD2 = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisableEmoticon
return !(($DetailedBSoD1 -eq 0) -or ($DetailedBSoD2 -eq 0) -or !$DetailedBSoD1 -or !$DetailedBSoD2) if (($DetailedBSoD1 -eq 0) -or ($DetailedBSoD2 -eq 0) -or !$DetailedBSoD1 -or !$DetailedBSoD2) {
return $false
} else {
return $true
}
} }
} }

View File

@ -13,11 +13,10 @@ function Install-WinUtilChoco {
if((Test-WinUtilPackageManager -choco) -eq "installed") { if((Test-WinUtilPackageManager -choco) -eq "installed") {
return return
} }
# Install logic taken from https://chocolatey.org/install#individual
Write-Host "Seems Chocolatey is not installed, installing now." Write-Host "Seems Chocolatey is not installed, installing now."
Set-ExecutionPolicy Bypass -Scope Process -Force; Start-Process -FilePath "powershell" -ArgumentList "Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) -ErrorAction Stop" -Wait -NoNewWindow
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; Start-Process -FilePath "powershell" -ArgumentList "choco feature enable -n allowGlobalConfirmation" -Wait -NoNewWindow
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
} catch { } catch {
Write-Host "===========================================" -Foregroundcolor Red Write-Host "===========================================" -Foregroundcolor Red

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 Invoke-ChocoCommand { function Run-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 = Invoke-ChocoCommand -arguments "install 7zip -y" $exitCode = Run-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 Test-UpgradeNeeded { function Check-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 = Test-UpgradeNeeded -filePath "C:\temp\install-output.txt" $isUpgradeNeeded = Check-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 = Invoke-ChocoCommand "install $Program -y --log-file $installOutputFile" $installStatusCode = Run-ChocoCommand "install $Program -y --log-file $installOutputFile"
if ($installStatusCode -eq 0) { if ($installStatusCode -eq 0) {
if (Test-UpgradeNeeded $installOutputFile) { if (Check-UpgradeNeeded $installOutputFile) {
$upgradeStatusCode = Invoke-ChocoCommand "upgrade $Program -y" $upgradeStatusCode = Run-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 = Invoke-ChocoCommand "uninstall $chocoPackages -y" $uninstallStatusCode = Run-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

@ -21,11 +21,6 @@ Function Invoke-WinUtilDarkMode {
$Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize" $Path = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"
Set-ItemProperty -Path $Path -Name AppsUseLightTheme -Value $DarkMoveValue Set-ItemProperty -Path $Path -Name AppsUseLightTheme -Value $DarkMoveValue
Set-ItemProperty -Path $Path -Name SystemUsesLightTheme -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] { } 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] {

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

@ -1,103 +0,0 @@
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,4 +1,262 @@
function Microwin-NewUnattend { 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
}
}
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
$_.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 "*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*"
}
$failedCount = 0
foreach ($pkg in $pkglist) {
try {
$status = "Removing $pkg"
Write-Progress -Activity "Removing Apps" -Status $status -PercentComplete ($counter++/$pkglist.Count*100)
Remove-WindowsPackage -Path "$scratchDir" -PackageName $pkg -NoRestart -ErrorAction SilentlyContinue
} catch {
# This can happen if the package that is being removed is a permanent one, like FodMetadata
Write-Host "Could not remove OS package $($pkg)"
$failedCount += 1
continue
}
}
Write-Progress -Activity "Removing Apps" -Status "Ready" -Completed
if ($failedCount -gt 0)
{
Write-Host "Some packages could not be removed. Do not worry: your image will still work fine. This can happen if the package is permanent or has been superseded by a newer one."
}
} 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 "*dism*" -and
$_.PackageName -NotLike "*Foundation*" -and
$_.PackageName -NotLike "*FodMetadata*" -and
$_.PackageName -NotLike "*LanguageFeatures*" -and
$_.PackageName -NotLike "*Notepad*" -and
$_.PackageName -NotLike "*Printing*" -and
$_.PackageName -NotLike "*Foundation*" -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*"
}
$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 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 ( param (
[Parameter(Mandatory, Position = 0)] [string]$userName, [Parameter(Mandatory, Position = 0)] [string]$userName,
@ -160,7 +418,7 @@ function Microwin-NewUnattend {
</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\Microwin-RemovePackages.ps1' -Raw | Invoke-Expression;"</Path> <Path>powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\Windows\Temp\remove-packages.ps1' -Raw | Invoke-Expression;"</Path>
</RunSynchronousCommand> </RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add"> <RunSynchronousCommand wcm:action="add">
<Order>20</Order> <Order>20</Order>
@ -294,7 +552,7 @@ function Microwin-NewUnattend {
</component> </component>
</settings> </settings>
'@ '@
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,22000,1))) -eq $false) { 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 # Replace the placeholder text with an empty string to make it valid for Windows 10 Setup
$unattend = $unattend.Replace("<#REPLACEME#>", "").Trim() $unattend = $unattend.Replace("<#REPLACEME#>", "").Trim()
} else { } else {
@ -308,3 +566,172 @@ function Microwin-NewUnattend {
# Save unattended answer file with UTF-8 encoding # Save unattended answer file with UTF-8 encoding
$unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8 $unattend | Out-File -FilePath "$env:temp\unattend.xml" -Force -Encoding utf8
} }
function New-CheckInstall {
# using here string to embedd firstrun
$checkInstall = @'
@echo off
if exist "C:\windows\cpu.txt" (
echo C:\windows\cpu.txt exists
) else (
echo C:\windows\cpu.txt does not exist
)
if exist "C:\windows\SerialNumber.txt" (
echo C:\windows\SerialNumber.txt exists
) else (
echo C:\windows\SerialNumber.txt does not exist
)
if exist "C:\unattend.xml" (
echo C:\unattend.xml exists
) else (
echo C:\unattend.xml does not exist
)
if exist "C:\Windows\Setup\Scripts\SetupComplete.cmd" (
echo C:\Windows\Setup\Scripts\SetupComplete.cmd exists
) else (
echo C:\Windows\Setup\Scripts\SetupComplete.cmd does not exist
)
if exist "C:\Windows\Panther\unattend.xml" (
echo C:\Windows\Panther\unattend.xml exists
) else (
echo C:\Windows\Panther\unattend.xml does not exist
)
if exist "C:\Windows\System32\Sysprep\unattend.xml" (
echo C:\Windows\System32\Sysprep\unattend.xml exists
) else (
echo C:\Windows\System32\Sysprep\unattend.xml does not exist
)
if exist "C:\Windows\FirstStartup.ps1" (
echo C:\Windows\FirstStartup.ps1 exists
) else (
echo C:\Windows\FirstStartup.ps1 does not exist
)
if exist "C:\Windows\winutil.ps1" (
echo C:\Windows\winutil.ps1 exists
) else (
echo C:\Windows\winutil.ps1 does not exist
)
if exist "C:\Windows\LogSpecialize.txt" (
echo C:\Windows\LogSpecialize.txt exists
) else (
echo C:\Windows\LogSpecialize.txt does not exist
)
if exist "C:\Windows\LogAuditUser.txt" (
echo C:\Windows\LogAuditUser.txt exists
) else (
echo C:\Windows\LogAuditUser.txt does not exist
)
if exist "C:\Windows\LogOobeSystem.txt" (
echo C:\Windows\LogOobeSystem.txt exists
) else (
echo C:\Windows\LogOobeSystem.txt does not exist
)
if exist "c:\windows\csup.txt" (
echo c:\windows\csup.txt exists
) else (
echo c:\windows\csup.txt does not exist
)
if exist "c:\windows\LogFirstRun.txt" (
echo c:\windows\LogFirstRun.txt exists
) else (
echo c:\windows\LogFirstRun.txt does not exist
)
'@
$checkInstall | Out-File -FilePath "$env:temp\checkinstall.cmd" -Force -Encoding Ascii
}
function New-FirstRun {
# using here string to embedd firstrun
$firstRun = @'
# Set the global error action preference to continue
$ErrorActionPreference = "Continue"
function Remove-RegistryValue {
param (
[Parameter(Mandatory = $true)]
[string]$RegistryPath,
[Parameter(Mandatory = $true)]
[string]$ValueName
)
# Check if the registry path exists
if (Test-Path -Path $RegistryPath) {
$registryValue = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue
# Check if the registry value exists
if ($registryValue) {
# Remove the registry value
Remove-ItemProperty -Path $RegistryPath -Name $ValueName -Force
Write-Host "Registry value '$ValueName' removed from '$RegistryPath'."
} else {
Write-Host "Registry value '$ValueName' not found in '$RegistryPath'."
}
} else {
Write-Host "Registry path '$RegistryPath' not found."
}
}
"FirstStartup has worked" | Out-File -FilePath c:\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 "C:\Users\Default\Desktop\*.lnk"
# ************************************************
# Create WinUtil shortcut on the desktop
#
$desktopPath = "$($env:USERPROFILE)\Desktop"
# Specify the target PowerShell command
$command = "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command 'irm https://christitus.com/win | iex'"
# Specify the path for the shortcut
$shortcutPath = Join-Path $desktopPath 'winutil.lnk'
# Create a shell object
$shell = New-Object -ComObject WScript.Shell
# Create a shortcut object
$shortcut = $shell.CreateShortcut($shortcutPath)
if (Test-Path -Path "c:\Windows\cttlogo.png") {
$shortcut.IconLocation = "c:\Windows\cttlogo.png"
}
# Set properties of the shortcut
$shortcut.TargetPath = "powershell.exe"
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `"$command`""
# Save the shortcut
$shortcut.Save()
# Make the shortcut have 'Run as administrator' property on
$bytes = [System.IO.File]::ReadAllBytes($shortcutPath)
# Set byte value at position 0x15 in hex, or 21 in decimal, from the value 0x00 to 0x20 in hex
$bytes[0x15] = $bytes[0x15] -bor 0x20
[System.IO.File]::WriteAllBytes($shortcutPath, $bytes)
Write-Host "Shortcut created at: $shortcutPath"
#
# Done create WinUtil shortcut on the desktop
# ************************************************
Start-Process explorer
'@
$firstRun | Out-File -FilePath "$env:temp\FirstStartup.ps1" -Force
}

View File

@ -1,81 +0,0 @@
function Invoke-WinUtilSSHServer {
<#
.SYNOPSIS
Enables OpenSSH server to remote into your windows device
#>
# Get the latest version of OpenSSH Server
$FeatureName = Get-WindowsCapability -Online | Where-Object { $_.Name -like "OpenSSH.Server*" }
# Install the OpenSSH Server feature if not already installed
if ($FeatureName.State -ne "Installed") {
Write-Host "Enabling OpenSSH Server"
Add-WindowsCapability -Online -Name $FeatureName.Name
}
# Sets up the OpenSSH Server service
Write-Host "Starting the services"
Start-Service -Name sshd
Set-Service -Name sshd -StartupType Automatic
# Sets up the ssh-agent service
Start-Service 'ssh-agent'
Set-Service -Name 'ssh-agent' -StartupType 'Automatic'
# Confirm the required services are running
$SSHDaemonService = Get-Service -Name sshd
$SSHAgentService = Get-Service -Name 'ssh-agent'
if ($SSHDaemonService.Status -eq 'Running') {
Write-Host "OpenSSH Server is running."
} else {
try {
Write-Host "OpenSSH Server is not running. Attempting to restart..."
Restart-Service -Name sshd -Force
Write-Host "OpenSSH Server has been restarted successfully."
} catch {
Write-Host "Failed to restart OpenSSH Server: $_"
}
}
if ($SSHAgentService.Status -eq 'Running') {
Write-Host "ssh-agent is running."
} else {
try {
Write-Host "ssh-agent is not running. Attempting to restart..."
Restart-Service -Name sshd -Force
Write-Host "ssh-agent has been restarted successfully."
} catch {
Write-Host "Failed to restart ssh-agent : $_"
}
}
#Adding Firewall rule for port 22
Write-Host "Setting up firewall rules"
$firewallRule = (Get-NetFirewallRule -Name 'sshd').Enabled
if ($firewallRule) {
Write-Host "Firewall rule for OpenSSH Server (sshd) already exists."
} else {
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
Write-Host "Firewall rule for OpenSSH Server created and enabled."
}
# Check for the authorized_keys file
$sshFolderPath = "$env:HOMEDRIVE\$env:HOMEPATH\.ssh"
$authorizedKeysPath = "$sshFolderPath\authorized_keys"
if (-not (Test-Path -Path $sshFolderPath)) {
Write-Host "Creating ssh directory..."
New-Item -Path $sshFolderPath -ItemType Directory -Force
}
if (-not (Test-Path -Path $authorizedKeysPath)) {
Write-Host "Creating authorized_keys file..."
New-Item -Path $authorizedKeysPath -ItemType File -Force
Write-Host "authorized_keys file created at $authorizedKeysPath."
} else {
Write-Host "authorized_keys file already exists at $authorizedKeysPath."
}
Write-Host "OpenSSH server was successfully enabled."
Write-Host "The config file can be located at C:\ProgramData\ssh\sshd_config "
Write-Host "Add your public keys to this file -> $authorizedKeysPath"
}

View File

@ -1,187 +0,0 @@
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
}
}
# 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 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,180 +0,0 @@
function Invoke-WinutilThemeChange {
<#
.SYNOPSIS
Toggles between light and dark themes for a Windows utility application.
.DESCRIPTION
This function toggles the theme of the user interface between 'Light' and 'Dark' modes,
modifying various UI elements such as colors, margins, corner radii, font families, etc.
If the '-init' switch is used, it initializes the theme based on the system's current dark mode setting.
.PARAMETER init
A switch parameter. If set to $true, the function initializes the theme based on the systems current dark mode setting.
.EXAMPLE
Invoke-WinutilThemeChange
# Toggles the theme between 'Light' and 'Dark'.
.EXAMPLE
Invoke-WinutilThemeChange -init
# Initializes the theme based on the system's dark mode and applies the shared theme.
#>
param (
[switch]$init = $false,
[string]$theme
)
function Set-WinutilTheme {
<#
.SYNOPSIS
Applies the specified theme to the application's user interface.
.DESCRIPTION
This internal function applies the given theme by setting the relevant properties
like colors, font families, corner radii, etc., in the UI. It uses the
'Set-ThemeResourceProperty' helper function to modify the application's resources.
.PARAMETER currentTheme
The name of the theme to be applied. Common values are "Light", "Dark", or "shared".
#>
param (
[string]$currentTheme
)
function Set-ThemeResourceProperty {
<#
.SYNOPSIS
Sets a specific UI property in the application's resources.
.DESCRIPTION
This helper function sets a property (e.g., color, margin, corner radius) in the
application's resources, based on the provided type and value. It includes
error handling to manage potential issues while setting a property.
.PARAMETER Name
The name of the resource property to modify (e.g., "MainBackgroundColor", "ButtonBackgroundMouseoverColor").
.PARAMETER Value
The value to assign to the resource property (e.g., "#FFFFFF" for a color).
.PARAMETER Type
The type of the resource, such as "ColorBrush", "CornerRadius", "GridLength", or "FontFamily".
#>
param($Name, $Value, $Type)
try {
# Set the resource property based on its type
$sync.Form.Resources[$Name] = switch ($Type) {
"ColorBrush" { [Windows.Media.SolidColorBrush]::new($Value) }
"Color" {
# Convert hex string to RGB values
$hexColor = $Value.TrimStart("#")
$r = [Convert]::ToInt32($hexColor.Substring(0,2), 16)
$g = [Convert]::ToInt32($hexColor.Substring(2,2), 16)
$b = [Convert]::ToInt32($hexColor.Substring(4,2), 16)
[Windows.Media.Color]::FromRgb($r, $g, $b)
}
"CornerRadius" { [System.Windows.CornerRadius]::new($Value) }
"GridLength" { [System.Windows.GridLength]::new($Value) }
"Thickness" {
# Parse the Thickness value (supports 1, 2, or 4 inputs)
$values = $Value -split ","
switch ($values.Count) {
1 { [System.Windows.Thickness]::new([double]$values[0]) }
2 { [System.Windows.Thickness]::new([double]$values[0], [double]$values[1]) }
4 { [System.Windows.Thickness]::new([double]$values[0], [double]$values[1], [double]$values[2], [double]$values[3]) }
}
}
"FontFamily" { [Windows.Media.FontFamily]::new($Value) }
"Double" { [double]$Value }
default { $Value }
}
}
catch {
# Log a warning if there's an issue setting the property
Write-Warning "Failed to set property $($Name): $_"
}
}
# Retrieve all theme properties from the theme configuration
$themeProperties = $sync.configs.themes.$currentTheme.PSObject.Properties
foreach ($_ in $themeProperties) {
# Apply properties that deal with colors
if ($_.Name -like "*color*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "ColorBrush"
# For certain color properties, also set complementary values (e.g., BorderColor -> CBorderColor) This is required because e.g DropShadowEffect requires a <Color> and not a <SolidColorBrush> object
if ($_.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) {
Set-ThemeResourceProperty -Name "C$($_.Name)" -Value $_.Value -Type "Color"
}
}
# Apply corner radius properties
elseif ($_.Name -like "*Radius*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "CornerRadius"
}
# Apply row height properties
elseif ($_.Name -like "*RowHeight*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "GridLength"
}
# Apply thickness or margin properties
elseif (($_.Name -like "*Thickness*") -or ($_.Name -like "*margin")) {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Thickness"
}
# Apply font family properties
elseif ($_.Name -like "*FontFamily*") {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "FontFamily"
}
# Apply any other properties as doubles (numerical values)
else {
Set-ThemeResourceProperty -Name $_.Name -Value $_.Value -Type "Double"
}
}
}
$LightPreferencePath = "$env:LOCALAPPDATA\winutil\LightTheme.ini"
$DarkPreferencePath = "$env:LOCALAPPDATA\winutil\DarkTheme.ini"
if ($init) {
Set-WinutilTheme -currentTheme "shared"
if (Test-Path $LightPreferencePath) {
$theme = "Light"
}
elseif (Test-Path $DarkPreferencePath) {
$theme = "Dark"
}
else {
$theme = "Auto"
}
}
switch ($theme) {
"Auto" {
$systemUsesDarkMode = Get-WinUtilToggleStatus WPFToggleDarkMode
if ($systemUsesDarkMode) {
Set-WinutilTheme -currentTheme "Dark"
}
else{
Set-WinutilTheme -currentTheme "Light"
}
$themeButtonIcon = [char]0xF08C
Remove-Item $LightPreferencePath -Force -ErrorAction SilentlyContinue
Remove-Item $DarkPreferencePath -Force -ErrorAction SilentlyContinue
}
"Dark" {
Set-WinutilTheme -currentTheme $theme
$themeButtonIcon = [char]0xE708
$null = New-Item $DarkPreferencePath -Force
Remove-Item $LightPreferencePath -Force -ErrorAction SilentlyContinue
}
"Light" {
Set-WinutilTheme -currentTheme $theme
$themeButtonIcon = [char]0xE706
$null = New-Item $LightPreferencePath -Force
Remove-Item $DarkPreferencePath -Force -ErrorAction SilentlyContinue
}
}
# Update the theme selector button with the appropriate icon
$ThemeButton = $sync.Form.FindName("ThemeButton")
$ThemeButton.Content = [string]$themeButtonIcon
}

View File

@ -35,14 +35,8 @@ function Set-WinUtilRegistry {
New-Item -Path $Path -Force -ErrorAction Stop | Out-Null New-Item -Path $Path -Force -ErrorAction Stop | Out-Null
} }
if ($Value -ne "<RemoveEntry>") {
Write-Host "Set $Path\$Name to $Value" 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{
Write-Host "Remove $Path\$Name"
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] {

View File

@ -0,0 +1,83 @@
function Set-WinUtilUITheme {
<#
.SYNOPSIS
Sets the theme of the XAML file
.PARAMETER inputXML
A string representing the XAML object to modify
.PARAMETER customThemeName
The name of the custom theme to set the XAML to. Defaults to 'matrix'
.PARAMETER defaultThemeName
The name of the default theme to use when setting the XAML. Defaults to '_default'
.EXAMPLE
$returnVal = Set-WinUtilUITheme -inputXAML $inputXAML
if ($returnVal[0] -eq "") {
Write-Host "Failed to process inputXML"
} else {
$inputXML = $returnVal[0]
}
# to know which theme this function has used, access the second item in returned value.
Write-Host "Theme used in processing: $($returnVal[1])"
#>
param (
[Parameter(Mandatory, position=0)]
[string]$inputXML,
[Parameter(position=1)]
[string]$customThemeName = 'matrix',
[Parameter(position=2)]
[string]$defaultThemeName = '_default'
)
try {
# Note:
# Reason behind not caching the '$sync.configs.themes` object into a variable,
# because this code can modify the themes object.. meaning it's better to access it
# using the more verbose way, rather than introduce possible bugs into the code, just for the sake of readability.
#
if (-NOT $sync.configs.themes) {
throw [GenericException]::new("[Set-WinUtilTheme] Did not find 'config.themes' inside `$sync variable.")
}
if (-NOT $sync.configs.themes.$defaultThemeName) {
throw [GenericException]::new("[Set-WinUtilTheme] Did not find '$defaultThemeName' theme in the themes config file.")
}
$themeToUse = $customThemeName
if ($sync.configs.themes.$themeToUse) {
# Loop through every default theme option, and modify the custom theme in $sync variable,
# so that it has full options available for other functions to use.
foreach ($option in $sync.configs.themes.$defaultThemeName.PSObject.Properties) {
$optionName = $option.Name
$optionValue = $option.Value
if (-NOT $sync.configs.themes.$themeToUse.$optionName) {
$sync.configs.themes.$themeToUse | Add-Member -MemberType NoteProperty -Name $optionName -Value $optionValue
}
}
} else {
Write-Debug "[Set-WinUtilTheme] Theme '$customThemeName' was not found, using '$defaultThemeName' instead."
$themeToUse = $defaultThemeName
}
foreach ($property in $sync.configs.themes.$themeToUse.PSObject.Properties) {
$key = $property.Name
$value = $property.Value
# Add curly braces around the key
$formattedKey = "{$key}"
# Replace the key with the value in the input XML
$inputXML = $inputXML.Replace($formattedKey, $value)
}
}
catch {
Write-Host "[Set-WinUtilTheme] Unable to apply theme" -ForegroundColor Red
Write-Host "$($psitem.Exception.Message)" -ForegroundColor Red
$inputXML = "" # Make inputXML equal an empty string, indicating something went wrong to the function caller.
}
return @($inputXML, $themeToUse);
}

View File

@ -33,25 +33,25 @@ function Show-CustomDialog {
#> #>
param( param(
[string]$Message, [string]$Message,
[int]$Width = $sync.Form.Resources.CustomDialogWidth, [int]$Width = 300,
[int]$Height = $sync.Form.Resources.CustomDialogHeight, [int]$Height = 200,
[int]$FontSize = $sync.Form.Resources.CustomDialogFontSize, [int]$FontSize = 10,
[int]$HeaderFontSize = $sync.Form.Resources.CustomDialogFontSizeHeader, [int]$HeaderFontSize = 14,
[int]$IconSize = $sync.Form.Resources.CustomDialogLogoSize, [int]$IconSize = 25,
[bool]$EnableScroll = $false [bool]$EnableScroll = $false
) )
Add-Type -AssemblyName PresentationFramework Add-Type -AssemblyName PresentationFramework
# Define theme colors # Define theme colors
$foregroundColor = $sync.Form.Resources.MainForegroundColor $foregroundColor = $sync.configs.themes.$ctttheme.MainForegroundColor
$backgroundColor = $sync.Form.Resources.MainBackgroundColor $backgroundColor = $sync.configs.themes.$ctttheme.MainBackgroundColor
$font = New-Object Windows.Media.FontFamily("Consolas") $font = New-Object Windows.Media.FontFamily("Consolas")
$borderColor = $sync.Form.Resources.BorderColor # ButtonInstallBackgroundColor $borderColor = $sync.configs.themes.$ctttheme.BorderColor # ButtonInstallBackgroundColor
$buttonBackgroundColor = $sync.Form.Resources.ButtonInstallBackgroundColor $buttonBackgroundColor = $sync.configs.themes.$ctttheme.ButtonInstallBackgroundColor
$buttonForegroundColor = $sync.Form.Resources.ButtonInstallForegroundColor $buttonForegroundColor = $sync.configs.themes.$ctttheme.ButtonInstallForegroundColor
$shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA") $shadowColor = [Windows.Media.ColorConverter]::ConvertFromString("#AAAAAAAA")
$logocolor = $sync.Form.Resources.LabelboxForegroundColor $logocolor = $sync.configs.themes.$ctttheme.LabelboxForegroundColor
# Create a custom dialog window # Create a custom dialog window
$dialog = New-Object Windows.Window $dialog = New-Object Windows.Window
@ -162,7 +162,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 = $sync.configs.themes.$ctttheme.LinkForegroundColor
$hyperlink.Add_Click({ $hyperlink.Add_Click({
param($sender, $args) param($sender, $args)
@ -170,11 +170,11 @@ function Show-CustomDialog {
}) })
$hyperlink.Add_MouseEnter({ $hyperlink.Add_MouseEnter({
param($sender, $args) param($sender, $args)
$sender.Foreground = $sync.Form.Resources.LinkHoverForegroundColor $sender.Foreground = $sync.configs.themes.$ctttheme.LinkHoverForegroundColor
}) })
$hyperlink.Add_MouseLeave({ $hyperlink.Add_MouseLeave({
param($sender, $args) param($sender, $args)
$sender.Foreground = $sync.Form.Resources.LinkForegroundColor $sender.Foreground = $sync.configs.themes.$ctttheme.LinkForegroundColor
}) })
$messageTextBlock.Inlines.Add($hyperlink) $messageTextBlock.Inlines.Add($hyperlink)

View File

@ -19,6 +19,7 @@ function Invoke-WPFButton {
} }
Switch -Wildcard ($Button) { Switch -Wildcard ($Button) {
"WPFTab?BT" {Invoke-WPFTab $Button} "WPFTab?BT" {Invoke-WPFTab $Button}
"WPFInstall" {Invoke-WPFInstall} "WPFInstall" {Invoke-WPFInstall}
"WPFUninstall" {Invoke-WPFUnInstall} "WPFUninstall" {Invoke-WPFUnInstall}
@ -53,12 +54,10 @@ 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-MicrowinGetIso} "WPFGetIso" {Invoke-WPFGetIso}
"WPFMicrowin" {Invoke-Microwin} "WPFMicrowin" {Invoke-WPFMicrowin}
"WPFCloseButton" {Invoke-WPFCloseButton} "WPFCloseButton" {Invoke-WPFCloseButton}
"MicrowinScratchDirBT" {Invoke-ScratchDialog} "MicrowinScratchDirBT" {Invoke-ScratchDialog}
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile} "WPFWinUtilPSProfile" {Invoke-WinUtilpsProfile}
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
"WPFWinUtilSSHServer" {Invoke-WinUtilSSHServer}
} }
} }

View File

@ -1,4 +1,4 @@
function Invoke-MicrowinGetIso { function Invoke-WPFGetIso {
<# <#
.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-MicrowinGetIso {
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.")
Microwin-GetOscdimg -oscdimgPath $oscdimgPath Get-Oscdimg -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"
@ -62,8 +62,6 @@ function Invoke-MicrowinGetIso {
} }
} }
if ($sync["ISOmanual"].IsChecked) {
# Open file dialog to let user choose the ISO file
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.initialDirectory = $initialDirectory $openFileDialog.initialDirectory = $initialDirectory
@ -76,66 +74,6 @@ function Invoke-MicrowinGetIso {
$sync.BusyMessage.Visibility="Hidden" $sync.BusyMessage.Visibility="Hidden"
return return
} }
} elseif ($sync["ISOdownloader"].IsChecked) {
# Create folder browsers for user-specified locations
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$isoDownloaderFBD = New-Object System.Windows.Forms.FolderBrowserDialog
$isoDownloaderFBD.Description = "Please specify the path to download the ISO file to:"
$isoDownloaderFBD.ShowNewFolderButton = $true
if ($isoDownloaderFBD.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK)
{
return
}
# Grab the location of the selected path
$targetFolder = $isoDownloaderFBD.SelectedPath
# Auto download newest ISO
# Credit: https://github.com/pbatard/Fido
$fidopath = "$env:temp\Fido.ps1"
$originalLocation = $PSScriptRoot
Invoke-WebRequest "https://github.com/pbatard/Fido/raw/master/Fido.ps1" -OutFile $fidopath
Set-Location -Path $env:temp
# Detect if the first option ("System language") has been selected and get a Fido-approved language from the current culture
$lang = if ($sync["ISOLanguage"].SelectedIndex -eq 0) {
Microwin-GetLangFromCulture -langName (Get-Culture).Name
} else {
$sync["ISOLanguage"].SelectedItem
}
& $fidopath -Win 'Windows 11' -Rel $sync["ISORelease"].SelectedItem -Arch "x64" -Lang $lang -Ed "Windows 11 Home/Pro/Edu"
if (-not $?)
{
Write-Host "Could not download the ISO file. Look at the output of the console for more information."
$msg = "The ISO file could not be downloaded"
[System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
return
}
Set-Location $originalLocation
# Use the FullName property to only grab the file names. Using this property is necessary as, without it, you're passing the usual output of Get-ChildItem
# to the variable, and let's be honest, that does NOT exist in the file system
$filePath = (Get-ChildItem -Path "$env:temp" -Filter "Win11*.iso").FullName | Sort-Object LastWriteTime -Descending | Select-Object -First 1
$fileName = [IO.Path]::GetFileName("$filePath")
if (($targetFolder -ne "") -and (Test-Path "$targetFolder"))
{
try
{
# "Let it download to $env:TEMP and then we **move** it to the file path." - CodingWonders
$destinationFilePath = "$targetFolder\$fileName"
Write-Host "Moving ISO file. Please wait..."
Move-Item -Path "$filePath" -Destination "$destinationFilePath" -Force
$filePath = $destinationFilePath
}
catch
{
Write-Host "Unable to move the ISO file to the location you specified. The downloaded ISO is in the `"$env:TEMP`" folder"
Write-Host "Error information: $($_.Exception.Message)" -ForegroundColor Yellow
}
}
}
Write-Host "File path $($filePath)" Write-Host "File path $($filePath)"
if (-not (Test-Path -Path "$filePath" -PathType Leaf)) { if (-not (Test-Path -Path "$filePath" -PathType Leaf)) {

View File

@ -19,59 +19,45 @@ function Invoke-WPFImpex {
$Config = $null $Config = $null
) )
function ConfigDialog { if ($type -eq "export") {
if (!$Config) { $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog
switch ($type) {
"export" { $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog }
"import" { $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog }
} }
if ($type -eq "import") {
$FileBrowser = New-Object System.Windows.Forms.OpenFileDialog
}
if (-not $Config) {
$FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop')
$FileBrowser.Filter = "JSON Files (*.json)|*.json" $FileBrowser.Filter = "JSON Files (*.json)|*.json"
$FileBrowser.ShowDialog() | Out-Null $FileBrowser.ShowDialog() | Out-Null
if($FileBrowser.FileName -eq "") { if($FileBrowser.FileName -eq "") {
return $null return
} else { } else {
return $FileBrowser.FileName $Config = $FileBrowser.FileName
}
} else {
return $Config
} }
} }
switch ($type) { if ($type -eq "export") {
"export" { $jsonFile = Get-WinUtilCheckBoxes -unCheck $false
try { $jsonFile | ConvertTo-Json | Out-File $FileBrowser.FileName -Force
$Config = ConfigDialog $runscript = "iex ""& { `$(irm christitus.com/win) } -Config '$($FileBrowser.FileName)'"""
if ($Config) { $runscript | Set-Clipboard
$jsonFile = Get-WinUtilCheckBoxes -unCheck $false | ConvertTo-Json
$jsonFile | Out-File $Config -Force
"iex ""& { `$(irm christitus.com/win) } -Config '$Config'""" | Set-Clipboard
} }
} catch { if ($type -eq "import") {
Write-Error "An error occurred while exporting: $_"
}
}
"import" {
try {
$Config = ConfigDialog
if ($Config) {
try {
if ($Config -match '^https?://') {
$jsonFile = (Invoke-WebRequest "$Config").Content | ConvertFrom-Json
} else {
$jsonFile = Get-Content $Config | ConvertFrom-Json $jsonFile = Get-Content $Config | ConvertFrom-Json
$flattenedJson = @()
$jsonFile.PSObject.Properties | ForEach-Object {
$category = $_.Name
foreach ($checkboxName in $_.Value) {
if ($category -ne "Install") {
$flattenedJson += $checkboxName
} }
} catch {
Write-Error "Failed to load the JSON file from the specified path or URL: $_"
return
} }
$flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value }) }
$flattenedJson = [string]$flattenedJson
Invoke-WPFPresets -preset $flattenedJson -imported $true Invoke-WPFPresets -preset $flattenedJson -imported $true
} }
} catch {
Write-Error "An error occurred while importing: $_"
}
}
}
} }

View File

@ -20,7 +20,7 @@ function Invoke-WPFInstall {
return return
} }
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked) $ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
$installHandle = Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock { Invoke-WPFRunspace -ArgumentList $PackagesToInstall,$ChocoPreference -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference) param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) { if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })

View File

@ -1,4 +1,4 @@
function Invoke-Microwin { function Invoke-WPFMicrowin {
<# <#
.DESCRIPTION .DESCRIPTION
Invoke MicroWin routines... Invoke MicroWin routines...
@ -51,6 +51,10 @@ public class PowerManagement {
$index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim() $index = $sync.MicrowinWindowsFlavors.SelectedValue.Split(":")[0].Trim()
Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)" Write-Host "Index chosen: '$index' from $($sync.MicrowinWindowsFlavors.SelectedValue)"
$keepPackages = $sync.WPFMicrowinKeepProvisionedPackages.IsChecked
$keepProvisionedPackages = $sync.WPFMicrowinKeepAppxPackages.IsChecked
$keepDefender = $sync.WPFMicrowinKeepDefender.IsChecked
$keepEdge = $sync.WPFMicrowinKeepEdge.IsChecked
$copyToUSB = $sync.WPFMicrowinCopyToUsb.IsChecked $copyToUSB = $sync.WPFMicrowinCopyToUsb.IsChecked
$injectDrivers = $sync.MicrowinInjectDrivers.IsChecked $injectDrivers = $sync.MicrowinInjectDrivers.IsChecked
$importDrivers = $sync.MicrowinImportDrivers.IsChecked $importDrivers = $sync.MicrowinImportDrivers.IsChecked
@ -76,10 +80,9 @@ 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 ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,10240,0))) -eq $false) { if ((Test-CompatibleImage $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,14 +91,6 @@ public class PowerManagement {
return return
} }
# Detect whether the image to process contains Windows 10 and show warning
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
$msg = "Windows 10 has been detected in the image you want to process. While you can continue, Windows 10 is not a recommended target for MicroWin, and you may not get the full experience."
$dlg_msg = $msg
Write-Host $msg
[System.Windows.MessageBox]::Show($dlg_msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Exclamation)
}
$mountDirExists = Test-Path $mountDir $mountDirExists = Test-Path $mountDir
$scratchDirExists = Test-Path $scratchDir $scratchDirExists = Test-Path $scratchDir
if (-not $mountDirExists -or -not $scratchDirExists) { if (-not $mountDirExists -or -not $scratchDirExists) {
@ -156,69 +151,47 @@ public class PowerManagement {
} }
Write-Host "Remove Features from the image" Write-Host "Remove Features from the image"
Microwin-RemoveFeatures Remove-Features
Write-Host "Removing features complete!" Write-Host "Removing features complete!"
Write-Host "Removing OS packages" Write-Host "Removing OS packages"
Microwin-RemovePackages Remove-Packages
Write-Host "Removing Appx Bloat" Write-Host "Removing Appx Bloat"
Microwin-RemoveProvisionedPackages Remove-ProvisionedPackages
# Detect Windows 11 24H2 and add dependency to FileExp to prevent Explorer look from going back - thanks @WitherOrNot and @thecatontheceiling Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
if ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,26100,1))) -eq $true) { Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
try { Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
if (Test-Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -PathType Leaf) { Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe"
# Found the culprit. Do the following: Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Photo Viewer" -Directory
# 1. Take ownership of the file, from TrustedInstaller to Administrators Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Photo Viewer" -Directory
takeown /F "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /A Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory
# 2. Set ACLs so that we can write to it Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory
icacls "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" /grant "$(Microwin-GetLocalizedUsers -admins $true):(M)" | Out-Host Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory
# 3. Open the file and do the modification Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Mail" -Directory
$appxManifest = Get-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Internet Explorer" -Directory
$originalLine = $appxManifest[13] Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Internet Explorer" -Directory
$dependency = "`n <PackageDependency Name=`"Microsoft.WindowsAppRuntime.CBS`" MinVersion=`"1.0.0.0`" Publisher=`"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US`" />" Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\GameBarPresenceWriter"
$appxManifest[13] = "$originalLine$dependency" Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDriveSetup.exe"
Set-Content -Path "$scratchDir\Windows\SystemApps\MicrosoftWindows.Client.FileExp_cw5n1h2txyewy\appxmanifest.xml" -Value $appxManifest -Force -Encoding utf8 Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDrive.ico"
} Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*narratorquickstart*" -Directory
} Remove-FileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
catch {
# Do nothing
}
}
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LogFiles\WMI\RtBackup" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\DiagTrack" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\InboxApps" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\LocationNotificationWindows.exe"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Photo Viewer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Photo Viewer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Media Player" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Media Player" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Windows Mail" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Windows Mail" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files (x86)\Internet Explorer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Program Files\Internet Explorer" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\GameBarPresenceWriter"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDriveSetup.exe"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\System32\OneDrive.ico"
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*narratorquickstart*" -Directory
Microwin-RemoveFileOrDirectory -pathToDelete "$($scratchDir)\Windows\SystemApps" -mask "*ParentalControls*" -Directory
Write-Host "Removal complete!" Write-Host "Removal complete!"
Write-Host "Create unattend.xml" Write-Host "Create unattend.xml"
#New-Unattend
if ($sync.MicrowinUserName.Text -eq "") if ($sync.MicrowinUserName.Text -eq "")
{ {
Microwin-NewUnattend -userName "User" New-Unattend -userName "User"
} }
else else
{ {
if ($sync.MicrowinUserPassword.Password -eq "") if ($sync.MicrowinUserPassword.Password -eq "")
{ {
Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)" New-Unattend -userName "$($sync.MicrowinUserName.Text)"
} }
else else
{ {
Microwin-NewUnattend -userName "$($sync.MicrowinUserName.Text)" -userPassword "$($sync.MicrowinUserPassword.Password)" New-Unattend -userName "$($sync.MicrowinUserName.Text)" -userPassword "$($sync.MicrowinUserPassword.Password)"
} }
} }
Write-Host "Done Create unattend.xml" Write-Host "Done Create unattend.xml"
@ -231,7 +204,7 @@ public class PowerManagement {
Write-Host "Done Copy unattend.xml" Write-Host "Done Copy unattend.xml"
Write-Host "Create FirstRun" Write-Host "Create FirstRun"
Microwin-NewFirstRun New-FirstRun
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
@ -243,7 +216,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"
Microwin-NewCheckInstall New-CheckInstall
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"
@ -265,9 +238,6 @@ public class PowerManagement {
# Write-Host Error code $LASTEXITCODE # Write-Host Error code $LASTEXITCODE
Write-Host "Done disabling Teams" Write-Host "Done disabling Teams"
Write-Host "Fix Windows Volume Mixer Issue"
reg add "HKLM\zNTUSER\Software\Microsoft\Internet Explorer\LowRegistry\Audio\PolicyConfig\PropertyStore" /f
Write-Host "Bypassing system requirements (system image)" Write-Host "Bypassing system requirements (system image)"
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV1" /t REG_DWORD /d 0 /f
reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f reg add "HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache" /v "SV2" /t REG_DWORD /d 0 /f
@ -319,19 +289,6 @@ 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 ((Microwin-TestCompatibleImage $imgVersion $([System.Version]::new(10,0,21996,1))) -eq $false) {
# We're dealing with Windows 10. Configure sane desktop settings. NOTE: even though stuff to disable News and Interests is there,
# it doesn't seem to work, and I don't want to waste more time dealing with an operating system that will lose support in a year (2025)
# I invite anyone to work on improving stuff for News and Interests, but that won't be me!
Write-Host "Disabling Search Highlights..."
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Feeds\DSB" /v "ShowDynamicContent" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\SearchSettings" /v "IsDynamicSearchBoxEnabled" /t REG_DWORD /d 0 /f
reg add "HKLM\zSOFTWARE\Policies\Microsoft\Dsh" /v "AllowNewsAndInterests" /t REG_DWORD /d 0 /f
reg add "HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" /v "TraySearchBoxVisible" /t REG_DWORD /d 1 /f
}
} catch { } catch {
Write-Error "An unexpected error occurred: $_" Write-Error "An unexpected error occurred: $_"
} finally { } finally {
@ -431,7 +388,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"
Microwin-CopyToUSB("$($SaveDialog.FileName)") Copy-ToUSB("$($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

@ -17,7 +17,7 @@ function Invoke-WPFPresets {
param ( param (
[Parameter(position=0)] [Parameter(position=0)]
[Array]$preset = "", [string]$preset = "",
[Parameter(position=1)] [Parameter(position=1)]
[bool]$imported = $false, [bool]$imported = $false,
@ -51,7 +51,7 @@ function Invoke-WPFPresets {
} }
# Check if the checkbox name exists in the flattened JSON hashtable # Check if the checkbox name exists in the flattened JSON hashtable
if ($CheckBoxesToCheck -contains $checkboxName) { if ($CheckBoxesToCheck.Contains($checkboxName)) {
# If it exists, set IsChecked to true # If it exists, set IsChecked to true
$sync.$checkboxName.IsChecked = $true $sync.$checkboxName.IsChecked = $true
Write-Debug "$checkboxName is checked" Write-Debug "$checkboxName is checked"

View File

@ -11,50 +11,61 @@ function Invoke-WPFRunspace {
.PARAMETER ArgumentList .PARAMETER ArgumentList
A list of arguments to pass to the runspace A list of arguments to pass to the runspace
.PARAMETER ParameterList
A list of named parameters that should be provided.
.EXAMPLE .EXAMPLE
Invoke-WPFRunspace ` Invoke-WPFRunspace `
-ScriptBlock $sync.ScriptsInstallPrograms ` -ScriptBlock $sync.ScriptsInstallPrograms `
-ArgumentList "Installadvancedip,Installbitwarden" ` -ArgumentList "Installadvancedip,Installbitwarden" `
Invoke-WPFRunspace`
-ScriptBlock $sync.ScriptsInstallPrograms `
-ParameterList @(("PackagesToInstall", @("Installadvancedip,Installbitwarden")),("ChocoPreference", $true))
#> #>
[CmdletBinding()] [CmdletBinding()]
Param ( Param (
$ScriptBlock, [Parameter(Mandatory=$true)]
$ArgumentList, [scriptblock]$ScriptBlock,
$ParameterList, [Parameter(Mandatory=$false)]
$DebugPreference [object[]]$ArgumentList,
[Parameter(Mandatory=$false)]
[System.Management.Automation.ActionPreference]$DebugPreference = 'SilentlyContinue'
) )
try {
# Create a PowerShell instance # Create a PowerShell instance
$script:powershell = [powershell]::Create() $powershell = [powershell]::Create()
# Add Scriptblock and Arguments to runspace # Add Scriptblock and Arguments to runspace
$script:powershell.AddScript($ScriptBlock) $powershell.AddScript($ScriptBlock)
$script:powershell.AddArgument($ArgumentList) if ($ArgumentList) {
foreach ($Argument in $ArgumentList) {
foreach ($parameter in $ParameterList) { $powershell.AddArgument($Argument)
$script:powershell.AddParameter($parameter[0], $parameter[1])
} }
$script:powershell.AddArgument($DebugPreference) # Pass DebugPreference to the script block }
$script:powershell.RunspacePool = $sync.runspace $powershell.AddArgument($DebugPreference)
# Execute the RunspacePool # Ensure runspace pool is available
$script:handle = $script:powershell.BeginInvoke() if (-not $sync.runspace -or $sync.runspace.IsDisposed) {
throw "Runspace pool is not initialized or has been disposed."
}
$powershell.RunspacePool = $sync.runspace
# Clean up the RunspacePool threads when they are complete, and invoke the garbage collector to clean up the memory # Execute the RunspacePool asynchronously
if ($script:handle.IsCompleted) { $handle = $powershell.BeginInvoke()
$script:powershell.EndInvoke($script:handle)
$script:powershell.Dispose() # Set up an event to handle completion
$sync.runspace.Dispose() $null = Register-ObjectEvent -InputObject $powershell -EventName InvocationStateChanged -Action {
$sync.runspace.Close() if ($EventArgs.InvocationStateInfo.State -eq "Completed") {
$powershell.EndInvoke($handle)
$powershell.Dispose()
[System.GC]::Collect() [System.GC]::Collect()
Unregister-Event -SourceIdentifier $EventSubscriber.SourceIdentifier
} }
}
# Return the handle # Return the handle
return $handle return $handle
} }
catch {
Write-Error "Error in Invoke-WPFRunspace: $_"
if ($powershell) { $powershell.Dispose() }
throw
}
}

View File

@ -0,0 +1,72 @@
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"
}

View File

@ -10,18 +10,17 @@ function Invoke-WPFTab {
#> #>
Param ( Param ($ClickedTab)
[Parameter(Mandatory,position=0)]
[string]$ClickedTab
)
$tabNav = Get-WinUtilVariables | Where-Object {$psitem -like "WPFTabNav"} $tabNav = Get-WinUtilVariables | Where-Object {$psitem -like "WPFTabNav"}
$tabNumber = [int]($ClickedTab -replace "WPFTab","" -replace "BT","") - 1 $tabNumber = [int]($ClickedTab -replace "WPFTab","" -replace "BT","") - 1
$filter = Get-WinUtilVariables -Type ToggleButton | Where-Object {$psitem -like "WPFTab?BT"} $filter = Get-WinUtilVariables -Type ToggleButton | Where-Object {$psitem -like "WPFTab?BT"}
($sync.GetEnumerator()).where{$psitem.Key -in $filter} | ForEach-Object { $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object {
if ($ClickedTab -ne $PSItem.name) { if ($ClickedTab -ne $PSItem.name) {
$sync[$PSItem.Name].IsChecked = $false $sync[$PSItem.Name].IsChecked = $false
# $tabNumber = [int]($PSItem.Name -replace "WPFTab","" -replace "BT","") - 1
# $sync.$tabNav.Items[$tabNumber].IsSelected = $false
} else { } else {
$sync["$ClickedTab"].IsChecked = $true $sync["$ClickedTab"].IsChecked = $true
$tabNumber = [int]($ClickedTab-replace "WPFTab","" -replace "BT","") - 1 $tabNumber = [int]($ClickedTab-replace "WPFTab","" -replace "BT","") - 1

View File

@ -27,7 +27,7 @@ function Invoke-WPFUIElements {
$window = $sync["Form"] $window = $sync["Form"]
$theme = $sync.Form.Resources $theme = $sync.configs.themes.$ctttheme
$borderstyle = $window.FindResource("BorderStyle") $borderstyle = $window.FindResource("BorderStyle")
$HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle") $HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle")
$ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle") $ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle")
@ -186,7 +186,7 @@ function Invoke-WPFUIElements {
$label.ToolTip = $entryInfo.Description $label.ToolTip = $entryInfo.Description
$label.HorizontalAlignment = "Left" $label.HorizontalAlignment = "Left"
$label.FontSize = $theme.FontSize $label.FontSize = $theme.FontSize
$label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") $label.Foreground = $theme.MainForegroundColor
$dockPanel.Children.Add($label) | Out-Null $dockPanel.Children.Add($label) | Out-Null
$stackPanel.Children.Add($dockPanel) | Out-Null $stackPanel.Children.Add($dockPanel) | Out-Null
@ -207,14 +207,14 @@ function Invoke-WPFUIElements {
$toggleButton.HorizontalAlignment = "Left" $toggleButton.HorizontalAlignment = "Left"
$toggleButton.Height = $theme.TabButtonHeight $toggleButton.Height = $theme.TabButtonHeight
$toggleButton.Width = $theme.TabButtonWidth $toggleButton.Width = $theme.TabButtonWidth
$toggleButton.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "ButtonInstallBackgroundColor") $toggleButton.Background = $theme.ButtonInstallBackgroundColor
$toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") $toggleButton.Foreground = [Windows.Media.Brushes]::White
$toggleButton.FontWeight = [Windows.FontWeights]::Bold $toggleButton.FontWeight = [Windows.FontWeights]::Bold
$textBlock = New-Object Windows.Controls.TextBlock $textBlock = New-Object Windows.Controls.TextBlock
$textBlock.FontSize = $theme.TabButtonFontSize $textBlock.FontSize = $theme.TabButtonFontSize
$textBlock.Background = [Windows.Media.Brushes]::Transparent $textBlock.Background = [Windows.Media.Brushes]::Transparent
$textBlock.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "ButtonInstallForegroundColor") $textBlock.Foreground = $theme.ButtonInstallForegroundColor
$underline = New-Object Windows.Documents.Underline $underline = New-Object Windows.Documents.Underline
$underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1") $underline.Inlines.Add($entryInfo.name -replace "(.).*", "`$1")
@ -292,7 +292,7 @@ function Invoke-WPFUIElements {
$checkBox.FontSize = $theme.FontSize $checkBox.FontSize = $theme.FontSize
$checkBox.ToolTip = $entryInfo.Description $checkBox.ToolTip = $entryInfo.Description
$checkBox.Margin = $theme.CheckBoxMargin $checkBox.Margin = $theme.CheckBoxMargin
if ($entryInfo.Checked -eq $true) { if ($entryInfo.Checked) {
$checkBox.IsChecked = $entryInfo.Checked $checkBox.IsChecked = $entryInfo.Checked
} }
$horizontalStackPanel.Children.Add($checkBox) | Out-Null $horizontalStackPanel.Children.Add($checkBox) | Out-Null

View File

@ -50,14 +50,14 @@ Function Invoke-WPFUltimatePerformance {
} elseif ($State -eq "Disable") { } elseif ($State -eq "Disable") {
# Check if the Ultimate Performance plan is installed by GUID # Check if the Ultimate Performance plan is installed by GUID
$installedPlan = (powercfg -list | Select-String -Pattern "ChrisTitus - Ultimate Power Plan").Line.Split()[3] $installedPlan = powercfg -list | Select-String -Pattern $ultimateGUID
if ($installedPlan) { if ($installedPlan) {
# Extract the GUID of the installed Ultimate Performance plan # Extract the GUID of the installed Ultimate Performance plan
$ultimatePlanGUID = $installedPlan.Line.Split()[3] $ultimatePlanGUID = $installedPlan.Line.Split()[3]
# Set a different power plan as active before deleting the Ultimate Performance plan # Set a different power plan as active before deleting the Ultimate Performance plan
$balancedPlanGUID = 381b4222-f694-41f0-9685-ff5bb260df2e $balancedPlanGUID = (powercfg -list | Select-String -Pattern "Balanced").Line.Split()[3]
powercfg -setactive $balancedPlanGUID powercfg -setactive $balancedPlanGUID
# Delete the Ultimate Performance plan by GUID # Delete the Ultimate Performance plan by GUID

View File

@ -30,7 +30,7 @@ function Invoke-WPFUnInstall {
if($confirm -eq "No") {return} if($confirm -eq "No") {return}
$ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked) $ChocoPreference = $($sync.WPFpreferChocolatey.IsChecked)
Invoke-WPFRunspace -ArgumentList @(("PackagesToInstall", $PackagesToInstall),("ChocoPreference", $ChocoPreference)) -DebugPreference $DebugPreference -ScriptBlock { Invoke-WPFRunspace -ArgumentList $PackagesToInstall, $ChocoPreference -DebugPreference $DebugPreference -ScriptBlock {
param($PackagesToInstall, $ChocoPreference, $DebugPreference) param($PackagesToInstall, $ChocoPreference, $DebugPreference)
if ($PackagesToInstall.count -eq 1) { if ($PackagesToInstall.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })

View File

@ -42,24 +42,4 @@ function Invoke-WPFUpdatesdefault {
Write-Host "===================================================" Write-Host "==================================================="
Write-Host "--- Windows Update Settings Reset to Default ---" Write-Host "--- Windows Update Settings Reset to Default ---"
Write-Host "===================================================" Write-Host "==================================================="
Start-Process -FilePath "secedit" -ArgumentList "/configure /cfg $env:windir\inf\defltbase.inf /db defltbase.sdb /verbose" -Wait
Start-Process -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicyUsers" -Wait
Start-Process -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicy" -Wait
Start-Process -FilePath "gpupdate" -ArgumentList "/force" -Wait
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
Write-Host "==================================================="
Write-Host "--- Windows Local Policies Reset to Default ---"
Write-Host "==================================================="
} }

View File

@ -13,50 +13,66 @@ function Invoke-WPFtweaksbutton {
} }
$Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"]
$DNSChange = $sync["WPFchangedns"].text -ne "Default"
if ($DNSChange) {
Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text Set-WinUtilDNS -DNSProvider $sync["WPFchangedns"].text
}
if ($tweaks.count -eq 0 -and $sync["WPFchangedns"].text -eq "Default") { if ($tweaks.count -eq 0 -and -not $DNSChange) {
$msg = "Please check the tweaks you wish to perform." $msg = "Please check the tweaks you wish to perform or select a DNS provider."
[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
} }
Write-Debug "Number of tweaks to process: $($Tweaks.Count)" Write-Debug "Number of tweaks to process: $($Tweaks.Count)"
# The leading "," in the ParameterList is nessecary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise try {
$tweaksHandle = Invoke-WPFRunspace -ParameterList @(,("tweaks",$tweaks)) -DebugPreference $DebugPreference -ScriptBlock { $handle = Invoke-WPFRunspace -ArgumentList $Tweaks, $DNSChange -DebugPreference $DebugPreference -ScriptBlock {
param( param($Tweaks, $DNSChange, $DebugPreference)
$tweaks,
$DebugPreference
)
Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)" Write-Debug "Inside Number of tweaks to process: $($Tweaks.Count)"
$sync.ProcessRunning = $true $sync.ProcessRunning = $true
if ($Tweaks.count -eq 1) { if ($Tweaks.count -eq 0 -and $DNSChange) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} elseif ($Tweaks.count -eq 1) {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" })
} else { } else {
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" })
} }
# Execute other selected tweaks
# Execute selected tweaks
for ($i = 0; $i -lt $Tweaks.Count; $i++) { for ($i = 0; $i -lt $Tweaks.Count; $i++) {
Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100) $currentTweak = $Tweaks[$i]
Invoke-WinUtilTweaks $tweaks[$i] Set-WinUtilProgressBar -Label "Applying $currentTweak" -Percent ($i / $Tweaks.Count * 100)
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) })
# Apply the current tweak
Invoke-WinUtilTweaks $currentTweak
# Update taskbar progress
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value (($i + 1) / $Tweaks.Count) })
} }
Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100 Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100
$sync.ProcessRunning = $false $sync.ProcessRunning = $false
$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" })
Write-Host "=================================" Write-Host "================================="
Write-Host "-- Tweaks are Finished ---" Write-Host "-- Tweaks are Finished ---"
Write-Host "=================================" Write-Host "================================="
}
# $ButtonType = [System.Windows.MessageBoxButton]::OK # Optionally, you can add code here to update the UI or perform other tasks while the runspace is executing
# $MessageboxTitle = "Tweaks are Finished " # For example, you might want to disable certain UI elements until the runspace completes
# $Messageboxbody = ("Done")
# $MessageIcon = [System.Windows.MessageBoxImage]::Information # If you need to wait for completion before proceeding, you can use:
# [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) # $handle.AsyncWaitHandle.WaitOne()
# But be cautious about blocking the UI thread
Write-Host "Tweaks execution started in background."
}
catch {
Write-Error "Failed to start tweaks execution: $_"
[System.Windows.MessageBox]::Show("An error occurred while starting tweaks execution. Please check the logs for more information.", "Error", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Error)
} }
} }

View File

@ -4,7 +4,6 @@
{{ super() }} {{ super() }}
<div style="color: red; text-align: center; padding: 10px; font-size: 20px;"> <div style="color: red; text-align: center; padding: 10px; font-size: 20px;">
<strong>Announcement:</strong> We are currently not adding any applications to WinUtil and any apps that will be added through a PR will be declined by the maintainer. <strong>Announcement:</strong> We are currently not adding any applications to WinUtil and any apps that will be added through a PR will be declined by the maintainer.
<strong>Announcement:</strong> We are currently reworking the docs to use Hugo rather then mkdocs.
</div> </div>
{% endblock %} {% endblock %}

View File

@ -10,7 +10,7 @@ $InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionSta
$InitialSessionState.Variables.Add($hashVars) $InitialSessionState.Variables.Add($hashVars)
# Get every private function and add them to the session state # Get every private function and add them to the session state
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|Microwin|WPF' } $functions = (Get-ChildItem function:\).where{$_.name -like "*winutil*" -or $_.name -like "*WPF*"}
foreach ($function in $functions) { foreach ($function in $functions) {
$functionDefinition = Get-Content function:\$($function.name) $functionDefinition = Get-Content function:\$($function.name)
$functionEntry = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $($function.name), $functionDefinition $functionEntry = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $($function.name), $functionDefinition
@ -52,6 +52,29 @@ $sync.runspace.Open()
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window' $inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
$defaulttheme = '_default'
if ((Get-WinUtilToggleStatus WPFToggleDarkMode) -eq $True) {
if (Invoke-WinUtilGPU -eq $True) {
$ctttheme = 'Matrix'
} else {
$ctttheme = 'Dark'
}
} else {
$ctttheme = 'Classic'
}
$returnVal = Set-WinUtilUITheme -inputXML $inputXML -customThemeName $ctttheme -defaultThemeName $defaulttheme
if ($returnVal[0] -eq "") {
Write-Host "Failed to statically apply theming to xaml content using Set-WinUtilTheme, please check previous Error/Warning messages." -ForegroundColor Red
Write-Host "Quitting winutil..." -ForegroundColor Red
$sync.runspace.Dispose()
$sync.runspace.Close()
[System.GC]::Collect()
exit 1
}
$inputXML = $returnVal[0]
$ctttheme = $returnVal[1]
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework') [void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML [xml]$XAML = $inputXML
@ -81,35 +104,6 @@ if (-NOT ($readerOperationSuccessful)) {
exit 1 exit 1
} }
# Setup the Window to follow listen for windows Theme Change events and update the winutil theme
# throttle logic needed, because windows seems to send more than one theme change event per change
$lastThemeChangeTime = [datetime]::MinValue
$debounceInterval = [timespan]::FromSeconds(2)
$sync.Form.Add_Loaded({
$interopHelper = New-Object System.Windows.Interop.WindowInteropHelper $sync.Form
$hwndSource = [System.Windows.Interop.HwndSource]::FromHwnd($interopHelper.Handle)
$hwndSource.AddHook({
param (
[System.IntPtr]$hwnd,
[int]$msg,
[System.IntPtr]$wParam,
[System.IntPtr]$lParam,
[ref]$handled
)
# Check for the Event WM_SETTINGCHANGE (0x1001A) and validate that Button shows the icon for "Auto" => [char]0xF08C
if (($msg -eq 0x001A) -and $sync.ThemeButton.Content -eq [char]0xF08C) {
$currentTime = [datetime]::Now
if ($currentTime - $lastThemeChangeTime -gt $debounceInterval) {
Invoke-WinutilThemeChange -theme "Auto"
$script:lastThemeChangeTime = $currentTime
$handled = $true
}
}
return 0
})
})
Invoke-WinutilThemeChange -init $true
# Load the configuration files # Load the configuration files
#Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid" #Invoke-WPFUIElements -configVariable $sync.configs.nav -targetGridName "WPFMainGrid"
Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5 Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "appspanel" -columncount 5
@ -254,34 +248,24 @@ $commonKeyEvents = {
$sync["Form"].Add_PreViewKeyDown($commonKeyEvents) $sync["Form"].Add_PreViewKeyDown($commonKeyEvents)
$sync["Form"].Add_MouseLeftButtonDown({ $sync["Form"].Add_MouseLeftButtonDown({
# Hide Settings and Theme Popup on click anywhere else if ($sync["SettingsPopup"].IsOpen) {
if ($sync.SettingsButton.IsOpen -or $sync["SettingsPopup"].IsOpen = $false
$sync.ThemePopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
$sync.ThemePopup.IsOpen = $false
} }
$sync["Form"].DragMove() $sync["Form"].DragMove()
}) })
$sync["Form"].Add_MouseDoubleClick({ $sync["Form"].Add_MouseDoubleClick({
if ($_.OriginalSource -is [System.Windows.Controls.Grid] -or
$_.OriginalSource -is [System.Windows.Controls.StackPanel]) {
if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) { if ($sync["Form"].WindowState -eq [Windows.WindowState]::Normal) {
$sync["Form"].WindowState = [Windows.WindowState]::Maximized $sync["Form"].WindowState = [Windows.WindowState]::Maximized;
} } else {
else{ $sync["Form"].WindowState = [Windows.WindowState]::Normal;
$sync["Form"].WindowState = [Windows.WindowState]::Normal
}
} }
}) })
$sync["Form"].Add_Deactivated({ $sync["Form"].Add_Deactivated({
Write-Debug "WinUtil lost focus" Write-Debug "WinUtil lost focus"
# Hide Settings and Theme Popup on Winutil Focus Loss if ($sync["SettingsPopup"].IsOpen) {
if ($sync.SettingsButton.IsOpen -or $sync["SettingsPopup"].IsOpen = $false
$sync.ThemePopup.IsOpen) {
$sync.SettingsPopup.IsOpen = $false
$sync.ThemePopup.IsOpen = $false
} }
}) })
@ -399,33 +383,6 @@ Add-Type @"
}) })
# Add event handlers for the RadioButtons
$sync["ISOdownloader"].add_Checked({
$sync["ISORelease"].Visibility = [System.Windows.Visibility]::Visible
$sync["ISOLanguage"].Visibility = [System.Windows.Visibility]::Visible
})
$sync["ISOmanual"].add_Checked({
$sync["ISORelease"].Visibility = [System.Windows.Visibility]::Collapsed
$sync["ISOLanguage"].Visibility = [System.Windows.Visibility]::Collapsed
})
$sync["ISORelease"].Items.Add("24H2") | Out-Null
$sync["ISORelease"].SelectedItem = "24H2"
$sync["ISOLanguage"].Items.Add("System Language ($(Microwin-GetLangFromCulture -langName $((Get-Culture).Name)))") | Out-Null
if ($currentCulture -ne "English International") {
$sync["ISOLanguage"].Items.Add("English International") | Out-Null
}
if ($currentCulture -ne "English") {
$sync["ISOLanguage"].Items.Add("English") | Out-Null
}
if ($sync["ISOLanguage"].Items.Count -eq 1) {
$sync["ISOLanguage"].IsEnabled = $false
}
$sync["ISOLanguage"].SelectedIndex = 0
# Load Checkboxes and Labels outside of the Filter function only once on startup for performance reasons # Load Checkboxes and Labels outside of the Filter function only once on startup for performance reasons
$filter = Get-WinUtilVariables -Type CheckBox $filter = Get-WinUtilVariables -Type CheckBox
$CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter } $CheckBoxes = ($sync.GetEnumerator()).where{ $psitem.Key -in $filter }
@ -448,8 +405,8 @@ $sync["SearchBar"].Add_TextChanged({
$textToSearch = $sync.SearchBar.Text.ToLower() $textToSearch = $sync.SearchBar.Text.ToLower()
foreach ($CheckBox in $CheckBoxes) { foreach ($CheckBox in $CheckBoxes) {
# Skip if the checkbox is null, it doesn't have content or it is the prefer Choco checkbox # Check if the checkbox is null or if it doesn't have content
if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null -or $CheckBox.Name -eq "WPFpreferChocolatey") { if ($CheckBox -eq $null -or $CheckBox.Value -eq $null -or $CheckBox.Value.Content -eq $null) {
continue continue
} }
@ -521,47 +478,15 @@ Set-WinUtilTaskbaritem -overlay "logo"
$sync["Form"].Add_Activated({ $sync["Form"].Add_Activated({
Set-WinUtilTaskbaritem -overlay "logo" Set-WinUtilTaskbaritem -overlay "logo"
}) })
# Define event handler for ThemeButton click
$sync["ThemeButton"].Add_Click({
if ($sync.ThemePopup.IsOpen) {
$sync.ThemePopup.IsOpen = $false
}
else{
$sync.ThemePopup.IsOpen = $true
}
$sync.SettingsPopup.IsOpen = $false
})
# Define event handlers for menu items
$sync["AutoThemeMenuItem"].Add_Click({
$sync.ThemePopup.IsOpen = $false
Invoke-WinutilThemeChange -theme "Auto"
$_.Handled = $false
})
# Define event handlers for menu items
$sync["DarkThemeMenuItem"].Add_Click({
$sync.ThemePopup.IsOpen = $false
Invoke-WinutilThemeChange -theme "Dark"
$_.Handled = $false
})
# Define event handlers for menu items
$sync["LightThemeMenuItem"].Add_Click({
$sync.ThemePopup.IsOpen = $false
Invoke-WinutilThemeChange -theme "Light"
$_.Handled = $false
})
# Define event handler for button click # Define event handler for button click
$sync["SettingsButton"].Add_Click({ $sync["SettingsButton"].Add_Click({
Write-Debug "SettingsButton clicked" Write-Debug "SettingsButton clicked"
if ($sync.SettingsPopup.IsOpen) { if ($sync["SettingsPopup"].IsOpen) {
$sync.SettingsPopup.IsOpen = $false $sync["SettingsPopup"].IsOpen = $false
} else {
$sync["SettingsPopup"].IsOpen = $true
} }
else{
$sync.SettingsPopup.IsOpen = $true
}
$sync.ThemePopup.IsOpen = $false
$_.Handled = $false $_.Handled = $false
}) })
@ -593,8 +518,12 @@ MicroWin : <a href="https://github.com/KonTy">@KonTy</a>
GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a> GitHub : <a href="https://github.com/ChrisTitusTech/winutil">ChrisTitusTech/winutil</a>
Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sync.version)">$($sync.version)</a> Version : <a href="https://github.com/ChrisTitusTech/winutil/releases/tag/$($sync.version)">$($sync.version)</a>
"@ "@
$FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
Show-CustomDialog -Message $authorInfo -LogoSize $LogoSize $HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$LogoSize = $sync.configs.themes.$ctttheme.CustomDialogLogoSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -LogoSize $LogoSize
}) })
$sync["SponsorMenuItem"].Add_Click({ $sync["SponsorMenuItem"].Add_Click({
@ -615,8 +544,12 @@ $sync["SponsorMenuItem"].Add_Click({
$authorInfo += "An error occurred while fetching or processing the sponsors: $_`n" $authorInfo += "An error occurred while fetching or processing the sponsors: $_`n"
} }
Show-CustomDialog -Message $authorInfo -EnableScroll $true $FontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSize
$HeaderFontSize = $sync.configs.themes.$ctttheme.CustomDialogFontSizeHeader
$LogoSize = $sync.configs.themes.$ctttheme.CustomDialogLogoSize
$Width = $sync.configs.themes.$ctttheme.CustomDialogWidth
$Height = $sync.configs.themes.$ctttheme.CustomDialogHeight
Show-CustomDialog -Message $authorInfo -Width $Width -Height $Height -FontSize $FontSize -HeaderFontSize $HeaderFontSize -LogoSize $LogoSize -EnableScroll $true
}) })
$sync["Form"].ShowDialog() | out-null $sync["Form"].ShowDialog() | out-null
Stop-Transcript Stop-Transcript

View File

@ -72,45 +72,80 @@ function Invoke-Preprocessing {
throw "[Invoke-Preprocessing] Invalid Paramter Value for 'WorkingDir', passed value: '$WorkingDir'. Either the path is a File or Non-Existing/Invlid, please double check your code." throw "[Invoke-Preprocessing] Invalid Paramter Value for 'WorkingDir', passed value: '$WorkingDir'. Either the path is a File or Non-Existing/Invlid, please double check your code."
} }
$InternalExcludedFiles = [System.Collections.Generic.List[string]]::new($ExcludedFiles.Count) $count = $ExcludedFiles.Count
ForEach ($excludedFile in $ExcludedFiles) {
$InternalExcludedFiles.Add($excludedFile) | Out-Null # Make sure there's a * at the end of folders in ExcludedFiles list
for ($i = 0; $i -lt $count; $i++) {
$excludedFile = $ExcludedFiles[$i]
$isFolder = ($excludedFile) -match '\\$'
if ($isFolder) { $ExcludedFiles[$i] = $excludedFile + '*' }
} }
# Validate the ExcludedItems List before continuing on, # Validate the ExcludedFiles List before continuing on,
# that's if there's a list in the first place, and '-SkipInternalExcludedFilesValidation' was not provided. # that's if there's a list in the first place, and '-SkipExcludedFilesValidation' was not provided.
if ($ExcludedFiles.Count -gt 0) { if (-not $SkipExcludedFilesValidation) {
ForEach ($excludedFile in $ExcludedFiles) { for ($i = 0; $i -lt $count; $i++) {
$excludedFile = $ExcludedFiles[$i]
$filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))" $filePath = "$(($WorkingDir -replace ('\\$', '')) + '\' + ($excludedFile -replace ('\.\\', '')))"
$files = Get-ChildItem -Recurse -Path "$filePath" -File -Force
if ($files.Count -gt 0) { # Handle paths with wildcards in a different implementation
ForEach ($file in $files) { $matches = ($filePath) -match '^.*?\*'
$InternalExcludedFiles.Add("$($file.FullName)") | Out-Null
if ($matches) {
if (-NOT (Get-ChildItem -Recurse -Path "$filePath" -File -Force)) {
$failedFilesList += "'$filePath', "
}
} else {
if (-NOT (Test-Path -Path "$filePath")) {
$failedFilesList += "'$filePath', "
}
} }
} else { $failedFilesList += "'$filePath', " }
} }
$failedFilesList = $failedFilesList -replace (',\s*$', '') $failedFilesList = $failedFilesList -replace (',\s*$', '')
if ((-not $failedFilesList -eq "") -and (-not $SkipExcludedFilesValidation)) { if (-NOT $failedFilesList -eq "") {
throw "[Invoke-Preprocessing] One or more File Paths and/or File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, the failed to validate are: $failedFilesList" throw "[Invoke-Preprocessing] One or more File Paths and/or File Patterns were not found, you can use '-SkipExcludedFilesValidation' switch to skip this check, the failed to validate are: $failedFilesList"
} }
} }
# Get Files List # Get Files List
[System.Collections.ArrayList]$files = Get-ChildItem -LiteralPath $WorkingDir -Recurse -Exclude $InternalExcludedFiles -File -Force [System.Collections.ArrayList]$files = Get-ChildItem $WorkingDir -Recurse -Exclude $ExcludedFiles -File -Force
$numOfFiles = $files.Count
# Only keep the 'FullName' Property for every entry in the list # Only keep the 'FullName' Property for every entry in the list
for ($i = 0; $i -lt $files.Count; $i++) { for ($i = 0; $i -lt $numOfFiles; $i++) {
$file = $files[$i] $file = $files[$i]
$files[$i] = $file.FullName $files[$i] = $file.FullName
} }
# If a file(s) are found in Exclude List, # If a file(s) are found in Exclude List,
# Remove the file from files list. # Remove the file from files list.
ForEach ($excludedFile in $InternalExcludedFiles) { for ($j = 0; $j -lt $excludedFiles.Count; $j++) {
$index = $files.IndexOf("$excludedFile") # Prepare some variables
$excluded = $excludedFiles[$j]
$pathToFind = ($excluded) -replace ('^\.\\', '')
$pathToFind = $WorkingDir + '\' + $pathToFind
$index = -1 # reset index on every iteration
# Handle paths with wildcards in a different implementation
$matches = ($pathToFind) -match '^.*?\*'
if ($matches) {
$filesToCheck = Get-ChildItem -Recurse -Path "$pathToFind" -File -Force
if ($filesToCheck) {
for ($k = 0; $k -lt $filesToCheck.Count; $k++) {
$fileToCheck = $filesToCheck[$k]
$index = $files.IndexOf("$fileToCheck")
if ($index -ge 0) { $files.RemoveAt($index) } if ($index -ge 0) { $files.RemoveAt($index) }
} }
}
} else {
$index = $files.IndexOf("$pathToFind")
if ($index -ge 0) { $files.RemoveAt($index) }
}
}
# Make sure 'numOfFiles' is synced with the actual Number of Files found in '$files'
# This's done because previous may or may not edit the files list, so we should update it
$numOfFiles = $files.Count $numOfFiles = $files.Count
if ($numOfFiles -eq 0) { if ($numOfFiles -eq 0) {

View File

@ -30,7 +30,7 @@ function RedirectToLatestPreRelease {
if ($latestRelease) { if ($latestRelease) {
$url = "https://github.com/ChrisTitusTech/winutil/releases/download/$latestRelease/winutil.ps1" $url = "https://github.com/ChrisTitusTech/winutil/releases/download/$latestRelease/winutil.ps1"
} else { } else {
Write-Host 'No pre-release version found. This is most likely because the latest release is a full release and no newer pre-release exists.' -ForegroundColor Yellow Write-Host 'Unable to determine latest pre-release version.' -ForegroundColor Red
Write-Host "Using latest Full Release" Write-Host "Using latest Full Release"
$url = "https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1" $url = "https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1"
} }

File diff suppressed because it is too large Load Diff