diff --git a/.github/workflows/close-discussion.yml b/.github/workflows/close-discussion.yml index 252b7823..de919c13 100644 --- a/.github/workflows/close-discussion.yml +++ b/.github/workflows/close-discussion.yml @@ -8,31 +8,36 @@ jobs: closeDiscussion: runs-on: ubuntu-latest steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Check if PR was merged if: github.event.pull_request.merged == true run: echo "PR was merged" - - - name: Extract Discussion Number & Close If any Where Found + + - name: Extract Discussion Number & Close If any Were Found env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} if: github.event.pull_request.merged == true id: extract-discussion run: | - echo '${{ github.event.pull_request.body }}' > pr_body.txt + pr_body="${{ github.event.pull_request.body }}" + discussion_ids=$(echo "$pr_body" | grep -oP '(?i)(resolve|fix|close)[s|d]? #\K[0-9]+') + + if [ -z "$discussion_ids" ]; then + echo "No discussion IDs found." + exit 0 + fi - discussion_ids_arr=() - cat pr_body.txt | grep -i -Po '^\s*(-|\d+\.)?\s*(Resolve(s|d)?)\s*#\d+\s*$|^\s*(-|\d+\.)?\s*(Fix(es|ed)?)\s*#\d+\s*$|^\s*(-|\d+\.)?\s*(Close(s|d)?)\s*#\d+\s*$' | awk -F '#' '{print $2}' > discussion_ids_list.txt - while read -r line; do - discussion_ids_arr+=("$line") - done < discussion_ids_list.txt - - number_of_ids=${#discussion_ids_arr[@]} - for (( i=0; i<${number_of_ids}; i++ )); - do - discussion_id=${discussion_ids_arr[$i]} - echo "$discussion_id" - curl -X PATCH -H "Authorization: token $GITHUB_TOKEN" \ + for discussion_id in $discussion_ids; do + echo "Closing discussion #$discussion_id" + response=$(curl -s -o /dev/null -w "%{http_code}" -X PATCH -H "Authorization: token $GITHUB_TOKEN" \ -d '{"state": "closed"}' \ - 'https://api.github.com/repos/${{ github.repository }}/discussions/$discussion_id' + "https://api.github.com/repos/${{ github.repository }}/discussions/$discussion_id") + + if [ "$response" -ne 200 ]; then + echo "Failed to close discussion #$discussion_id. HTTP status code: $response" + exit 1 + fi done shell: bash diff --git a/.github/workflows/sponsors.yml b/.github/workflows/sponsors.yml index a3516e75..b6b21d18 100644 --- a/.github/workflows/sponsors.yml +++ b/.github/workflows/sponsors.yml @@ -8,6 +8,7 @@ permissions: jobs: deploy: runs-on: ubuntu-latest + if: (github.event_name == 'schedule' && github.repository == 'ChrisTitusTech/winutil') || (github.event_name != 'schedule') steps: - name: Checkout 🛎️ uses: actions/checkout@v4 diff --git a/README.md b/README.md index a4f4fc20..e43bf521 100644 --- a/README.md +++ b/README.md @@ -10,21 +10,20 @@ This utility is a compilation of Windows tasks I perform on each Windows system ## 💡 Usage -Winutil must be run in Admin mode because it performs system-wide tweaks. To achieve this, open PowerShell or Windows Terminal as an administrator. Here are a few ways to do it: +Winutil must be run in Admin mode because it performs system-wide tweaks. To achieve this, run PowerShell as an administrator. Here are a few ways to do it: -1. **Right-Click Method:** +1. **Start menu Method:** - Right-click on the start menu. - Choose "Windows PowerShell (Admin)" (for Windows 10) or "Terminal (Admin)" (for Windows 11). 2. **Search and Launch Method:** - Press the Windows key. - Type "PowerShell" or "Terminal" (for Windows 11). - - Press `Ctrl + Shift + Enter` to launch it with administrator privileges. - + - Press `Ctrl + Shift + Enter` or Right-click and choose "Run as administrator" to launch it with administrator privileges. ### Launch Command -#### Stable Branch +#### Stable Branch (Recommended) ```ps1 irm "https://christitus.com/win" | iex @@ -45,7 +44,6 @@ If you have Issues, refer to [Known Issues](https://christitustech.github.io/win ### [ChrisTitus.com Article](https://christitus.com/windows-tool/) - ## 💖 Support - To morally and mentally support the project, make sure to leave a ⭐️! - EXE Wrapper for $10 @ https://www.cttstore.com/windows-toolbox @@ -54,7 +52,7 @@ If you have Issues, refer to [Known Issues](https://christitustech.github.io/win These are the sponsors that help keep this project alive with monthly contributions. -Gregory NavasarkianYusuke SaitoTriHyderaMark AmosJason A. DiegmuellerwyattJan WilleOwenStefanthaddlDave Jones +Gregory NavasarkianYusuke SaitoTriHyderaMark AmosJason A. DiegmuellerwyattJan WilleOwenStefanthaddlPaulDave Jones ## 🏅 Thanks to all Contributors Thanks a lot for spending your time helping Winutil grow. Thanks a lot! Keep rocking 🍻. diff --git a/config/applications.json b/config/applications.json index b8552dfb..c7ad5a7e 100644 --- a/config/applications.json +++ b/config/applications.json @@ -205,7 +205,7 @@ "content": "Advanced Renamer", "description": "Advanced Renamer is a program for renaming multiple files and folders at once. By configuring renaming methods the names can be manipulated in various ways.", "link": "https://www.advancedrenamer.com/", - "winget": "XP9MD3S1KFCPH1" + "winget": "HulubuluSoftware.AdvancedRenamer" }, "calibre": { "category": "Document", @@ -2466,8 +2466,8 @@ "wingetui": { "category": "Utilities", "choco": "wingetui", - "content": "UnigetUI", - "description": "WingetUI is a graphical user interface for Microsoft's Windows Package Manager (winget).", + "content": "UniGetUI", + "description": "UniGetUI is a GUI for Winget, Chocolatey, and other Windows CLI package managers.", "link": "https://www.marticliment.com/wingetui/", "winget": "SomePythonThings.WingetUIStore" }, diff --git a/config/themes.json b/config/themes.json index 4bc3766b..2c11a09d 100644 --- a/config/themes.json +++ b/config/themes.json @@ -25,6 +25,10 @@ "MicroWinLogoSize": "10", + "ProgressBarForegroundColor": "#FFAC1C", + "ProgressBarBackgroundColor": "Transparent", + "ProgressBarTextColor": "#000000", + "ComboBoxBackgroundColor": "#FFFFFF", "LabelboxForegroundColor": "#000000", "MainForegroundColor": "#000000", @@ -95,6 +99,10 @@ "MicroWinLogoSize": "10", + "ProgressBarForegroundColor": "#222222", + "ProgressBarBackgroundColor": "Transparent", + "ProgressBarTextColor": "#cccccc", + "ComboBoxBackgroundColor": "#000000", "LabelboxForegroundColor": "#FFEE58", "MainForegroundColor": "#9CCC65", @@ -163,6 +171,10 @@ "MicroWinLogoSize": "10", + "ProgressBarForegroundColor": "#222222", + "ProgressBarBackgroundColor": "Transparent", + "ProgressBarTextColor": "#FFFFFF", + "ComboBoxBackgroundColor": "#000000", "LabelboxForegroundColor": "#FFEE58", "MainForegroundColor": "#9CCC65", diff --git a/config/tweaks.json b/config/tweaks.json index c16ba9a6..890a0986 100644 --- a/config/tweaks.json +++ b/config/tweaks.json @@ -3008,6 +3008,22 @@ "Enable-NetAdapterBinding -Name \"*\" -ComponentID ms_tcpip6" ] }, + "WPFTweaksDisableBGapps": { + "Content": "Disable Background Apps", + "Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Win11", + "category": "z__Advanced Tweaks - CAUTION", + "panel": "1", + "Order": "a024_", + "registry": [ + { + "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\BackgroundAccessApplications", + "Name": "GlobalUserDisabled", + "Value": "1", + "OriginalValue": "0", + "Type": "DWord" + } + ] + }, "WPFTweaksDisableFSO": { "Content": "Disable Fullscreen Optimizations", "Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen", @@ -3144,6 +3160,14 @@ "Order": "a204_", "Type": "Toggle" }, + "WPFToggleDetailedBSoD": { + "Content": "Detailed BSoD", + "Description": "If Enabled then you will see a detailed Blue Screen of Death (BSOD) with more information.", + "category": "Customize Preferences", + "panel": "2", + "Order": "a205_", + "Type": "Toggle" + }, "WPFOOSUbutton": { "Content": "Run OO Shutup 10", "category": "z__Advanced Tweaks - CAUTION", diff --git a/functions/private/Get-WinUtilToggleStatus.ps1 b/functions/private/Get-WinUtilToggleStatus.ps1 index 5c9201f4..019978a4 100644 --- a/functions/private/Get-WinUtilToggleStatus.ps1 +++ b/functions/private/Get-WinUtilToggleStatus.ps1 @@ -139,4 +139,12 @@ Function Get-WinUtilToggleStatus { return $true } } + if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") { + $DetailedBSoD = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters + if($DetailedBSoD -eq 0) { + return $false + } else { + return $true + } + } } diff --git a/functions/private/Install-WinUtilProgramWinget.ps1 b/functions/private/Install-WinUtilProgramWinget.ps1 deleted file mode 100644 index d331547b..00000000 --- a/functions/private/Install-WinUtilProgramWinget.ps1 +++ /dev/null @@ -1,114 +0,0 @@ -Function Install-WinUtilProgramWinget { - - <# - .SYNOPSIS - Manages the provided programs using Winget - - .PARAMETER ProgramsToInstall - A list of programs to manage - - .PARAMETER manage - The action to perform on the programs, can be either 'Installing' or 'Uninstalling' - - .NOTES - The triple quotes are required any time you need a " in a normal script block. - The winget Return codes are documented here: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md - #> - - param( - [Parameter(Mandatory, Position=0)] - [PsCustomObject]$ProgramsToInstall, - - [Parameter(Position=1)] - [String]$manage = "Installing" - ) - - $count = $ProgramsToInstall.Count - - Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0 - Write-Host "===========================================" - Write-Host "-- Configuring winget packages ---" - Write-Host "===========================================" - for ($i = 0; $i -lt $count; $i++) { - $Program = $ProgramsToInstall[$i]$failedPackages = @() - Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.winget) $($i + 1) of $count" -PercentComplete $((($i + 1)/$count) * 100) - if($manage -eq "Installing") { - # Install package via ID, if it fails try again with different scope and then with an unelevated prompt. - # Since Install-WinGetPackage might not be directly available, we use winget install command as a workaround. - # Winget, not all installers honor any of the following: System-wide, User Installs, or Unelevated Prompt OR Silent Install Mode. - # This is up to the individual package maintainers to enable these options. Aka. not as clean as Linux Package Managers. - Write-Host "Starting install of $($Program.winget) with winget." - try { - $status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode - if($status -eq 0) { - Write-Host "$($Program.winget) installed successfully." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - if ($status -eq -1978335189) { - Write-Host "$($Program.winget) No applicable update found" - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - Write-Host "Attempt with User scope" - $status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --scope user --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode - if($status -eq 0) { - Write-Host "$($Program.winget) installed successfully with User scope." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - if ($status -eq -1978335189) { - Write-Host "$($Program.winget) No applicable update found" - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - Write-Host "Attempt with User prompt" - $userChoice = [System.Windows.MessageBox]::Show("Do you want to attempt $($Program.winget) installation with specific user credentials? Select 'Yes' to proceed or 'No' to skip.", "User Credential Prompt", [System.Windows.MessageBoxButton]::YesNo) - if ($userChoice -eq 'Yes') { - $getcreds = Get-Credential - $process = Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Credential $getcreds -PassThru -NoNewWindow - Wait-Process -Id $process.Id - $status = $process.ExitCode - } else { - Write-Host "Skipping installation with specific user credentials." - } - if($status -eq 0) { - Write-Host "$($Program.winget) installed successfully with User prompt." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - if ($status -eq -1978335189) { - Write-Host "$($Program.winget) No applicable update found" - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - } catch { - Write-Host "Failed to install $($Program.winget). With winget" - $failedPackages += $Program - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) - } - } - elseif($manage -eq "Uninstalling") { - # Uninstall package via ID using winget directly. - try { - $status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode - if($status -ne 0) { - Write-Host "Failed to uninstall $($Program.winget)." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) - } else { - Write-Host "$($Program.winget) uninstalled successfully." - $failedPackages += $Program - } - } catch { - Write-Host "Failed to uninstall $($Program.winget) due to an error: $_" - $failedPackages += $Program - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) - } - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - } else { - throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage" - } - } - Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed - return $failedPackages; -} diff --git a/functions/private/Invoke-WinUtilDetailedBSoD.ps1 b/functions/private/Invoke-WinUtilDetailedBSoD.ps1 new file mode 100644 index 00000000..691313c9 --- /dev/null +++ b/functions/private/Invoke-WinUtilDetailedBSoD.ps1 @@ -0,0 +1,30 @@ +Function Invoke-WinUtilDetailedBSoD { + <# + + .SYNOPSIS + Enables/Disables Detailed BSoD + (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name 'DisplayParameters').DisplayParameters + + + #> + Param($Enabled) + try { + if ($Enabled -eq $false) { + Write-Host "Enabling Detailed BSoD" + $value = 1 + } else { + Write-Host "Disabling Detailed BSoD" + $value =0 + } + + $Path = "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl" + Set-ItemProperty -Path $Path -Name DisplayParameters -Value $value + } catch [System.Security.SecurityException] { + Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception" + } catch [System.Management.Automation.ItemNotFoundException] { + Write-Warning $psitem.Exception.ErrorRecord + } catch { + Write-Warning "Unable to set $Name due to unhandled exception" + Write-Warning $psitem.Exception.StackTrace + } +} diff --git a/functions/private/Invoke-WinUtilWingetProgram.ps1 b/functions/private/Invoke-WinUtilWingetProgram.ps1 new file mode 100644 index 00000000..e755e618 --- /dev/null +++ b/functions/private/Invoke-WinUtilWingetProgram.ps1 @@ -0,0 +1,169 @@ +Function Invoke-WinUtilWingetProgram { + <# + .SYNOPSIS + Runs the designated action on the provided programs using Winget + + .PARAMETER Programs + A list of programs to process + + .PARAMETER action + The action to perform on the programs, can be either 'Install' or 'Uninstall' + + .NOTES + The triple quotes are required any time you need a " in a normal script block. + The winget Return codes are documented here: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-actionr/winget/returnCodes.md + #> + + param( + [Parameter(Mandatory, Position=0)]$Programs, + + [Parameter(Mandatory, Position=1)] + [ValidateSet("Install", "Uninstall")] + [String]$Action + ) + + Function Invoke-Winget { + <# + .SYNOPSIS + Invokes the winget.exe with the provided arguments and return the exit code + + .PARAMETER wingetId + The Id of the Program that Winget should Install/Uninstall + + .PARAMETER scope + Determines the installation mode. Can be "user" or "machine" (For more info look at the winget documentation) + + .PARAMETER credential + The PSCredential Object of the user that should be used to run winget + + .NOTES + Invoke Winget uses the public variable $Action defined outside the function to determine if a Program should be installed or removed + #> + param ( + [string]$wingetId, + [string]$scope = "", + [PScredential]$credential = $null + ) + + $commonArguments = "--id $wingetId --silent" + $arguments = if ($Action -eq "Install") { + "install $commonArguments --accept-source-agreements --accept-package-agreements $(if ($scope) {" --scope $scope"})" + } else { + "uninstall $commonArguments" + } + + $processParams = @{ + FilePath = "winget" + ArgumentList = $arguments + Wait = $true + PassThru = $true + NoNewWindow = $true + } + + if ($credential) { + $processParams.credential = $credential + } + + return (Start-Process @processParams).ExitCode + } + + Function Invoke-Install { + <# + .SYNOPSIS + Contains the Install Logic and return code handling from winget + + .PARAMETER Program + The Winget ID of the Program that should be installed + #> + param ( + [string]$Program + ) + $status = Invoke-Winget -wingetId $Program + if ($status -eq 0) { + Write-Host "$($Program) installed successfully." + return $true + } elseif ($status -eq -1978335189) { + Write-Host "$($Program) No applicable update found" + return $true + } + + Write-Host "Attempt installation of $($Program) with User scope" + $status = Invoke-Winget -wingetId $Program -scope "user" + if ($status -eq 0) { + Write-Host "$($Program) installed successfully with User scope." + return $true + } elseif ($status -eq -1978335189) { + Write-Host "$($Program) No applicable update found" + return $true + } + + $userChoice = [System.Windows.MessageBox]::Show("Do you want to attempt $($Program) installation with specific user credentials? Select 'Yes' to proceed or 'No' to skip.", "User credential Prompt", [System.Windows.MessageBoxButton]::YesNo) + if ($userChoice -eq 'Yes') { + $getcreds = Get-Credential + $status = Invoke-Winget -wingetId $Program -credential $getcreds + if ($status -eq 0) { + Write-Host "$($Program) installed successfully with User prompt." + return $true + } + } else { + Write-Host "Skipping installation with specific user credentials." + } + + Write-Host "Failed to install $($Program)." + return $false + } + + Function Invoke-Uninstall { + <# + .SYNOPSIS + Contains the Uninstall Logic and return code handling from winget + + .PARAMETER Program + The Winget ID of the Program that should be uninstalled + #> + param ( + [psobject]$Program + ) + + try { + $status = Invoke-Winget -wingetId $Program + if ($status -eq 0) { + Write-Host "$($Program) uninstalled successfully." + return $true + } else { + Write-Host "Failed to uninstall $($Program)." + return $false + } + } catch { + Write-Host "Failed to uninstall $($Program) due to an error: $_" + return $false + } + } + + $count = $Programs.Count + $failedPackages = @() + + Write-Host "===========================================" + Write-Host "-- Configuring winget packages ---" + Write-Host "===========================================" + + for ($i = 0; $i -lt $count; $i++) { + $Program = $Programs[$i] + $result = $false + Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100) + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i / $count)}) + + $result = switch ($Action) { + "Install" {Invoke-Install -Program $Program} + "Uninstall" {Invoke-Uninstall -Program $Program} + default {throw "[Install-WinUtilProgramWinget] Invalid action: $Action"} + } + + if (-not $result) { + $failedPackages += $Program + } + } + + Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100 + return $failedPackages +} diff --git a/functions/private/Set-WinUtilProgressbar.ps1 b/functions/private/Set-WinUtilProgressbar.ps1 new file mode 100644 index 00000000..3984380f --- /dev/null +++ b/functions/private/Set-WinUtilProgressbar.ps1 @@ -0,0 +1,30 @@ +function Set-WinUtilProgressbar{ + <# + .SYNOPSIS + This function is used to Update the Progress Bar displayed in the winutil GUI. + It will be automatically hidden if the user clicks something and no process is running + .PARAMETER Label + The Text to be overlayed onto the Progress Bar + .PARAMETER PERCENT + The percentage of the Progress Bar that should be filled (0-100) + .PARAMETER Hide + If provided, the Progress Bar and the label will be hidden + #> + param( + [string]$Label, + [ValidateRange(0,100)] + [int]$Percent, + $Hide + ) + if ($hide) { + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Visibility = "Collapsed"}) + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBar.Visibility = "Collapsed"}) + } else { + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Visibility = "Visible"}) + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBar.Visibility = "Visible"}) + } + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Content.Text = $label}) + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Content.ToolTip = $label}) + $sync.form.Dispatcher.Invoke([action]{ $sync.ProgressBar.Value = $percent}) + +} diff --git a/functions/public/Invoke-WPFButton.ps1 b/functions/public/Invoke-WPFButton.ps1 index d55017dd..92bec394 100644 --- a/functions/public/Invoke-WPFButton.ps1 +++ b/functions/public/Invoke-WPFButton.ps1 @@ -14,9 +14,12 @@ function Invoke-WPFButton { # Use this to get the name of the button #[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info") - + if (-not $sync.ProcessRunning) { + Set-WinUtilProgressBar -label "" -percent 0 -hide $true + } + Switch -Wildcard ($Button) { - + "WPFTab?BT" {Invoke-WPFTab $Button} "WPFinstall" {Invoke-WPFInstall} "WPFuninstall" {Invoke-WPFUnInstall} diff --git a/functions/public/Invoke-WPFInstall.ps1 b/functions/public/Invoke-WPFInstall.ps1 index 8e033228..842681e8 100644 --- a/functions/public/Invoke-WPFInstall.ps1 +++ b/functions/public/Invoke-WPFInstall.ps1 @@ -29,14 +29,14 @@ function Invoke-WPFInstall { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) } $packagesWinget, $packagesChoco = { - $packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new() + $packagesWinget = [System.Collections.ArrayList]::new() $packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new() foreach ($package in $PackagesToInstall) { if ($package.winget -eq "na") { $packagesChoco.add($package) Write-Host "Queueing $($package.choco) for Chocolatey install" } else { - $packagesWinget.add($package) + $null = $packagesWinget.add($($package.winget)) Write-Host "Queueing $($package.winget) for Winget install" } } @@ -48,7 +48,7 @@ function Invoke-WPFInstall { $errorPackages = @() if($packagesWinget.Count -gt 0) { Install-WinUtilWinget - $errorPackages += Install-WinUtilProgramWinget -ProgramsToInstall $packagesWinget + $errorPackages += Invoke-WinUtilWingetProgram -Action Install -Programs $packagesWinget $errorPackages| ForEach-Object {if($_.choco -ne "na") {$packagesChoco += $_}} } if($packagesChoco.Count -gt 0) { diff --git a/functions/public/Invoke-WPFMicrowin.ps1 b/functions/public/Invoke-WPFMicrowin.ps1 index 1871c08a..a91588b3 100644 --- a/functions/public/Invoke-WPFMicrowin.ps1 +++ b/functions/public/Invoke-WPFMicrowin.ps1 @@ -416,21 +416,15 @@ public class PowerManagement { } Write-Host "[INFO] Using oscdimg.exe from: $oscdimgPath" - #& oscdimg.exe -m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso - #Start-Process -FilePath $oscdimgPath -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso" -NoNewWindow -Wait - #Start-Process -FilePath $oscdimgPath -ArgumentList '-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir `"$($SaveDialog.FileName)`"' -NoNewWindow -Wait - $oscdimgProc = New-Object System.Diagnostics.Process - $oscdimgProc.StartInfo.FileName = $oscdimgPath - $oscdimgProc.StartInfo.Arguments = "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir `"$($SaveDialog.FileName)`"" - $oscdimgProc.StartInfo.CreateNoWindow = $True - $oscdimgProc.StartInfo.WindowStyle = "Hidden" - $oscdimgProc.StartInfo.UseShellExecute = $False - $oscdimgProc.Start() - $oscdimgProc.WaitForExit() + + $oscdimgProc = Start-Process -FilePath "$oscdimgPath" -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin `"$mountDir`" `"$($SaveDialog.FileName)`"" -Wait -PassThru -NoNewWindow + + $LASTEXITCODE = $oscdimgProc.ExitCode + + Write-Host "OSCDIMG Error Level : $($oscdimgProc.ExitCode)" if ($copyToUSB) { Write-Host "Copying target ISO to the USB drive" - #Copy-ToUSB("$env:temp\microwin.iso") Copy-ToUSB("$($SaveDialog.FileName)") if ($?) { Write-Host "Done Copying target ISO to USB drive!" } else { Write-Host "ISO copy failed." } } @@ -447,13 +441,20 @@ public class PowerManagement { Write-Host "`n`nPerforming Cleanup..." Remove-Item -Recurse -Force "$($scratchDir)" Remove-Item -Recurse -Force "$($mountDir)" - #$msg = "Done. ISO image is located here: $env:temp\microwin.iso" $msg = "Done. ISO image is located here: $($SaveDialog.FileName)" Write-Host $msg Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) } else { Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed." + try { + # This creates a new Win32 exception from which we can extract a message in the system language. + # Now, this will NOT throw an exception + $exitCode = New-Object System.ComponentModel.Win32Exception($LASTEXITCODE) + Write-Host "Reason: $($exitCode.Message)" + } catch { + # Could not get error description from Windows APIs + } } $sync.MicrowinOptionsPanel.Visibility = 'Collapsed' diff --git a/functions/public/Invoke-WPFToggle.ps1 b/functions/public/Invoke-WPFToggle.ps1 index c1bdc1c8..d0b79da1 100644 --- a/functions/public/Invoke-WPFToggle.ps1 +++ b/functions/public/Invoke-WPFToggle.ps1 @@ -32,5 +32,6 @@ function Invoke-WPFToggle { "WPFToggleTaskView" {Invoke-WinUtilTaskView $(Get-WinUtilToggleStatus WPFToggleTaskView)} "WPFToggleHiddenFiles" {Invoke-WinUtilHiddenFiles $(Get-WinUtilToggleStatus WPFToggleHiddenFiles)} "WPFToggleTaskbarAlignment" {Invoke-WinUtilTaskbarAlignment $(Get-WinUtilToggleStatus WPFToggleTaskbarAlignment)} + "WPFToggleDetailedBSoD" {Invoke-WinUtilDetailedBSoD $(Get-WinUtilToggleStatus WPFToggleDetailedBSoD)} } } diff --git a/functions/public/Invoke-WPFTweakPS7.ps1 b/functions/public/Invoke-WPFTweakPS7.ps1 index 830d2a3c..3e291c4c 100644 --- a/functions/public/Invoke-WPFTweakPS7.ps1 +++ b/functions/public/Invoke-WPFTweakPS7.ps1 @@ -17,7 +17,7 @@ function Invoke-WPFTweakPS7{ Write-Host "Powershell 7 is already installed." } else { Write-Host "Installing Powershell 7..." - Install-WinUtilProgramWinget -ProgramsToInstall @(@{"winget"="Microsoft.PowerShell"}) + Invoke-WinUtilWingetProgram -Action Install -Programs @("Microsoft.PowerShell") } $targetTerminalName = "PowerShell" } diff --git a/functions/public/Invoke-WPFUnInstall.ps1 b/functions/public/Invoke-WPFUnInstall.ps1 index 528194dc..19aec2d2 100644 --- a/functions/public/Invoke-WPFUnInstall.ps1 +++ b/functions/public/Invoke-WPFUnInstall.ps1 @@ -45,7 +45,7 @@ function Invoke-WPFUnInstall { $packagesChoco.add($package) Write-Host "Queueing $($package.choco) for Chocolatey Uninstall" } else { - $packagesWinget.add($package) + $packagesWinget.add($($package.winget)) Write-Host "Queueing $($package.winget) for Winget Uninstall" } } @@ -56,14 +56,12 @@ function Invoke-WPFUnInstall { # Install all selected programs in new window if($packagesWinget.Count -gt 0) { - Install-WinUtilProgramWinget -ProgramsToInstall $packagesWinget -Manage "Uninstalling" + Invoke-WinUtilWingetProgram -Action Uninstall -Programs $packagesWinget } if($packagesChoco.Count -gt 0) { Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling" } - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) - Write-Host "===========================================" Write-Host "-- Uninstalls have finished ---" Write-Host "===========================================" diff --git a/functions/public/Invoke-WPFtweaksbutton.ps1 b/functions/public/Invoke-WPFtweaksbutton.ps1 index e38ec8b2..a389bcee 100644 --- a/functions/public/Invoke-WPFtweaksbutton.ps1 +++ b/functions/public/Invoke-WPFtweaksbutton.ps1 @@ -35,15 +35,13 @@ function Invoke-WPFtweaksbutton { } else { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) } - $cnt = 0 # Execute other selected tweaks - foreach ($tweak in $Tweaks) { - Write-Debug "This is a tweak to run $tweak count: $cnt" - Invoke-WinUtilTweaks $tweak - $cnt += 1 - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) }) + + for ($i = 0; $i -lt $Tweaks.Count; $i++) { + Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $Tweaks.Count * 100) + Invoke-WinUtilTweaks $tweaks[$i]$sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) }) } - + Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100 $sync.ProcessRunning = $false $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) Write-Host "=================================" diff --git a/functions/public/Invoke-WPFundoall.ps1 b/functions/public/Invoke-WPFundoall.ps1 index a65940e8..826e1576 100644 --- a/functions/public/Invoke-WPFundoall.ps1 +++ b/functions/public/Invoke-WPFundoall.ps1 @@ -12,7 +12,7 @@ function Invoke-WPFundoall { return } - $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] + $tweaks = (Get-WinUtilCheckBoxes)["WPFtweaks"] if ($tweaks.count -eq 0) { $msg = "Please check the tweaks you wish to undo." @@ -20,186 +20,29 @@ function Invoke-WPFundoall { return } - Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock { - param($Tweaks, $DebugPreference) + Invoke-WPFRunspace -ArgumentList $tweaks -DebugPreference $DebugPreference -ScriptBlock { + param($tweaks, $DebugPreference) $sync.ProcessRunning = $true - if ($Tweaks.count -eq 1) { + if ($tweaks.count -eq 1) { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) } else { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) } - $cnt = 0 + - Foreach ($tweak in $tweaks) { - Invoke-WinUtilTweaks $tweak -undo $true - $cnt += 1 - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) }) + for ($i = 0; $i -lt $tweaks.Count; $i++) { + Set-WinUtilProgressBar -Label "Undoing $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100) + Invoke-WinUtiltweaks $tweaks[$i] -undo $true + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$tweaks.Count) }) } + Set-WinUtilProgressBar -Label "Undo Tweaks Finished" -Percent 100 $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 "--- Undo Tweaks are Finished ---" Write-Host "==================================" - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Tweaks are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) } - -<# - - Write-Host "Creating Restore Point in case something bad happens" - Enable-ComputerRestore -Drive "$env:SystemDrive" - Checkpoint-Computer -Description "RestorePoint1" -RestorePointType "MODIFY_SETTINGS" - - Write-Host "Enabling Telemetry..." - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name "AllowTelemetry" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -Type DWord -Value 1 - Write-Host "Enabling Wi-Fi Sense" - Set-ItemProperty -Path "HKLM:\Software\Microsoft\PolicyManager\default\WiFi\AllowWiFiHotSpotReporting" -Name "Value" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\Software\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots" -Name "Value" -Type DWord -Value 1 - Write-Host "Enabling Application suggestions..." - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "ContentDeliveryAllowed" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "OemPreInstalledAppsEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "PreInstalledAppsEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "PreInstalledAppsEverEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SilentInstalledAppsEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-338387Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-338388Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-338389Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-353698Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SystemPaneSuggestionsEnabled" -Type DWord -Value 1 - If (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent") { - Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableWindowsConsumerFeatures" -Type DWord -Value 0 - Write-Host "Enabling Activity History..." - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "EnableActivityFeed" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "PublishUserActivities" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "UploadUserActivities" -Type DWord -Value 1 - Write-Host "Enable Location Tracking..." - If (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location") { - Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" -Name "Value" -Type String -Value "Allow" - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}" -Name "SensorPermissionState" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\lfsvc\Service\Configuration" -Name "Status" -Type DWord -Value 1 - Write-Host "Enabling automatic Maps updates..." - Set-ItemProperty -Path "HKLM:\SYSTEM\Maps" -Name "AutoUpdateEnabled" -Type DWord -Value 1 - Write-Host "Enabling Feedback..." - If (Test-Path "HKCU:\SOFTWARE\Microsoft\Siuf\Rules") { - Remove-Item -Path "HKCU:\SOFTWARE\Microsoft\Siuf\Rules" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Siuf\Rules" -Name "NumberOfSIUFInPeriod" -Type DWord -Value 0 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DoNotShowFeedbackNotifications" -Type DWord -Value 0 - Write-Host "Enabling Tailored Experiences..." - If (Test-Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent") { - Remove-Item -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableTailoredExperiencesWithDiagnosticData" -Type DWord -Value 0 - Write-Host "Disabling Advertising ID..." - If (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo") { - Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" -Name "DisabledByGroupPolicy" -Type DWord -Value 0 - Write-Host "Allow Error reporting..." - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name "Disabled" -Type DWord -Value 0 - Write-Host "Allowing Diagnostics Tracking Service..." - Stop-Service "DiagTrack" -WarningAction SilentlyContinue - Set-Service "DiagTrack" -StartupType Manual - Write-Host "Allowing WAP Push Service..." - Stop-Service "dmwappushservice" -WarningAction SilentlyContinue - Set-Service "dmwappushservice" -StartupType Manual - Write-Host "Allowing Home Groups services..." - Stop-Service "HomeGroupListener" -WarningAction SilentlyContinue - Set-Service "HomeGroupListener" -StartupType Manual - Stop-Service "HomeGroupProvider" -WarningAction SilentlyContinue - Set-Service "HomeGroupProvider" -StartupType Manual - Write-Host "Enabling Storage Sense..." - New-Item -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy" | Out-Null - Write-Host "Allowing Superfetch service..." - Stop-Service "SysMain" -WarningAction SilentlyContinue - Set-Service "SysMain" -StartupType Manual - Write-Host "Setting BIOS time to Local Time instead of UTC..." - Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Type DWord -Value 0 - Write-Host "Enabling Hibernation..." - Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Session Manager\Power" -Name "HibernteEnabled" -Type Dword -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FlyoutMenuSettings" -Name "ShowHibernateOption" -Type Dword -Value 1 - Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization" -Name "NoLockScreen" -ErrorAction SilentlyContinue - - Write-Host "Hiding file operations details..." - If (Test-Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager") { - Remove-Item -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager" -Name "EnthusiastMode" -Type DWord -Value 0 - Write-Host "Showing Task View button..." - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowTaskViewButton" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People" -Name "PeopleBand" -Type DWord -Value 1 - - Write-Host "Changing default Explorer view to Quick Access..." - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "LaunchTo" -Type DWord -Value 0 - - Write-Host "Unrestricting AutoLogger directory" - $autoLoggerDir = "$env:PROGRAMDATA\Microsoft\Diagnosis\ETLLogs\AutoLogger" - icacls $autoLoggerDir /grant:r SYSTEM:`(OI`)`(CI`)F | Out-Null - - Write-Host "Enabling and starting Diagnostics Tracking Service" - Set-Service "DiagTrack" -StartupType Automatic - Start-Service "DiagTrack" - - Write-Host "Hiding known file extensions" - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "HideFileExt" -Type DWord -Value 1 - - Write-Host "Reset Local Group Policies to Stock Defaults" - # cmd /c secedit /configure /cfg %windir%\inf\defltbase.inf /db defltbase.sdb /verbose - cmd /c RD /S /Q "%WinDir%\System32\GroupPolicyUsers" - cmd /c RD /S /Q "%WinDir%\System32\GroupPolicy" - cmd /c gpupdate /force - # Considered using Invoke-GPUpdate but requires module most people won't have installed - - Write-Host "Adjusting visual effects for appearance..." - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "DragFullWindows" -Type String -Value 1 - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "MenuShowDelay" -Type String -Value 400 - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "UserPreferencesMask" -Type Binary -Value ([byte[]](158, 30, 7, 128, 18, 0, 0, 0)) - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop\WindowMetrics" -Name "MinAnimate" -Type String -Value 1 - Set-ItemProperty -Path "HKCU:\Control Panel\Keyboard" -Name "KeyboardDelay" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ListviewAlphaSelect" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ListviewShadow" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarAnimations" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" -Name "VisualFXSetting" -Type DWord -Value 3 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\DWM" -Name "EnableAeroPeek" -Type DWord -Value 1 - Remove-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "HungAppTimeout" -ErrorAction SilentlyContinue - Write-Host "Restoring Clipboard History..." - Remove-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Clipboard" -Name "EnableClipboardHistory" -ErrorAction SilentlyContinue - Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "AllowClipboardHistory" -ErrorAction SilentlyContinue - Write-Host "Enabling Notifications and Action Center" - Remove-Item -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Force - Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications" -Name "ToastEnabled" - Write-Host "Restoring Default Right Click Menu Layout" - Remove-Item -Path "HKCU:\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" -Recurse -Confirm:$false -Force - - Write-Host "Reset News and Interests" - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" -Name "EnableFeeds" -Type DWord -Value 1 - # Remove "News and Interest" from taskbar - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Feeds" -Name "ShellFeedsTaskbarViewMode" -Type DWord -Value 0 - Write-Host "Done - Reverted to Stock Settings" - - Write-Host "Essential Undo Completed" - - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Undo All" - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) - - Write-Host "=================================" - Write-Host "--- Undo All is Finished ---" - Write-Host "=================================" - #> } diff --git a/winutil.ps1 b/winutil.ps1 index aa683a3b..e6e5c218 100644 --- a/winutil.ps1 +++ b/winutil.ps1 @@ -8,7 +8,7 @@ Author : Chris Titus @christitustech Runspace Author: @DeveloperDurp GitHub : https://github.com/ChrisTitusTech - Version : 24.07.25 + Version : 24.07.31 #> param ( [switch]$Debug, @@ -45,7 +45,7 @@ Add-Type -AssemblyName System.Windows.Forms # Variable to sync between runspaces $sync = [Hashtable]::Synchronized(@{}) $sync.PSScriptRoot = $PSScriptRoot -$sync.version = "24.07.25" +$sync.version = "24.07.31" $sync.configs = @{} $sync.ProcessRunning = $false @@ -744,6 +744,15 @@ Function Get-WinUtilToggleStatus { return $true } } + if ($ToggleSwitch -eq "WPFToggleDetailedBSoD") { + $DetailedBSoD = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl').DisplayParameters + if($DetailedBSoD -eq 0) { + return $false + } + else{ + return $true + } + } } function Get-WinUtilVariables { @@ -988,122 +997,6 @@ function Install-WinUtilProgramChoco { return; } -Function Install-WinUtilProgramWinget { - - <# - .SYNOPSIS - Manages the provided programs using Winget - - .PARAMETER ProgramsToInstall - A list of programs to manage - - .PARAMETER manage - The action to perform on the programs, can be either 'Installing' or 'Uninstalling' - - .NOTES - The triple quotes are required any time you need a " in a normal script block. - The winget Return codes are documented here: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-manager/winget/returnCodes.md - #> - - param( - [Parameter(Mandatory, Position=0)] - [PsCustomObject]$ProgramsToInstall, - - [Parameter(Position=1)] - [String]$manage = "Installing" - ) - - $count = $ProgramsToInstall.Count - - Write-Progress -Activity "$manage Applications" -Status "Starting" -PercentComplete 0 - Write-Host "===========================================" - Write-Host "-- Configuring winget packages ---" - Write-Host "===========================================" - for ($i = 0; $i -lt $count; $i++) { - $Program = $ProgramsToInstall[$i] - $failedPackages = @() - Write-Progress -Activity "$manage Applications" -Status "$manage $($Program.winget) $($i + 1) of $count" -PercentComplete $((($i + 1)/$count) * 100) - if($manage -eq "Installing") { - # Install package via ID, if it fails try again with different scope and then with an unelevated prompt. - # Since Install-WinGetPackage might not be directly available, we use winget install command as a workaround. - # Winget, not all installers honor any of the following: System-wide, User Installs, or Unelevated Prompt OR Silent Install Mode. - # This is up to the individual package maintainers to enable these options. Aka. not as clean as Linux Package Managers. - Write-Host "Starting install of $($Program.winget) with winget." - try { - $status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode - if($status -eq 0) { - Write-Host "$($Program.winget) installed successfully." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - if ($status -eq -1978335189) { - Write-Host "$($Program.winget) No applicable update found" - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - Write-Host "Attempt with User scope" - $status = $(Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --scope user --silent --accept-source-agreements --accept-package-agreements" -Wait -PassThru -NoNewWindow).ExitCode - if($status -eq 0) { - Write-Host "$($Program.winget) installed successfully with User scope." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - if ($status -eq -1978335189) { - Write-Host "$($Program.winget) No applicable update found" - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - Write-Host "Attempt with User prompt" - $userChoice = [System.Windows.MessageBox]::Show("Do you want to attempt $($Program.winget) installation with specific user credentials? Select 'Yes' to proceed or 'No' to skip.", "User Credential Prompt", [System.Windows.MessageBoxButton]::YesNo) - if ($userChoice -eq 'Yes') { - $getcreds = Get-Credential - $process = Start-Process -FilePath "winget" -ArgumentList "install --id $($Program.winget) --silent --accept-source-agreements --accept-package-agreements" -Credential $getcreds -PassThru -NoNewWindow - Wait-Process -Id $process.Id - $status = $process.ExitCode - } else { - Write-Host "Skipping installation with specific user credentials." - } - if($status -eq 0) { - Write-Host "$($Program.winget) installed successfully with User prompt." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - if ($status -eq -1978335189) { - Write-Host "$($Program.winget) No applicable update found" - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - continue - } - } catch { - Write-Host "Failed to install $($Program.winget). With winget" - $failedPackages += $Program - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" -value ($x/$count) }) - } - } - elseif($manage -eq "Uninstalling") { - # Uninstall package via ID using winget directly. - try { - $status = $(Start-Process -FilePath "winget" -ArgumentList "uninstall --id $($Program.winget) --silent" -Wait -PassThru -NoNewWindow).ExitCode - if($status -ne 0) { - Write-Host "Failed to uninstall $($Program.winget)." - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) - } else { - Write-Host "$($Program.winget) uninstalled successfully." - $failedPackages += $Program - } - } catch { - Write-Host "Failed to uninstall $($Program.winget) due to an error: $_" - $failedPackages += $Program - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Error" }) - } - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($x/$count) }) - } - else { - throw "[Install-WinUtilProgramWinget] Invalid Value for Parameter 'manage', Provided Value is: $manage" - } - } - Write-Progress -Activity "$manage Applications" -Status "Finished" -Completed - return $failedPackages; -} function Install-WinUtilWinget { <# @@ -2012,6 +1905,40 @@ Function Invoke-WinUtilDarkMode { Write-Warning $psitem.Exception.StackTrace } } +Function Invoke-WinUtilDetailedBSoD { + <# + + .SYNOPSIS + Enables/Disables Detailed BSoD + (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl' -Name 'DisplayParameters').DisplayParameters + + + #> + Param($Enabled) + Try{ + if ($Enabled -eq $false){ + Write-Host "Enabling Detailed BSoD" + $value = 1 + } + else { + Write-Host "Disabling Detailed BSoD" + $value =0 + } + + $Path = "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl" + Set-ItemProperty -Path $Path -Name DisplayParameters -Value $value + } + Catch [System.Security.SecurityException] { + Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception" + } + Catch [System.Management.Automation.ItemNotFoundException] { + Write-Warning $psitem.Exception.ErrorRecord + } + Catch{ + Write-Warning "Unable to set $Name due to unhandled exception" + Write-Warning $psitem.Exception.StackTrace + } +} function Invoke-WinUtilFeatureInstall { <# @@ -2722,6 +2649,177 @@ function Invoke-WinUtilVerboseLogon { Write-Warning $psitem.Exception.StackTrace } } +Function Invoke-WinUtilWingetProgram { + <# + .SYNOPSIS + Runs the designated action on the provided programs using Winget + + .PARAMETER Programs + A list of programs to process + + .PARAMETER action + The action to perform on the programs, can be either 'Install' or 'Uninstall' + + .NOTES + The triple quotes are required any time you need a " in a normal script block. + The winget Return codes are documented here: https://github.com/microsoft/winget-cli/blob/master/doc/windows/package-actionr/winget/returnCodes.md + #> + + param( + [Parameter(Mandatory, Position=0)] + $Programs, + + [Parameter(Mandatory, Position=1)] + [ValidateSet("Install", "Uninstall")] + [String]$Action + ) + + Function Invoke-Winget { + <# + .SYNOPSIS + Invokes the winget.exe with the provided arguments and return the exit code + + .PARAMETER wingetId + The Id of the Program that Winget should Install/Uninstall + + .PARAMETER scope + Determines the installation mode. Can be "user" or "machine" (For more info look at the winget documentation) + + .PARAMETER credential + The PSCredential Object of the user that should be used to run winget + + .NOTES + Invoke Winget uses the public variable $Action defined outside the function to determine if a Program should be installed or removed + #> + param ( + [string]$wingetId, + [string]$scope = "", + [PScredential]$credential = $null + ) + + $commonArguments = "--id $wingetId --silent" + $arguments = if ($Action -eq "Install"){ + "install $commonArguments --accept-source-agreements --accept-package-agreements $(if ($scope) {" --scope $scope"})" + } + else { + "uninstall $commonArguments" + } + + $processParams = @{ + FilePath = "winget" + ArgumentList = $arguments + Wait = $true + PassThru = $true + NoNewWindow = $true + } + + if ($credential) { + $processParams.credential = $credential + } + + return (Start-Process @processParams).ExitCode + } + + Function Invoke-Install { + <# + .SYNOPSIS + Contains the Install Logic and return code handling from winget + + .PARAMETER Program + The Winget ID of the Program that should be installed + #> + param ( + [string]$Program + ) + $status = Invoke-Winget -wingetId $Program + if ($status -eq 0) { + Write-Host "$($Program) installed successfully." + return $true + } elseif ($status -eq -1978335189) { + Write-Host "$($Program) No applicable update found" + return $true + } + + Write-Host "Attempt installation of $($Program) with User scope" + $status = Invoke-Winget -wingetId $Program -scope "user" + if ($status -eq 0) { + Write-Host "$($Program) installed successfully with User scope." + return $true + } elseif ($status -eq -1978335189) { + Write-Host "$($Program) No applicable update found" + return $true + } + + $userChoice = [System.Windows.MessageBox]::Show("Do you want to attempt $($Program) installation with specific user credentials? Select 'Yes' to proceed or 'No' to skip.", "User credential Prompt", [System.Windows.MessageBoxButton]::YesNo) + if ($userChoice -eq 'Yes') { + $getcreds = Get-Credential + $status = Invoke-Winget -wingetId $Program -credential $getcreds + if ($status -eq 0) { + Write-Host "$($Program) installed successfully with User prompt." + return $true + } + } else { + Write-Host "Skipping installation with specific user credentials." + } + + Write-Host "Failed to install $($Program)." + return $false + } + + Function Invoke-Uninstall { + <# + .SYNOPSIS + Contains the Uninstall Logic and return code handling from winget + + .PARAMETER Program + The Winget ID of the Program that should be uninstalled + #> + param ( + [psobject]$Program + ) + + try { + $status = Invoke-Winget -wingetId $Program + if ($status -eq 0) { + Write-Host "$($Program) uninstalled successfully." + return $true + } else { + Write-Host "Failed to uninstall $($Program)." + return $false + } + } catch { + Write-Host "Failed to uninstall $($Program) due to an error: $_" + return $false + } + } + + $count = $Programs.Count + $failedPackages = @() + + Write-Host "===========================================" + Write-Host "-- Configuring winget packages ---" + Write-Host "===========================================" + + for ($i = 0; $i -lt $count; $i++) { + $Program = $Programs[$i] + $result = $false + Set-WinUtilProgressBar -label "$Action $($Program)" -percent ($i / $count * 100) + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i / $count)}) + + $result = switch ($Action) { + "Install" {Invoke-Install -Program $Program} + "Uninstall" {Invoke-Uninstall -Program $Program} + default {throw "[Install-WinUtilProgramWinget] Invalid action: $Action"} + } + + if (-not $result) { + $failedPackages += $Program + } + } + + Set-WinUtilProgressBar -label "$($Action)ation done" -percent 100 + return $failedPackages +} function Remove-WinUtilAPPX { <# @@ -2793,6 +2891,37 @@ function Set-WinUtilDNS { Write-Warning $psitem.Exception.StackTrace } } +function Set-WinUtilProgressbar{ + <# + .SYNOPSIS + This function is used to Update the Progress Bar displayed in the winutil GUI. + It will be automatically hidden if the user clicks something and no process is running + .PARAMETER Label + The Text to be overlayed onto the Progress Bar + .PARAMETER PERCENT + The percentage of the Progress Bar that should be filled (0-100) + .PARAMETER Hide + If provided, the Progress Bar and the label will be hidden + #> + param( + [string]$Label, + [ValidateRange(0,100)] + [int]$Percent, + $Hide + ) + if ($hide){ + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Visibility = "Collapsed"}) + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBar.Visibility = "Collapsed"}) + } + else{ + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Visibility = "Visible"}) + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBar.Visibility = "Visible"}) + } + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Content.Text = $label}) + $sync.form.Dispatcher.Invoke([action]{$sync.ProgressBarLabel.Content.ToolTip = $label}) + $sync.form.Dispatcher.Invoke([action]{ $sync.ProgressBar.Value = $percent}) + +} function Set-WinUtilRegistry { <# @@ -3525,9 +3654,12 @@ function Invoke-WPFButton { # Use this to get the name of the button #[System.Windows.MessageBox]::Show("$Button","Chris Titus Tech's Windows Utility","OK","Info") - + if (-not $sync.ProcessRunning){ + Set-WinUtilProgressBar -label "" -percent 0 -hide $true + } + Switch -Wildcard ($Button){ - + "WPFTab?BT" {Invoke-WPFTab $Button} "WPFinstall" {Invoke-WPFInstall} "WPFuninstall" {Invoke-WPFUnInstall} @@ -4399,14 +4531,14 @@ function Invoke-WPFInstall { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) } $packagesWinget, $packagesChoco = { - $packagesWinget = [System.Collections.Generic.List`1[System.Object]]::new() + $packagesWinget = [System.Collections.ArrayList]::new() $packagesChoco = [System.Collections.Generic.List`1[System.Object]]::new() foreach ($package in $PackagesToInstall) { if ($package.winget -eq "na") { $packagesChoco.add($package) Write-Host "Queueing $($package.choco) for Chocolatey install" } else { - $packagesWinget.add($package) + $null = $packagesWinget.add($($package.winget)) Write-Host "Queueing $($package.winget) for Winget install" } } @@ -4418,7 +4550,7 @@ function Invoke-WPFInstall { $errorPackages = @() if($packagesWinget.Count -gt 0){ Install-WinUtilWinget - $errorPackages += Install-WinUtilProgramWinget -ProgramsToInstall $packagesWinget + $errorPackages += Invoke-WinUtilWingetProgram -Action Install -Programs $packagesWinget $errorPackages| ForEach-Object {if($_.choco -ne "na") {$packagesChoco += $_}} } if($packagesChoco.Count -gt 0){ @@ -4920,22 +5052,16 @@ public class PowerManagement { } Write-Host "[INFO] Using oscdimg.exe from: $oscdimgPath" - #& oscdimg.exe -m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso - #Start-Process -FilePath $oscdimgPath -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir $env:temp\microwin.iso" -NoNewWindow -Wait - #Start-Process -FilePath $oscdimgPath -ArgumentList '-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir `"$($SaveDialog.FileName)`"' -NoNewWindow -Wait - $oscdimgProc = New-Object System.Diagnostics.Process - $oscdimgProc.StartInfo.FileName = $oscdimgPath - $oscdimgProc.StartInfo.Arguments = "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin $mountDir `"$($SaveDialog.FileName)`"" - $oscdimgProc.StartInfo.CreateNoWindow = $True - $oscdimgProc.StartInfo.WindowStyle = "Hidden" - $oscdimgProc.StartInfo.UseShellExecute = $False - $oscdimgProc.Start() - $oscdimgProc.WaitForExit() + + $oscdimgProc = Start-Process -FilePath "$oscdimgPath" -ArgumentList "-m -o -u2 -udfver102 -bootdata:2#p0,e,b$mountDir\boot\etfsboot.com#pEF,e,b$mountDir\efi\microsoft\boot\efisys.bin `"$mountDir`" `"$($SaveDialog.FileName)`"" -Wait -PassThru -NoNewWindow + + $LASTEXITCODE = $oscdimgProc.ExitCode + + Write-Host "OSCDIMG Error Level : $($oscdimgProc.ExitCode)" if ($copyToUSB) { Write-Host "Copying target ISO to the USB drive" - #Copy-ToUSB("$env:temp\microwin.iso") Copy-ToUSB("$($SaveDialog.FileName)") if ($?) { Write-Host "Done Copying target ISO to USB drive!" } else { Write-Host "ISO copy failed." } } @@ -4952,13 +5078,23 @@ public class PowerManagement { Write-Host "`n`nPerforming Cleanup..." Remove-Item -Recurse -Force "$($scratchDir)" Remove-Item -Recurse -Force "$($mountDir)" - #$msg = "Done. ISO image is located here: $env:temp\microwin.iso" $msg = "Done. ISO image is located here: $($SaveDialog.FileName)" Write-Host $msg Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Information) } else { Write-Host "ISO creation failed. The "$($mountDir)" directory has not been removed." + try + { + # This creates a new Win32 exception from which we can extract a message in the system language. + # Now, this will NOT throw an exception + $exitCode = New-Object System.ComponentModel.Win32Exception($LASTEXITCODE) + Write-Host "Reason: $($exitCode.Message)" + } + catch + { + # Could not get error description from Windows APIs + } } $sync.MicrowinOptionsPanel.Visibility = 'Collapsed' @@ -5309,6 +5445,7 @@ function Invoke-WPFToggle { "WPFToggleTaskView" {Invoke-WinUtilTaskView $(Get-WinUtilToggleStatus WPFToggleTaskView)} "WPFToggleHiddenFiles" {Invoke-WinUtilHiddenFiles $(Get-WinUtilToggleStatus WPFToggleHiddenFiles)} "WPFToggleTaskbarAlignment" {Invoke-WinUtilTaskbarAlignment $(Get-WinUtilToggleStatus WPFToggleTaskbarAlignment)} + "WPFToggleDetailedBSoD" {Invoke-WinUtilDetailedBSoD $(Get-WinUtilToggleStatus WPFToggleDetailedBSoD)} } } function Invoke-WPFTweakPS7{ @@ -5330,7 +5467,7 @@ function Invoke-WPFTweakPS7{ Write-Host "Powershell 7 is already installed." } else { Write-Host "Installing Powershell 7..." - Install-WinUtilProgramWinget -ProgramsToInstall @(@{"winget"="Microsoft.PowerShell"}) + Invoke-WinUtilWingetProgram -Action Install -Programs @("Microsoft.PowerShell") } $targetTerminalName = "PowerShell" } @@ -5401,15 +5538,14 @@ function Invoke-WPFtweaksbutton { } else { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) } - $cnt = 0 # Execute other selected tweaks - foreach ($tweak in $Tweaks) { - Write-Debug "This is a tweak to run $tweak count: $cnt" - Invoke-WinUtilTweaks $tweak - $cnt += 1 - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) }) + + for ($i = 0; $i -lt $Tweaks.Count; $i++){ + Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($i / $Tweaks.Count * 100) + Invoke-WinUtilTweaks $tweaks[$i] + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$Tweaks.Count) }) } - + Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100 $sync.ProcessRunning = $false $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" }) Write-Host "=================================" @@ -5490,7 +5626,7 @@ function Invoke-WPFundoall { return } - $Tweaks = (Get-WinUtilCheckBoxes)["WPFTweaks"] + $tweaks = (Get-WinUtilCheckBoxes)["WPFtweaks"] if ($tweaks.count -eq 0){ $msg = "Please check the tweaks you wish to undo." @@ -5498,188 +5634,31 @@ function Invoke-WPFundoall { return } - Invoke-WPFRunspace -ArgumentList $Tweaks -DebugPreference $DebugPreference -ScriptBlock { - param($Tweaks, $DebugPreference) + Invoke-WPFRunspace -ArgumentList $tweaks -DebugPreference $DebugPreference -ScriptBlock { + param($tweaks, $DebugPreference) $sync.ProcessRunning = $true - if ($Tweaks.count -eq 1){ + if ($tweaks.count -eq 1){ $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" }) } else { $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" }) } - $cnt = 0 + - Foreach ($tweak in $tweaks){ - Invoke-WinUtilTweaks $tweak -undo $true - $cnt += 1 - $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($cnt/$Tweaks.Count) }) + for ($i = 0; $i -lt $tweaks.Count; $i++){ + Set-WinUtilProgressBar -Label "Undoing $($tweaks[$i])" -Percent ($i / $tweaks.Count * 100) + Invoke-WinUtiltweaks $tweaks[$i] -undo $true + $sync.form.Dispatcher.Invoke([action]{ Set-WinUtilTaskbaritem -value ($i/$tweaks.Count) }) } + Set-WinUtilProgressBar -Label "Undo Tweaks Finished" -Percent 100 $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 "--- Undo Tweaks are Finished ---" Write-Host "==================================" - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Tweaks are Finished " - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) } - -<# - - Write-Host "Creating Restore Point in case something bad happens" - Enable-ComputerRestore -Drive "$env:SystemDrive" - Checkpoint-Computer -Description "RestorePoint1" -RestorePointType "MODIFY_SETTINGS" - - Write-Host "Enabling Telemetry..." - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\DataCollection" -Name "AllowTelemetry" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "AllowTelemetry" -Type DWord -Value 1 - Write-Host "Enabling Wi-Fi Sense" - Set-ItemProperty -Path "HKLM:\Software\Microsoft\PolicyManager\default\WiFi\AllowWiFiHotSpotReporting" -Name "Value" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\Software\Microsoft\PolicyManager\default\WiFi\AllowAutoConnectToWiFiSenseHotspots" -Name "Value" -Type DWord -Value 1 - Write-Host "Enabling Application suggestions..." - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "ContentDeliveryAllowed" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "OemPreInstalledAppsEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "PreInstalledAppsEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "PreInstalledAppsEverEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SilentInstalledAppsEnabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-338387Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-338388Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-338389Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SubscribedContent-353698Enabled" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager" -Name "SystemPaneSuggestionsEnabled" -Type DWord -Value 1 - If (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent") { - Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableWindowsConsumerFeatures" -Type DWord -Value 0 - Write-Host "Enabling Activity History..." - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "EnableActivityFeed" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "PublishUserActivities" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "UploadUserActivities" -Type DWord -Value 1 - Write-Host "Enable Location Tracking..." - If (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location") { - Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\location" -Name "Value" -Type String -Value "Allow" - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Sensor\Overrides\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}" -Name "SensorPermissionState" -Type DWord -Value 1 - Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\lfsvc\Service\Configuration" -Name "Status" -Type DWord -Value 1 - Write-Host "Enabling automatic Maps updates..." - Set-ItemProperty -Path "HKLM:\SYSTEM\Maps" -Name "AutoUpdateEnabled" -Type DWord -Value 1 - Write-Host "Enabling Feedback..." - If (Test-Path "HKCU:\SOFTWARE\Microsoft\Siuf\Rules") { - Remove-Item -Path "HKCU:\SOFTWARE\Microsoft\Siuf\Rules" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Siuf\Rules" -Name "NumberOfSIUFInPeriod" -Type DWord -Value 0 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DataCollection" -Name "DoNotShowFeedbackNotifications" -Type DWord -Value 0 - Write-Host "Enabling Tailored Experiences..." - If (Test-Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent") { - Remove-Item -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CloudContent" -Name "DisableTailoredExperiencesWithDiagnosticData" -Type DWord -Value 0 - Write-Host "Disabling Advertising ID..." - If (Test-Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo") { - Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\AdvertisingInfo" -Name "DisabledByGroupPolicy" -Type DWord -Value 0 - Write-Host "Allow Error reporting..." - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name "Disabled" -Type DWord -Value 0 - Write-Host "Allowing Diagnostics Tracking Service..." - Stop-Service "DiagTrack" -WarningAction SilentlyContinue - Set-Service "DiagTrack" -StartupType Manual - Write-Host "Allowing WAP Push Service..." - Stop-Service "dmwappushservice" -WarningAction SilentlyContinue - Set-Service "dmwappushservice" -StartupType Manual - Write-Host "Allowing Home Groups services..." - Stop-Service "HomeGroupListener" -WarningAction SilentlyContinue - Set-Service "HomeGroupListener" -StartupType Manual - Stop-Service "HomeGroupProvider" -WarningAction SilentlyContinue - Set-Service "HomeGroupProvider" -StartupType Manual - Write-Host "Enabling Storage Sense..." - New-Item -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\StorageSense\Parameters\StoragePolicy" | Out-Null - Write-Host "Allowing Superfetch service..." - Stop-Service "SysMain" -WarningAction SilentlyContinue - Set-Service "SysMain" -StartupType Manual - Write-Host "Setting BIOS time to Local Time instead of UTC..." - Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" -Name "RealTimeIsUniversal" -Type DWord -Value 0 - Write-Host "Enabling Hibernation..." - Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Session Manager\Power" -Name "HibernteEnabled" -Type Dword -Value 1 - Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FlyoutMenuSettings" -Name "ShowHibernateOption" -Type Dword -Value 1 - Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization" -Name "NoLockScreen" -ErrorAction SilentlyContinue - - Write-Host "Hiding file operations details..." - If (Test-Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager") { - Remove-Item -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager" -Recurse -ErrorAction SilentlyContinue - } - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\OperationStatusManager" -Name "EnthusiastMode" -Type DWord -Value 0 - Write-Host "Showing Task View button..." - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowTaskViewButton" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\People" -Name "PeopleBand" -Type DWord -Value 1 - - Write-Host "Changing default Explorer view to Quick Access..." - Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "LaunchTo" -Type DWord -Value 0 - - Write-Host "Unrestricting AutoLogger directory" - $autoLoggerDir = "$env:PROGRAMDATA\Microsoft\Diagnosis\ETLLogs\AutoLogger" - icacls $autoLoggerDir /grant:r SYSTEM:`(OI`)`(CI`)F | Out-Null - - Write-Host "Enabling and starting Diagnostics Tracking Service" - Set-Service "DiagTrack" -StartupType Automatic - Start-Service "DiagTrack" - - Write-Host "Hiding known file extensions" - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "HideFileExt" -Type DWord -Value 1 - - Write-Host "Reset Local Group Policies to Stock Defaults" - # cmd /c secedit /configure /cfg %windir%\inf\defltbase.inf /db defltbase.sdb /verbose - cmd /c RD /S /Q "%WinDir%\System32\GroupPolicyUsers" - cmd /c RD /S /Q "%WinDir%\System32\GroupPolicy" - cmd /c gpupdate /force - # Considered using Invoke-GPUpdate but requires module most people won't have installed - - Write-Host "Adjusting visual effects for appearance..." - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "DragFullWindows" -Type String -Value 1 - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "MenuShowDelay" -Type String -Value 400 - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "UserPreferencesMask" -Type Binary -Value ([byte[]](158, 30, 7, 128, 18, 0, 0, 0)) - Set-ItemProperty -Path "HKCU:\Control Panel\Desktop\WindowMetrics" -Name "MinAnimate" -Type String -Value 1 - Set-ItemProperty -Path "HKCU:\Control Panel\Keyboard" -Name "KeyboardDelay" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ListviewAlphaSelect" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ListviewShadow" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "TaskbarAnimations" -Type DWord -Value 1 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects" -Name "VisualFXSetting" -Type DWord -Value 3 - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\DWM" -Name "EnableAeroPeek" -Type DWord -Value 1 - Remove-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name "HungAppTimeout" -ErrorAction SilentlyContinue - Write-Host "Restoring Clipboard History..." - Remove-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Clipboard" -Name "EnableClipboardHistory" -ErrorAction SilentlyContinue - Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Name "AllowClipboardHistory" -ErrorAction SilentlyContinue - Write-Host "Enabling Notifications and Action Center" - Remove-Item -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Force - Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications" -Name "ToastEnabled" - Write-Host "Restoring Default Right Click Menu Layout" - Remove-Item -Path "HKCU:\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}" -Recurse -Confirm:$false -Force - - Write-Host "Reset News and Interests" - Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds" -Name "EnableFeeds" -Type DWord -Value 1 - # Remove "News and Interest" from taskbar - Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Feeds" -Name "ShellFeedsTaskbarViewMode" -Type DWord -Value 0 - Write-Host "Done - Reverted to Stock Settings" - - Write-Host "Essential Undo Completed" - - $ButtonType = [System.Windows.MessageBoxButton]::OK - $MessageboxTitle = "Undo All" - $Messageboxbody = ("Done") - $MessageIcon = [System.Windows.MessageBoxImage]::Information - - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) - - Write-Host "=================================" - Write-Host "--- Undo All is Finished ---" - Write-Host "=================================" - #> } function Invoke-WPFUnInstall { <# @@ -5728,7 +5707,7 @@ function Invoke-WPFUnInstall { $packagesChoco.add($package) Write-Host "Queueing $($package.choco) for Chocolatey Uninstall" } else { - $packagesWinget.add($package) + $packagesWinget.add($($package.winget)) Write-Host "Queueing $($package.winget) for Winget Uninstall" } } @@ -5739,14 +5718,12 @@ function Invoke-WPFUnInstall { # Install all selected programs in new window if($packagesWinget.Count -gt 0){ - Install-WinUtilProgramWinget -ProgramsToInstall $packagesWinget -Manage "Uninstalling" + Invoke-WinUtilWingetProgram -Action Uninstall -Programs $packagesWinget } if($packagesChoco.Count -gt 0){ Install-WinUtilProgramChoco -ProgramsToInstall $packagesChoco -Manage "Uninstalling" } - [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) - Write-Host "===========================================" Write-Host "-- Uninstalls have finished ---" Write-Host "===========================================" @@ -6102,7 +6079,7 @@ $sync.configs.applications = '{ "content": "Advanced Renamer", "description": "Advanced Renamer is a program for renaming multiple files and folders at once. By configuring renaming methods the names can be manipulated in various ways.", "link": "https://www.advancedrenamer.com/", - "winget": "XP9MD3S1KFCPH1" + "winget": "HulubuluSoftware.AdvancedRenamer" }, "WPFInstallcalibre": { "category": "Document", @@ -8363,8 +8340,8 @@ $sync.configs.applications = '{ "WPFInstallwingetui": { "category": "Utilities", "choco": "wingetui", - "content": "UnigetUI", - "description": "WingetUI is a graphical user interface for Microsoft's Windows Package Manager (winget).", + "content": "UniGetUI", + "description": "UniGetUI is a GUI for Winget, Chocolatey, and other Windows CLI package managers.", "link": "https://www.marticliment.com/wingetui/", "winget": "SomePythonThings.WingetUIStore" }, @@ -9223,6 +9200,9 @@ $sync.configs.themes = '{ "WinUtilIconSize": "Auto", "SettingsIconFontSize": "18", "MicroWinLogoSize": "10", + "ProgressBarForegroundColor": "#FFAC1C", + "ProgressBarBackgroundColor": "Transparent", + "ProgressBarTextColor": "#000000", "ComboBoxBackgroundColor": "#FFFFFF", "LabelboxForegroundColor": "#000000", "MainForegroundColor": "#000000", @@ -9284,6 +9264,9 @@ $sync.configs.themes = '{ "WinUtilIconSize": "Auto", "SettingsIconFontSize": "18", "MicroWinLogoSize": "10", + "ProgressBarForegroundColor": "#222222", + "ProgressBarBackgroundColor": "Transparent", + "ProgressBarTextColor": "#cccccc", "ComboBoxBackgroundColor": "#000000", "LabelboxForegroundColor": "#FFEE58", "MainForegroundColor": "#9CCC65", @@ -9343,6 +9326,9 @@ $sync.configs.themes = '{ "WinUtilIconSize": "Auto", "SettingsIconFontSize": "18", "MicroWinLogoSize": "10", + "ProgressBarForegroundColor": "#222222", + "ProgressBarBackgroundColor": "Transparent", + "ProgressBarTextColor": "#FFFFFF", "ComboBoxBackgroundColor": "#000000", "LabelboxForegroundColor": "#FFEE58", "MainForegroundColor": "#9CCC65", @@ -12399,6 +12385,22 @@ $sync.configs.tweaks = '{ "Enable-NetAdapterBinding -Name \"*\" -ComponentID ms_tcpip6" ] }, + "WPFTweaksDisableBGapps": { + "Content": "Disable Background Apps", + "Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Win11", + "category": "z__Advanced Tweaks - CAUTION", + "panel": "1", + "Order": "a024_", + "registry": [ + { + "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\BackgroundAccessApplications", + "Name": "GlobalUserDisabled", + "Value": "1", + "OriginalValue": "0", + "Type": "DWord" + } + ] + }, "WPFTweaksDisableFSO": { "Content": "Disable Fullscreen Optimizations", "Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen", @@ -12535,6 +12537,14 @@ $sync.configs.tweaks = '{ "Order": "a204_", "Type": "Toggle" }, + "WPFToggleDetailedBSoD": { + "Content": "Detailed BSoD", + "Description": "If Enabled then you will see a detailed Blue Screen of Death (BSOD) with more information.", + "category": "Customize Preferences", + "panel": "2", + "Order": "a205_", + "Type": "Toggle" + }, "WPFOOSUbutton": { "Content": "Run OO Shutup 10", "category": "z__Advanced Tweaks - CAUTION", @@ -13223,6 +13233,7 @@ $inputXML = ' + @@ -13243,7 +13254,7 @@ $inputXML = ' @@ -13267,9 +13278,38 @@ $inputXML = ' + + + +