<# .NOTES Maintainer : AtiqSoft Upstream : Chris Titus Tech WinUtil (MIT licensed; see THIRD-PARTY-NOTICES.md) Runspace Author: @DeveloperDurp GitHub : https://github.com/ChrisTitusTech Version : 26.07.10 #> param ( [string]$Config, [ValidateSet("Standard", "Minimal", "Advanced", "")] [string]$Preset, [switch]$Offline ) $PARAM_OFFLINE = $false if ($Offline) { $PARAM_OFFLINE = $true } if ($ExecutionContext.SessionState.LanguageMode -ne 'FullLanguage') { Write-Host "AtiqSoft WinCare is unable to run on this system. PowerShell execution is restricted by security policies." -ForegroundColor Red return } if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Output "AtiqSoft WinCare needs to be run as Administrator. Attempting to relaunch." $argList = @() $PSBoundParameters.GetEnumerator() | ForEach-Object { $argList += if ($_.Value -is [switch] -and $_.Value) { "-$($_.Key)" } elseif ($_.Value -is [array]) { "-$($_.Key) $($_.Value -join ',')" } elseif ($_.Value) { "-$($_.Key) '$($_.Value)'" } } $script = if ($PSCommandPath) { "& { & `'$($PSCommandPath)`' $($argList -join ' ') }" } else { "&([ScriptBlock]::Create((irm https://github.com/ChrisTitusTech/winutil/releases/latest/download/winutil.ps1))) $($argList -join ' ')" } $powershellCmd = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" } $processCmd = if (Get-Command wt.exe -ErrorAction SilentlyContinue) { "wt.exe" } else { "$powershellCmd" } if ($processCmd -eq "wt.exe") { Start-Process $processCmd -ArgumentList "$powershellCmd -ExecutionPolicy Bypass -NoProfile -Command `"$script`"" -Verb RunAs } else { Start-Process $processCmd -ArgumentList "-ExecutionPolicy Bypass -NoProfile -Command `"$script`"" -Verb RunAs } break } # Variable to sync between runspaces $sync = [Hashtable]::Synchronized(@{}) $sync.version = "26.07.10" $sync.configs = @{} $sync.Buttons = [System.Collections.Generic.List[PSObject]]::new() $sync.preferences = @{} $sync.ProcessRunning = $false $sync.selectedAppx = [System.Collections.Generic.List[string]]::new() $sync.selectedApps = [System.Collections.Generic.List[string]]::new() $sync.selectedTweaks = [System.Collections.Generic.List[string]]::new() $sync.selectedToggles = [System.Collections.Generic.List[string]]::new() $sync.selectedFeatures = [System.Collections.Generic.List[string]]::new() $sync.currentTab = "Install" $dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" $winutildir = "$env:LocalAppData\winutil" $sync.winutildir = $winutildir $logdir = "$winutildir\logs" $sync.logPath = "$logdir\winutil_$dateTime.log" $sync.transcriptPath = $sync.logPath Start-Transcript -Path $sync.logPath -Append -NoClobber | Out-Null $Host.UI.RawUI.WindowTitle = "AtiqSoft WinCare" Clear-Host function Add-SelectedAppsMenuItem { <# .SYNOPSIS This is a helper function that generates and adds the Menu Items to the Selected Apps Popup. .Parameter name The actual Name of an App like "Chrome" or "Brave" This name is contained in the "Content" property inside the applications.json .PARAMETER key The key which identifies an app object in applications.json For Chrome this would be "WPFInstallchrome" because "WPFInstall" is prepended automatically for each key in applications.json #> param ([string]$name, [string]$key) $selectedAppGrid = New-Object Windows.Controls.Grid $selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "*"})) $selectedAppGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width = "30"})) # Sets the name to the Content as well as the Tooltip, because the parent Popup Border has a fixed width and text could "overflow". # With the tooltip, you can still read the whole entry on hover $selectedAppLabel = New-Object Windows.Controls.Label $selectedAppLabel.Content = $name $selectedAppLabel.ToolTip = $name $selectedAppLabel.HorizontalAlignment = "Left" $selectedAppLabel.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") [System.Windows.Controls.Grid]::SetColumn($selectedAppLabel, 0) $selectedAppGrid.Children.Add($selectedAppLabel) $selectedAppRemoveButton = New-Object Windows.Controls.Button $selectedAppRemoveButton.FontFamily = "Segoe MDL2 Assets" $selectedAppRemoveButton.Content = [string]([char]0xE711) $selectedAppRemoveButton.HorizontalAlignment = "Center" $selectedAppRemoveButton.Tag = $key $selectedAppRemoveButton.ToolTip = "Remove the App from Selection" $selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") $selectedAppRemoveButton.SetResourceReference([Windows.Controls.Control]::StyleProperty, "HoverButtonStyle") # Highlight the Remove icon on Hover $selectedAppRemoveButton.Add_MouseEnter({ $this.Foreground = "Red" }) $selectedAppRemoveButton.Add_MouseLeave({ $this.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") }) $selectedAppRemoveButton.Add_Click({ $sync.($this.Tag).isChecked = $false # On click of the remove button, we only have to uncheck the corresponding checkbox. This will kick of all necessary changes to update the UI }) [System.Windows.Controls.Grid]::SetColumn($selectedAppRemoveButton, 1) $selectedAppGrid.Children.Add($selectedAppRemoveButton) # Add new Element to Popup $sync.selectedAppsstackPanel.Children.Add($selectedAppGrid) } function Close-WinUtilRunspacePool { if ($null -eq $sync -or -not $sync.ContainsKey("runspace") -or $null -eq $sync.runspace) { return } try { if ($sync.runspace.RunspacePoolStateInfo.State -notin @( [System.Management.Automation.Runspaces.RunspacePoolState]::Closed, [System.Management.Automation.Runspaces.RunspacePoolState]::Closing, [System.Management.Automation.Runspaces.RunspacePoolState]::Broken )) { $sync.runspace.Close() } } finally { $sync.runspace.Dispose() $sync.Remove("runspace") } } function Find-AppsByNameOrDescription { <# .SYNOPSIS Searches through the Apps on the Install Tab and hides all entries that do not match the string .DESCRIPTION Filters application entries by name or description using literal string matching. Respects collapsed category state and handles null $sync gracefully. .PARAMETER SearchString The string to be searched for. Wildcards are treated as literal characters. .NOTES - Uses module-scope $sync (no parameter needed; inherits from caller's scope) - Performs literal matching (no wildcard expansion) - Safely handles missing hashtable keys and null UI elements - Protected by try/catch to prevent UI thread crashes #> param( [Parameter(Mandatory = $false)] [string]$SearchString = "" ) # Validate that $sync exists and has required structure if ($null -eq $sync) { Write-Warning "Find-AppsByNameOrDescription: Global `$sync not found. Aborting search." return } if ($null -eq $sync.ItemsControl) { Write-Warning "Find-AppsByNameOrDescription: `$sync.ItemsControl not initialized. Aborting search." return } if ($null -eq $sync.configs -or $null -eq $sync.configs.applicationsHashtable) { Write-Warning "Find-AppsByNameOrDescription: `$sync.configs.applicationsHashtable not initialized. Aborting search." return } try { # Reset the visibility if the search string is empty or the search is cleared if ([string]::IsNullOrWhiteSpace($SearchString)) { $sync.ItemsControl.Items | ForEach-Object { # Each item is a StackPanel container $_.Visibility = [Windows.Visibility]::Visible if ($_.Children.Count -ge 2) { $categoryLabel = $_.Children[0] $wrapPanel = $_.Children[1] # Keep category label visible $categoryLabel.Visibility = [Windows.Visibility]::Visible # Respect the collapsed state of categories (indicated by + prefix) if ($categoryLabel.Content -like "+*") { $wrapPanel.Visibility = [Windows.Visibility]::Collapsed } else { $wrapPanel.Visibility = [Windows.Visibility]::Visible } # Show all apps within the category $wrapPanel.Children | ForEach-Object { $_.Visibility = [Windows.Visibility]::Visible } } } return } # Escape wildcard characters for literal matching $escapedSearchString = [System.Management.Automation.WildcardPattern]::Escape($SearchString) # Perform search $sync.ItemsControl.Items | ForEach-Object { # Each item is a StackPanel container with Children[0] = label, Children[1] = WrapPanel if ($_.Children.Count -ge 2) { $categoryLabel = $_.Children[0] $wrapPanel = $_.Children[1] $categoryHasMatch = $false # Keep category label visible $categoryLabel.Visibility = [Windows.Visibility]::Visible # Search through apps in this category foreach ($appControl in $wrapPanel.Children) { # Safely retrieve app entry from hashtable $appTag = $appControl.Tag $appEntry = $null if (-not [string]::IsNullOrWhiteSpace($appTag) -and $sync.configs.applicationsHashtable.ContainsKey($appTag)) { $appEntry = $sync.configs.applicationsHashtable[$appTag] } # Check if app matches search criteria if ($null -ne $appEntry) { $contentMatch = $appEntry.Content -like "*$escapedSearchString*" $descriptionMatch = $appEntry.Description -like "*$escapedSearchString*" if ($contentMatch -or $descriptionMatch) { # Show the App and mark that this category has a match $appControl.Visibility = [Windows.Visibility]::Visible $categoryHasMatch = $true } else { $appControl.Visibility = [Windows.Visibility]::Collapsed } } else { # Hide app if no entry found (data integrity issue) $appControl.Visibility = [Windows.Visibility]::Collapsed } } # If category has matches, show the WrapPanel and update the category label to expanded state if ($categoryHasMatch) { $wrapPanel.Visibility = [Windows.Visibility]::Visible $_.Visibility = [Windows.Visibility]::Visible # Update category label to show expanded state (-) if ($categoryLabel.Content -like "+*") { $categoryLabel.Content = $categoryLabel.Content -replace "^\+ ", "- " } } else { # Hide the entire category container if no matches $_.Visibility = [Windows.Visibility]::Collapsed } } } } catch { Write-Warning "Find-AppsByNameOrDescription: An error occurred during search: $_" # Fail gracefully - do not crash the UI thread return } } function Find-TweaksByNameOrDescription { <# .SYNOPSIS Searches through the Tweaks on the Tweaks Tab and hides all entries that do not match the search string .DESCRIPTION Filters tweak entries by name or description using literal string matching (no wildcard expansion). Respects collapsed category state and handles null $sync gracefully. Safe for rapid keystroke events; no terminal spam on error conditions. .PARAMETER SearchString The string to be searched for. Wildcards are treated as literal characters. .NOTES - Uses module-scope $sync (resolved via global/script fallback if needed) - Performs literal matching (no wildcard expansion) - Safely handles missing UI elements and null properties - Protected by try/catch to prevent UI thread crashes - PowerShell 5.1 compatible (no ternary operators, no advanced language features) #> param( [Parameter(Mandatory = $false)] [string]$SearchString = "" ) # ------------------------------------------------------------------------------ # 1. RESOLVE $SYNC WITH MULTI-LEVEL FALLBACK # ------------------------------------------------------------------------------ if ($null -eq $Sync) { $Sync = $global:sync if ($null -eq $Sync) { $Sync = $script:sync } } # Validate that $Sync exists and has required structure if ($null -eq $Sync) { # Silent return - function called on every keystroke; no warning spam return } if ($null -eq $Sync.Form) { # Silent return - form not yet initialized return } # ------------------------------------------------------------------------------ # 2. GET REFERENCE TO TWEAKS OR APPX PANEL # ------------------------------------------------------------------------------ $panelName = "tweakspanel" if ($null -ne $Sync.currentTab -and $Sync.currentTab -eq "AppX") { $panelName = "appxpanel" } $tweaksPanel = $null try { $tweaksPanel = $Sync.Form.FindName($panelName) } catch { # Silent return - panel not found or disposed return } if ($null -eq $tweaksPanel) { # Silent return - panel doesn't exist return } # ------------------------------------------------------------------------------ # 3. HANDLE EMPTY/WHITESPACE SEARCH STRING - RESET TO DEFAULT STATE # ------------------------------------------------------------------------------ if ([string]::IsNullOrWhiteSpace($SearchString)) { try { $tweaksPanel.Children | ForEach-Object { $categoryBorder = $_ # Safely set visibility if ($null -ne $categoryBorder) { $categoryBorder.Visibility = [Windows.Visibility]::Visible } # Process each category if ($categoryBorder -is [Windows.Controls.Border]) { $dockPanel = $null if ($null -ne $categoryBorder.Child) { $dockPanel = $categoryBorder.Child } if ($dockPanel -is [Windows.Controls.DockPanel]) { $itemsControl = $null $itemsControl = $dockPanel.Children | Where-Object { $_ -is [Windows.Controls.ItemsControl] } | Select-Object -First 1 if ($null -ne $itemsControl) { # Show all items in the category foreach ($item in $itemsControl.Items) { if ($null -ne $item) { # Check if it's a category label (first Label in the ItemsControl) if ($item -is [Windows.Controls.Label]) { $item.Visibility = [Windows.Visibility]::Visible } elseif ($item -is [Windows.Controls.DockPanel] -or $item -is [Windows.Controls.StackPanel]) { # Show all checkbox containers $item.Visibility = [Windows.Visibility]::Visible } } } } } } } } catch { # Silent catch - UI element may be disposed $null = $_ } return } # ------------------------------------------------------------------------------ # 4. PERFORM LITERAL SEARCH (NO WILDCARD EXPANSION) # ------------------------------------------------------------------------------ try { # Normalize search term once for the entire operation $searchTerm = $SearchString if ($null -eq $searchTerm) { $searchTerm = "" } # Iterate through all categories $tweaksPanel.Children | ForEach-Object { $categoryBorder = $_ $categoryHasMatch = $false if ($categoryBorder -is [Windows.Controls.Border]) { $dockPanel = $null if ($null -ne $categoryBorder.Child) { $dockPanel = $categoryBorder.Child } if ($dockPanel -is [Windows.Controls.DockPanel]) { $itemsControl = $null $itemsControl = $dockPanel.Children | Where-Object { $_ -is [Windows.Controls.ItemsControl] } | Select-Object -First 1 if ($null -ne $itemsControl) { $categoryLabel = $null # Process all items (checkboxes, labels, panels) in the ItemsControl for ($i = 0; $i -lt $itemsControl.Items.Count; $i++) { $item = $itemsControl.Items[$i] if ($null -eq $item) { continue } # ------------------------------------------------------------ # Check if this is a category label (usually first Label) # ------------------------------------------------------------ if ($item -is [Windows.Controls.Label]) { $categoryLabel = $item # Initially hide category label; show it only if matches found $item.Visibility = [Windows.Visibility]::Collapsed } # ------------------------------------------------------------ # Check if this is a DockPanel containing a tweak checkbox # ------------------------------------------------------------ elseif ($item -is [Windows.Controls.DockPanel]) { $checkbox = $null $label = $null # Safely extract checkbox and label $checkbox = $item.Children | Where-Object { $_ -is [Windows.Controls.CheckBox] } | Select-Object -First 1 $label = $item.Children | Where-Object { $_ -is [Windows.Controls.Label] } | Select-Object -First 1 # Check if tweak matches search criteria $itemMatches = $false if ($null -ne $label) { $labelContent = $label.Content $labelToolTip = $label.ToolTip # Safely null-check properties if ($null -eq $labelContent) { $labelContent = "" } if ($null -eq $labelToolTip) { $labelToolTip = "" } # Convert to string and perform LITERAL matching $labelContentStr = [string]$labelContent $labelToolTipStr = [string]$labelToolTip # Use IndexOf for literal matching (no wildcard interpretation) $contentMatch = $labelContentStr.IndexOf($searchTerm, [System.StringComparison]::OrdinalIgnoreCase) -ge 0 $toolTipMatch = $labelToolTipStr.IndexOf($searchTerm, [System.StringComparison]::OrdinalIgnoreCase) -ge 0 if ($contentMatch -or $toolTipMatch) { $itemMatches = $true } } # Set visibility based on match result if ($itemMatches) { $item.Visibility = [Windows.Visibility]::Visible $categoryHasMatch = $true } else { $item.Visibility = [Windows.Visibility]::Collapsed } } # ------------------------------------------------------------ # Check if this is a StackPanel containing a tweak checkbox # ------------------------------------------------------------ elseif ($item -is [Windows.Controls.StackPanel]) { $checkbox = $null $checkbox = $item.Children | Where-Object { $_ -is [Windows.Controls.CheckBox] } | Select-Object -First 1 $itemMatches = $false if ($null -ne $checkbox) { $checkboxContent = $checkbox.Content $checkboxToolTip = $checkbox.ToolTip # Safely null-check properties if ($null -eq $checkboxContent) { $checkboxContent = "" } if ($null -eq $checkboxToolTip) { $checkboxToolTip = "" } # Convert to string and perform LITERAL matching $checkboxContentStr = [string]$checkboxContent $checkboxToolTipStr = [string]$checkboxToolTip # Use IndexOf for literal matching (no wildcard interpretation) $contentMatch = $checkboxContentStr.IndexOf($searchTerm, [System.StringComparison]::OrdinalIgnoreCase) -ge 0 $toolTipMatch = $checkboxToolTipStr.IndexOf($searchTerm, [System.StringComparison]::OrdinalIgnoreCase) -ge 0 if ($contentMatch -or $toolTipMatch) { $itemMatches = $true } } # Set visibility based on match result if ($itemMatches) { $item.Visibility = [Windows.Visibility]::Visible $categoryHasMatch = $true } else { $item.Visibility = [Windows.Visibility]::Collapsed } } } # ------------------------------------------------------------ # Update category label visibility and expanded/collapsed state # ------------------------------------------------------------ if ($categoryHasMatch) { # Show category label if ($null -ne $categoryLabel) { $categoryLabel.Visibility = [Windows.Visibility]::Visible # Update category label to expanded state (change "+" to "-") $labelContent = $categoryLabel.Content if ($null -ne $labelContent) { $labelStr = [string]$labelContent # Safe string replacement without -replace regex if ($labelStr.StartsWith("+ ")) { $expandedLabel = "- " + $labelStr.Substring(2) $categoryLabel.Content = $expandedLabel } } } } } } # ---------------------------------------------------------------- # Set category border visibility based on whether it has matches # ---------------------------------------------------------------- if ($categoryHasMatch) { $categoryBorder.Visibility = [Windows.Visibility]::Visible } else { $categoryBorder.Visibility = [Windows.Visibility]::Collapsed } } } } catch { # Silent catch - UI elements may be disposed or in unexpected state # Do not log to terminal as this function is called on every keystroke $null = $_ } } function Get-WinUtilPackageLogSummary { param( [Parameter(Mandatory = $true)] [object[]]$Packages, [Parameter(Mandatory = $true)] [string]$Preference ) @($Packages | ForEach-Object { $package = $_ $packageName = @($package.Name, $package.Description, $package.winget, $package.choco) | Where-Object { -not [string]::IsNullOrWhiteSpace([string]$_) -and $_ -ne "na" } | Select-Object -First 1 if ([string]::IsNullOrWhiteSpace([string]$packageName)) { $packageName = "Unknown package" } if ($Preference -eq "Choco" -and -not [string]::IsNullOrWhiteSpace([string]$package.choco) -and $package.choco -ne "na") { "$packageName (choco: $($package.choco))" } elseif (-not [string]::IsNullOrWhiteSpace([string]$package.winget) -and $package.winget -ne "na") { "$packageName (winget: $($package.winget))" } else { "$packageName (no package id)" } }) } function Get-WinUtilSelectedPackages { param( [Parameter(Mandatory = $true)] [object] $PackageList, [Parameter(Mandatory = $true)] [string] $Preference ) if ($PackageList.count -eq 1) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" } } else { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" } } $packagesWinget = [System.Collections.ArrayList]::new() $packagesChoco = [System.Collections.ArrayList]::new() $packages = @{ Winget = $packagesWinget Choco = $packagesChoco } function Add-PackageId { param( [System.Collections.ArrayList]$Target, $PackageId ) if ([string]::IsNullOrWhiteSpace([string]$PackageId) -or $PackageId -eq "na") { return } if (-not $Target.Contains($PackageId)) { $null = $Target.Add($PackageId) } } foreach ($package in $PackageList) { switch ($Preference) { "Choco" { if ([string]::IsNullOrWhiteSpace([string]$package.choco) -or $package.choco -eq "na") { Add-PackageId -Target $packagesWinget -PackageId $package.winget } else { Add-PackageId -Target $packagesChoco -PackageId $package.choco } } "Winget" { Add-PackageId -Target $packagesWinget -PackageId $package.winget } } } return $packages } Function Get-WinUtilToggleStatus ($ToggleSwitch) { $ToggleSwitchReg = $sync.configs.tweaks.$ToggleSwitch.registry if ($null -eq $sync.ToggleStatusCache) { $sync.ToggleStatusCache = @{} } if ($sync.ToggleStatusCache.ContainsKey($ToggleSwitch)) { return [bool]$sync.ToggleStatusCache[$ToggleSwitch] } if (-not (Get-PSDrive -Name HKU -ErrorAction SilentlyContinue)) { New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS | Out-Null } foreach ($regentry in $ToggleSwitchReg) { if (Test-Path $regentry.Path) { $regstate = (Get-ItemProperty -Path $regentry.Path).$($regentry.Name) } else { $regstate = $null } if ($null -eq $regstate) { switch ([string]$regentry.DefaultState) { "true" { $regstate = $regentry.Value } "false" { $regstate = $regentry.OriginalValue } } } if ($regstate -ne $regentry.Value) { $sync.ToggleStatusCache[$ToggleSwitch] = $false return $false } } $sync.ToggleStatusCache[$ToggleSwitch] = $true return $true } function Get-WinUtilVariables { <# .SYNOPSIS Gets every form object of the provided type .OUTPUTS List containing every object that matches the provided type #> param ( [Parameter()] [string[]]$Type ) $keys = ($sync.keys).where{ $_ -like "WPF*" } if ($Type) { $output = $keys | ForEach-Object { try { $objType = $sync["$psitem"].GetType().Name if ($Type -contains $objType) { Write-Output $psitem } } catch { $null = $_ } } return $output } return $keys } function Hide-WPFInstallAppBusy { <# .SYNOPSIS Hides the busy overlay in the install app area of the WPF form. This is used to indicate that an install or uninstall has finished. #> Invoke-WPFUIThread -ScriptBlock { $sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Collapsed $sync.InstallAppAreaBorder.IsEnabled = $true $sync.InstallAppAreaScrollViewer.Effect.Radius = 0 } } function Initialize-InstallAppArea { <# .SYNOPSIS Creates a [Windows.Controls.ScrollViewer] containing a [Windows.Controls.ItemsControl] which is setup to use Virtualization to only load the visible elements for performance reasons. This is used as the parent object for all category and app entries on the install tab Used to as part of the Install Tab UI generation Also creates an overlay with a progress bar and text to indicate that an install or uninstall is in progress .PARAMETER TargetElement The element to which the AppArea should be added #> param($TargetElement) $targetGrid = $sync.Form.FindName($TargetElement) $null = $targetGrid.Children.Clear() # Create the outer Border for the aren where the apps will be placed $Border = New-Object Windows.Controls.Border $Border.VerticalAlignment = "Stretch" $Border.SetResourceReference([Windows.Controls.Control]::StyleProperty, "BorderStyle") $sync.InstallAppAreaBorder = $Border # Add a ScrollViewer, because the ItemsControl does not support scrolling by itself $scrollViewer = New-Object Windows.Controls.ScrollViewer $scrollViewer.VerticalScrollBarVisibility = 'Auto' $scrollViewer.HorizontalAlignment = 'Stretch' $scrollViewer.VerticalAlignment = 'Stretch' $scrollViewer.CanContentScroll = $true $sync.InstallAppAreaScrollViewer = $scrollViewer $Border.Child = $scrollViewer # Initialize the Blur Effect for the ScrollViewer, which will be used to indicate that an install/uninstall is in progress $blurEffect = New-Object Windows.Media.Effects.BlurEffect $blurEffect.Radius = 0 $scrollViewer.Effect = $blurEffect ## Create the ItemsControl, which will be the parent of all the app entries $itemsControl = New-Object Windows.Controls.ItemsControl $itemsControl.HorizontalAlignment = 'Stretch' $itemsControl.VerticalAlignment = 'Stretch' $scrollViewer.Content = $itemsControl # Use WrapPanel to create dynamic columns based on AppEntryWidth and window width $itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate $factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.WrapPanel]) $factory.SetValue([Windows.Controls.WrapPanel]::OrientationProperty, [Windows.Controls.Orientation]::Horizontal) $factory.SetValue([Windows.Controls.WrapPanel]::HorizontalAlignmentProperty, [Windows.HorizontalAlignment]::Left) $itemsPanelTemplate.VisualTree = $factory $itemsControl.ItemsPanel = $itemsPanelTemplate # Add the Border containing the App Area to the target Grid $targetGrid.Children.Add($Border) | Out-Null $overlay = New-Object Windows.Controls.Border $overlay.CornerRadius = New-Object Windows.CornerRadius(10) $overlay.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallOverlayBackgroundColor") $overlay.Visibility = [Windows.Visibility]::Collapsed # Also add the overlay to the target Grid on top of the App Area $targetGrid.Children.Add($overlay) | Out-Null $sync.InstallAppAreaOverlay = $overlay $overlayText = New-Object Windows.Controls.TextBlock $overlayText.Text = "Installing apps..." $overlayText.HorizontalAlignment = 'Center' $overlayText.VerticalAlignment = 'Center' $overlayText.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "MainForegroundColor") $overlayText.Background = "Transparent" $overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontSizeProperty, "HeaderFontSize") $overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontFamilyProperty, "MainFontFamily") $overlayText.SetResourceReference([Windows.Controls.TextBlock]::FontWeightProperty, "MainFontWeight") $overlayText.SetResourceReference([Windows.Controls.TextBlock]::MarginProperty, "MainMargin") $sync.InstallAppAreaOverlayText = $overlayText $progressbar = New-Object Windows.Controls.ProgressBar $progressbar.Name = "ProgressBar" $progressbar.Width = 250 $progressbar.Height = 50 $sync.ProgressBar = $progressbar # Add a TextBlock overlay for the progress bar text $progressBarTextBlock = New-Object Windows.Controls.TextBlock $progressBarTextBlock.Name = "progressBarTextBlock" $progressBarTextBlock.FontWeight = [Windows.FontWeights]::Bold $progressBarTextBlock.FontSize = 16 $progressBarTextBlock.Width = $progressbar.Width $progressBarTextBlock.Height = $progressbar.Height $progressBarTextBlock.SetResourceReference([Windows.Controls.TextBlock]::ForegroundProperty, "ProgressBarTextColor") $progressBarTextBlock.TextTrimming = "CharacterEllipsis" $progressBarTextBlock.Background = "Transparent" $sync.progressBarTextBlock = $progressBarTextBlock # Create a Grid to overlay the text on the progress bar $progressGrid = New-Object Windows.Controls.Grid $progressGrid.Width = $progressbar.Width $progressGrid.Height = $progressbar.Height $progressGrid.Margin = "0,10,0,10" $progressGrid.Children.Add($progressbar) | Out-Null $progressGrid.Children.Add($progressBarTextBlock) | Out-Null $overlayStackPanel = New-Object Windows.Controls.StackPanel $overlayStackPanel.Orientation = "Vertical" $overlayStackPanel.HorizontalAlignment = 'Center' $overlayStackPanel.VerticalAlignment = 'Center' $overlayStackPanel.Children.Add($overlayText) | Out-Null $overlayStackPanel.Children.Add($progressGrid) | Out-Null $overlay.Child = $overlayStackPanel return $itemsControl } function Initialize-InstallAppEntry { <# .SYNOPSIS Creates the app entry to be placed on the install tab for a given app Used to as part of the Install Tab UI generation .PARAMETER TargetElement The Element into which the Apps should be placed .PARAMETER appKey The Key of the app inside the $sync.configs.applicationsHashtable #> param( [Windows.Controls.WrapPanel]$TargetElement, $appKey ) $app = $sync.configs.applicationsHashtable.$appKey # Create the outer Border for the application type $border = New-Object Windows.Controls.Border $border.Style = $sync.Form.Resources.AppEntryBorderStyle $border.Tag = $appKey $border.ToolTip = $app.description $border.Add_MouseLeftButtonUp({ $childCheckbox = ($this.Child | Where-Object {$_.Template.TargetType -eq [System.Windows.Controls.Checkbox]})[0] $childCheckBox.isChecked = -not $childCheckbox.IsChecked }) $border.Add_MouseEnter({ if (($sync.$($this.Tag).IsChecked) -eq $false) { $this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallHighlightedColor") } }) $border.Add_MouseLeave({ if (($sync.$($this.Tag).IsChecked) -eq $false) { $this.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor") } }) $border.Add_MouseRightButtonUp({ # Store the selected app in a global variable so it can be used in the popup $sync.appPopupSelectedApp = $this.Tag # Set the popup position to the current mouse position $sync.appPopup.PlacementTarget = $this $sync.appPopup.IsOpen = $true }) $checkBox = New-Object Windows.Controls.CheckBox # Sanitize the name for WPF $checkBox.Name = $appKey -replace '-', '_' # Store the original appKey in Tag $checkBox.Tag = $appKey $checkbox.Style = $sync.Form.Resources.AppEntryCheckboxStyle $checkbox.Add_Checked({ Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $this.Parent.Tag $borderElement = $this.Parent $borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallSelectedColor") }) $checkbox.Add_Unchecked({ Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $this.Parent.Tag $borderElement = $this.Parent $borderElement.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "AppInstallUnselectedColor") }) # Create the TextBlock for the application name $appName = New-Object Windows.Controls.TextBlock $appName.Style = $sync.Form.Resources.AppEntryNameStyle $appName.Text = $app.content # Add FOSS label after the name if FOSS if ($app.foss -eq $true) { $fossRun = [System.Windows.Documents.Run]::new(" $([char]0x25CF)") $fossRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(110, 255, 114)) $fossRun.FontSize = 11.5 [void]$appName.Inlines.Add($fossRun) } $checkBox.Content = $appName # Add accessibility properties to make the elements screen reader friendly $checkBox.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $app.content) $border.SetValue([Windows.Automation.AutomationProperties]::NameProperty, $app.content) $border.Child = $checkBox if ($sync.selectedApps -contains $appKey) { $checkBox.IsChecked = $true } # Add the border to the corresponding Category $TargetElement.Children.Add($border) | Out-Null return $checkbox } function Initialize-InstallCategoryAppList { <# .SYNOPSIS Clears the Target Element and sets up a "Loading" message. This is done, because loading of all apps can take a bit of time in some scenarios Iterates through all Categories and Apps and adds them to the UI Used to as part of the Install Tab UI generation .PARAMETER TargetElement The Element into which the Categories and Apps should be placed .PARAMETER Apps The Hashtable of Apps to be added to the UI The Categories are also extracted from the Apps Hashtable #> param( $TargetElement, $Apps ) # Pre-group apps by category before creating WPF controls. $appsByCategory = @{} foreach ($appKey in $Apps.Keys) { $category = $Apps.$appKey.Category if (-not $appsByCategory.ContainsKey($category)) { $appsByCategory[$category] = @() } $appsByCategory[$category] += $appKey } $sync.InstallAppRenderQueue = [System.Collections.Queue]::new() foreach ($category in $($appsByCategory.Keys | Sort-Object)) { # Create a container for category label + apps $categoryContainer = New-Object Windows.Controls.StackPanel $categoryContainer.Orientation = "Vertical" $categoryContainer.Margin = New-Object Windows.Thickness(0, 0, 0, 0) $categoryContainer.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch [System.Windows.Automation.AutomationProperties]::SetName($categoryContainer, $Category) # Bind Width to the ItemsControl's ActualWidth to force full-row layout in WrapPanel $binding = New-Object Windows.Data.Binding $binding.Path = New-Object Windows.PropertyPath("ActualWidth") $binding.RelativeSource = New-Object Windows.Data.RelativeSource([Windows.Data.RelativeSourceMode]::FindAncestor, [Windows.Controls.ItemsControl], 1) [void][Windows.Data.BindingOperations]::SetBinding($categoryContainer, [Windows.FrameworkElement]::WidthProperty, $binding) # Add category label to container $toggleButton = New-Object Windows.Controls.Label $toggleButton.Content = "- $Category" $toggleButton.Tag = "CategoryToggleButton" $toggleButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize") $toggleButton.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily") $toggleButton.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "LabelboxForegroundColor") $toggleButton.Cursor = [System.Windows.Input.Cursors]::Hand $toggleButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch $sync.$Category = $toggleButton # Add click handler to toggle category visibility $toggleButton.Add_MouseLeftButtonUp({ param($categoryToggle) # Find the parent StackPanel (categoryContainer) $categoryContainer = $categoryToggle.Parent if ($categoryContainer -and $categoryContainer.Children.Count -ge 2) { # The WrapPanel is the second child $wrapPanel = $categoryContainer.Children[1] # Toggle visibility if ($wrapPanel.Visibility -eq [Windows.Visibility]::Visible) { $wrapPanel.Visibility = [Windows.Visibility]::Collapsed # Change - to + $categoryToggle.Content = $categoryToggle.Content -replace "^- ", "+ " } else { $wrapPanel.Visibility = [Windows.Visibility]::Visible # Change + to - $categoryToggle.Content = $categoryToggle.Content -replace "^\+ ", "- " } } }) $null = $categoryContainer.Children.Add($toggleButton) # Add wrap panel for apps to container $wrapPanel = New-Object Windows.Controls.WrapPanel $wrapPanel.Orientation = "Horizontal" $wrapPanel.HorizontalAlignment = "Left" $wrapPanel.VerticalAlignment = "Top" $wrapPanel.Margin = New-Object Windows.Thickness(0, 0, 0, 0) $wrapPanel.Visibility = [Windows.Visibility]::Visible $wrapPanel.Tag = "CategoryWrapPanel_$category" $null = $categoryContainer.Children.Add($wrapPanel) # Add the entire category container to the target element $null = $TargetElement.Items.Add($categoryContainer) $sync.InstallAppRenderQueue.Enqueue([pscustomobject]@{ Category = $category TargetElement = $wrapPanel AppKeys = @($appsByCategory[$category] | Sort-Object) }) } Start-WinUtilInstallAppRendering } function Initialize-WinUtilRunspacePool { if ($sync.runspace -and $sync.runspace.RunspacePoolStateInfo.State -eq [System.Management.Automation.Runspaces.RunspacePoolState]::Opened) { return $sync.runspace } if ($sync.runspace) { Close-WinUtilRunspacePool } # Set the maximum number of threads for the RunspacePool to the number of threads on the machine. $maxthreads = [Math]::Max([int]$env:NUMBER_OF_PROCESSORS, 1) # Create a new session state for parsing variables into our runspace. $hashVars = New-Object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync', $sync, $null $offlineVar = New-Object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_OFFLINE', $PARAM_OFFLINE, $null $initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() $initialSessionState.Variables.Add($hashVars) $initialSessionState.Variables.Add($offlineVar) # Get every WinUtil/WPF function and add it to the session state. $functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' } foreach ($function in $functions) { $functionDefinition = Get-Content function:\$($function.Name) $functionEntry = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList $function.Name, $functionDefinition $initialSessionState.Commands.Add($functionEntry) } $sync.runspace = [runspacefactory]::CreateRunspacePool( 1, # Minimum thread count $maxthreads, # Maximum thread count $initialSessionState, # Initial session state $Host # Machine to create runspaces on ) $sync.runspace.Open() return $sync.runspace } function Initialize-WinUtilTabContent { param( [Parameter(Mandatory = $true)] [string]$TabName ) if ($null -eq $sync.InitializedTabs) { $sync.InitializedTabs = @{} } if ($sync.InitializedTabs[$TabName]) { return } switch ($TabName) { "Install" { Invoke-WPFUIElements -configVariable $sync.configs.appnavigation -targetGridName "appscategory" -columncount 1 Initialize-WPFUI -targetGridName "appscategory" Initialize-WPFUI -targetGridName "appspanel" } "Tweaks" { Invoke-WPFUIElements -configVariable $sync.configs.tweaks -targetGridName "tweakspanel" -columncount 2 } "Config" { Invoke-WPFUIElements -configVariable $sync.configs.feature -targetGridName "featurespanel" -columncount 2 } "AppX" { Invoke-WPFUIElements -configVariable $sync.configs.appx -targetGridName "appxpanel" -columncount 2 } "Win11 Creator" { if ($sync.Form -and $sync.Form.Dispatcher) { $sync.Form.Dispatcher.BeginInvoke([System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilISOCheckExistingWork }) | Out-Null } } } $sync.InitializedTabs[$TabName] = $true } function Initialize-WinUtilTaskbarOverlayAssets { param( [bool]$IncludeLogo = $true, [bool]$IncludeStatusAssets = $true ) if ($IncludeLogo -and -not $sync["logorender"]) { $sync["logorender"] = (Invoke-WinUtilAssets -Type "Logo" -Size 90 -Render) } if ($IncludeStatusAssets -and -not $sync["checkmarkrender"]) { $sync["checkmarkrender"] = (Invoke-WinUtilAssets -Type "checkmark" -Size 512 -Render) } if ($IncludeStatusAssets -and -not $sync["warningrender"]) { $sync["warningrender"] = (Invoke-WinUtilAssets -Type "warning" -Size 512 -Render) } } function Install-WinUtilChoco { if (-not (Get-Command -Name choco)) { Write-Host "Chocolatey is not installed. Installing now..." $installScript = Invoke-WebRequest -Uri https://community.chocolatey.org/install.ps1 -UseBasicParsing Invoke-Command -ScriptBlock ([scriptblock]::Create($installScript.Content)) } } function Install-WinUtilProgramChoco { param ( [Parameter(Mandatory=$true)] [ValidateSet("Install", "Uninstall")] [string]$Action, [Parameter(Mandatory=$true)] [string[]]$Programs ) if ($Action -eq 'Install') { $arguments = "install $Programs -y" } else { $arguments = "uninstall $Programs -y" } Write-WinUtilLog -Component "Package" -Message "$Action choco package(s): $($Programs -join ', ')" $process = Start-Process -FilePath choco -ArgumentList $arguments -NoNewWindow -Wait -PassThru Write-WinUtilLog -Component "Package" -Message "$Action choco package(s) completed: $($Programs -join ', ') (exit code: $($process.ExitCode))" } Function Install-WinUtilProgramWinget { param ( [Parameter(Mandatory=$true)] [ValidateSet("Install", "Uninstall")] [string]$Action, [Parameter(Mandatory=$true)] [string[]]$Programs ) foreach ($program in $Programs) { if ([string]::IsNullOrWhiteSpace($program) -or $program -eq "na") { continue } $source = "winget" if ($program.StartsWith("msstore:", [System.StringComparison]::OrdinalIgnoreCase)) { $source = "msstore" $program = $program.Substring("msstore:".Length) } if ($Action -eq 'Install') { $arguments = @("install", "--id", $program, "--accept-package-agreements", "--accept-source-agreements", "--source", $source, "--silent") } else { $arguments = @("uninstall", "--id", $program, "--source", $source, "--silent") } Write-WinUtilLog -Component "Package" -Message "$Action winget package: $program (source: $source)" $process = Start-Process -FilePath winget -ArgumentList $arguments -NoNewWindow -Wait -PassThru Write-WinUtilLog -Component "Package" -Message "$Action winget package completed: $program (exit code: $($process.ExitCode))" } } function Install-WinUtilWinget { <# .SYNOPSIS Installs WinGet if not already installed. .DESCRIPTION installs winGet if needed #> if ((Test-WinUtilPackageManager -winget) -eq "installed") { return } Write-Host "WinGet is not installed. Installing now..." -ForegroundColor Red Install-PackageProvider -Name NuGet -Force Install-Module -Name Microsoft.WinGet.Client -Force Repair-WinGetPackageManager -AllUsers } function Invoke-WinUtilAssets { param ( $type, $Size, [switch]$render ) if ($render -and $null -ne $sync) { if ($null -eq $sync.RenderedAssetCache) { $sync.RenderedAssetCache = @{} } $cacheKey = "$(([string]$type).ToLowerInvariant())|$Size" if ($sync.RenderedAssetCache.ContainsKey($cacheKey)) { return $sync.RenderedAssetCache[$cacheKey] } } # Create the Viewbox and set its size $LogoViewbox = New-Object Windows.Controls.Viewbox $LogoViewbox.Width = $Size $LogoViewbox.Height = $Size # Create a Canvas to hold the paths $canvas = New-Object Windows.Controls.Canvas $canvas.Width = 100 $canvas.Height = 100 # Define a scale factor for the content inside the Canvas $scaleFactor = $Size / 100 # Apply a scale transform to the Canvas content $scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor) $canvas.LayoutTransform = $scaleTransform switch ($type) { 'logo' { $LogoPathData1 = @" M 18.00,14.00 C 18.00,14.00 45.00,27.74 45.00,27.74 45.00,27.74 57.40,34.63 57.40,34.63 57.40,34.63 59.00,43.00 59.00,43.00 59.00,43.00 59.00,83.00 59.00,83.00 55.35,81.66 46.99,77.79 44.72,74.79 41.17,70.10 42.01,59.80 42.00,54.00 42.00,51.62 42.20,48.29 40.98,46.21 38.34,41.74 25.78,38.60 21.28,33.79 16.81,29.02 18.00,20.20 18.00,14.00 Z "@ $LogoPath1 = New-Object Windows.Shapes.Path $LogoPath1.Data = [Windows.Media.Geometry]::Parse($LogoPathData1) $LogoPath1.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff") $LogoPathData2 = @" M 107.00,14.00 C 109.01,19.06 108.93,30.37 104.66,34.21 100.47,37.98 86.38,43.10 84.60,47.21 83.94,48.74 84.01,51.32 84.00,53.00 83.97,57.04 84.46,68.90 83.26,72.00 81.06,77.70 72.54,81.42 67.00,83.00 67.00,83.00 67.00,43.00 67.00,43.00 67.00,43.00 67.99,35.63 67.99,35.63 67.99,35.63 80.00,28.26 80.00,28.26 80.00,28.26 107.00,14.00 107.00,14.00 Z "@ $LogoPath2 = New-Object Windows.Shapes.Path $LogoPath2.Data = [Windows.Media.Geometry]::Parse($LogoPathData2) $LogoPath2.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#0567ff") $LogoPathData3 = @" M 19.00,46.00 C 21.36,47.14 28.67,50.71 30.01,52.63 31.17,54.30 30.99,57.04 31.00,59.00 31.04,65.41 30.35,72.16 33.56,78.00 38.19,86.45 46.10,89.04 54.00,93.31 56.55,94.69 60.10,97.20 63.00,97.22 65.50,97.24 68.77,95.36 71.00,94.25 76.42,91.55 84.51,87.78 88.82,83.68 94.56,78.20 95.96,70.59 96.00,63.00 96.01,60.24 95.59,54.63 97.02,52.39 98.80,49.60 103.95,47.87 107.00,47.00 107.00,47.00 107.00,67.00 107.00,67.00 106.90,87.69 96.10,93.85 80.00,103.00 76.51,104.98 66.66,110.67 63.00,110.52 60.33,110.41 55.55,107.53 53.00,106.25 46.21,102.83 36.63,98.57 31.04,93.68 16.88,81.28 19.00,62.88 19.00,46.00 Z "@ $LogoPath3 = New-Object Windows.Shapes.Path $LogoPath3.Data = [Windows.Media.Geometry]::Parse($LogoPathData3) $LogoPath3.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#a3a4a6") $canvas.Children.Add($LogoPath1) | Out-Null $canvas.Children.Add($LogoPath2) | Out-Null $canvas.Children.Add($LogoPath3) | Out-Null } 'checkmark' { $canvas.Width = 512 $canvas.Height = 512 $scaleFactor = $Size / 2.54 $scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor) $canvas.LayoutTransform = $scaleTransform # Define the circle path $circlePathData = "M 1.27,0 A 1.27,1.27 0 1,0 1.27,2.54 A 1.27,1.27 0 1,0 1.27,0" $circlePath = New-Object Windows.Shapes.Path $circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData) $circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#39ba00") # Define the checkmark path $checkmarkPathData = "M 0.873 1.89 L 0.41 1.391 A 0.17 0.17 0 0 1 0.418 1.151 A 0.17 0.17 0 0 1 0.658 1.16 L 1.016 1.543 L 1.583 1.013 A 0.17 0.17 0 0 1 1.599 1 L 1.865 0.751 A 0.17 0.17 0 0 1 2.105 0.759 A 0.17 0.17 0 0 1 2.097 0.999 L 1.282 1.759 L 0.999 2.022 L 0.874 1.888 Z" $checkmarkPath = New-Object Windows.Shapes.Path $checkmarkPath.Data = [Windows.Media.Geometry]::Parse($checkmarkPathData) $checkmarkPath.Fill = [Windows.Media.Brushes]::White # Add the paths to the Canvas $canvas.Children.Add($circlePath) | Out-Null $canvas.Children.Add($checkmarkPath) | Out-Null } 'warning' { $canvas.Width = 512 $canvas.Height = 512 # Define a scale factor for the content inside the Canvas $scaleFactor = $Size / 512 # Adjust scaling based on the canvas size $scaleTransform = New-Object Windows.Media.ScaleTransform($scaleFactor, $scaleFactor) $canvas.LayoutTransform = $scaleTransform # Define the circle path $circlePathData = "M 256,0 A 256,256 0 1,0 256,512 A 256,256 0 1,0 256,0" $circlePath = New-Object Windows.Shapes.Path $circlePath.Data = [Windows.Media.Geometry]::Parse($circlePathData) $circlePath.Fill = [System.Windows.Media.BrushConverter]::new().ConvertFromString("#f41b43") # Define the exclamation mark path $exclamationPathData = "M 256 307.2 A 35.89 35.89 0 0 1 220.14 272.74 L 215.41 153.3 A 35.89 35.89 0 0 1 251.27 116 H 260.73 A 35.89 35.89 0 0 1 296.59 153.3 L 291.86 272.74 A 35.89 35.89 0 0 1 256 307.2 Z" $exclamationPath = New-Object Windows.Shapes.Path $exclamationPath.Data = [Windows.Media.Geometry]::Parse($exclamationPathData) $exclamationPath.Fill = [Windows.Media.Brushes]::White # Get the bounds of the exclamation mark path $exclamationBounds = $exclamationPath.Data.Bounds # Calculate the center position for the exclamation mark path $exclamationCenterX = ($canvas.Width - $exclamationBounds.Width) / 2 - $exclamationBounds.X $exclamationPath.SetValue([Windows.Controls.Canvas]::LeftProperty, $exclamationCenterX) # Define the rounded rectangle at the bottom (dot of exclamation mark) $roundedRectangle = New-Object Windows.Shapes.Rectangle $roundedRectangle.Width = 80 $roundedRectangle.Height = 80 $roundedRectangle.RadiusX = 30 $roundedRectangle.RadiusY = 30 $roundedRectangle.Fill = [Windows.Media.Brushes]::White # Calculate the center position for the rounded rectangle $centerX = ($canvas.Width - $roundedRectangle.Width) / 2 $roundedRectangle.SetValue([Windows.Controls.Canvas]::LeftProperty, $centerX) $roundedRectangle.SetValue([Windows.Controls.Canvas]::TopProperty, 324.34) # Add the paths to the Canvas $canvas.Children.Add($circlePath) | Out-Null $canvas.Children.Add($exclamationPath) | Out-Null $canvas.Children.Add($roundedRectangle) | Out-Null } default { Write-Host "Invalid type: $type" } } # Add the Canvas to the Viewbox $LogoViewbox.Child = $canvas if ($render) { # Measure and arrange the canvas to ensure proper rendering $canvas.Measure([Windows.Size]::new($canvas.Width, $canvas.Height)) $canvas.Arrange([Windows.Rect]::new(0, 0, $canvas.Width, $canvas.Height)) $canvas.UpdateLayout() # Initialize RenderTargetBitmap correctly with dimensions $renderTargetBitmap = New-Object Windows.Media.Imaging.RenderTargetBitmap($canvas.Width, $canvas.Height, 96, 96, [Windows.Media.PixelFormats]::Pbgra32) # Render the canvas to the bitmap $renderTargetBitmap.Render($canvas) # Create a BitmapFrame from the RenderTargetBitmap $bitmapFrame = [Windows.Media.Imaging.BitmapFrame]::Create($renderTargetBitmap) # Create a PngBitmapEncoder and add the frame $bitmapEncoder = [Windows.Media.Imaging.PngBitmapEncoder]::new() $bitmapEncoder.Frames.Add($bitmapFrame) # Save to a memory stream $imageStream = New-Object System.IO.MemoryStream $bitmapEncoder.Save($imageStream) $imageStream.Position = 0 # Load the stream into a BitmapImage $bitmapImage = [Windows.Media.Imaging.BitmapImage]::new() $bitmapImage.BeginInit() $bitmapImage.StreamSource = $imageStream $bitmapImage.CacheOption = [Windows.Media.Imaging.BitmapCacheOption]::OnLoad $bitmapImage.EndInit() if ($bitmapImage.CanFreeze) { $bitmapImage.Freeze() } if ($null -ne $sync -and $sync.ContainsKey("RenderedAssetCache")) { $sync.RenderedAssetCache[$cacheKey] = $bitmapImage } return $bitmapImage } else { return $LogoViewbox } } Function Invoke-WinUtilCurrentSystem { <# .SYNOPSIS Checks to see what tweaks have already been applied and what programs are installed, and checks the according boxes .EXAMPLE InvokeWinUtilCurrentSystem -Checkbox "winget" #> param( $CheckBox ) if ($CheckBox -eq "choco") { $apps = (choco list | Select-String -Pattern "^\S+").Matches.Value $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"} $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object { $dependencies = @($sync.configs.applications.$($psitem.Key).choco -split ";") if ($dependencies -in $apps) { Write-Output $psitem.name } } } if ($checkbox -eq "winget") { $originalEncoding = [Console]::OutputEncoding [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() $Sync.InstalledPrograms = @("winget", "msstore") | ForEach-Object { winget list -s $psitem | Select-Object -skip 3 | ConvertFrom-String -PropertyNames "Name", "Id", "Version", "Available" -Delimiter '\s{2,}' } [Console]::OutputEncoding = $originalEncoding $filter = Get-WinUtilVariables -Type Checkbox | Where-Object {$psitem -like "WPFInstall*"} $sync.GetEnumerator() | Where-Object {$psitem.Key -in $filter} | ForEach-Object { $dependencies = @($sync.configs.applications.$($psitem.Key).winget -split ";") | ForEach-Object { $psitem -replace "^msstore:", "" } if ($dependencies[-1] -in $sync.InstalledPrograms.Id) { Write-Output $psitem.name } } } if ($CheckBox -eq "tweaks") { if (!(Test-Path 'HKU:\')) {$null = (New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS)} $sync.configs.tweaks | Get-Member -MemberType NoteProperty | ForEach-Object { $Config = $psitem.Name $entry = $sync.configs.tweaks.$Config $registryKeys = $entry.registry $serviceKeys = $entry.service $entryType = $entry.Type if ($registryKeys -or $serviceKeys) { $Values = @() if ($entryType -eq "Toggle") { if (-not (Get-WinUtilToggleStatus $Config)) { $values += $False } } else { $registryMatchCount = 0 $registryTotal = 0 Foreach ($tweaks in $registryKeys) { Foreach ($tweak in $tweaks) { $registryTotal++ $regstate = $null if (Test-Path $tweak.Path) { $regstate = Get-ItemProperty -Name $tweak.Name -Path $tweak.Path -ErrorAction SilentlyContinue | Select-Object -ExpandProperty $($tweak.Name) } if ($null -eq $regstate) { switch ($tweak.DefaultState) { "true" { $regstate = $tweak.Value } "false" { $regstate = $tweak.OriginalValue } default { $regstate = $tweak.OriginalValue } } } if ($regstate -eq $tweak.Value) { $registryMatchCount++ } } } if ($registryTotal -gt 0 -and $registryMatchCount -ne $registryTotal) { $values += $False } } Foreach ($tweaks in $serviceKeys) { Foreach ($tweak in $tweaks) { $Service = Get-Service -Name $tweak.Name if ($Service) { $actualValue = $Service.StartType $expectedValue = $tweak.StartupType if ($expectedValue -ne $actualValue) { $values += $False } } } } if ($values -notcontains $false) { Write-Output $Config } } } } } function Invoke-WinUtilExplorerUpdate { <# .SYNOPSIS Refreshes the Windows Explorer #> param ( [string]$action = "refresh" ) if ($action -eq "refresh") { Invoke-WPFRunspace -ScriptBlock { # Define the Win32 type only if it doesn't exist if (-not ([System.Management.Automation.PSTypeName]'Win32').Type) { 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 [Win32]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, [IntPtr]::Zero, "ImmersiveColorSet", $SMTO_ABORTIFHUNG, 100, [ref]([IntPtr]::Zero)) } } elseif ($action -eq "restart") { taskkill.exe /F /IM "explorer.exe" Start-Process "explorer.exe" } } function Invoke-WinUtilFeatureInstall ($CheckBox) { Write-WinUtilLog -Component "Feature" -Message "Applying feature action: $CheckBox" if ($sync.configs.feature.$CheckBox.feature) { foreach ($feature in $sync.configs.feature.$CheckBox.feature) { Write-Host "Installing $feature" Write-WinUtilLog -Component "Feature" -Message "Enabling Windows optional feature: $feature" Enable-WindowsOptionalFeature -Online -FeatureName $feature -All -NoRestart -ErrorAction Stop Write-WinUtilLog -Component "Feature" -Message "Enabled Windows optional feature: $feature" } } if ($sync.configs.feature.$CheckBox.InvokeScript) { foreach ($script in $sync.configs.feature.$CheckBox.InvokeScript) { Write-Host "Running Script for $CheckBox" Write-WinUtilLog -Component "Feature" -Message "Running feature script for: $CheckBox" Invoke-Command -ScriptBlock ([scriptblock]::Create($script)) -ErrorAction Stop Write-WinUtilLog -Component "Feature" -Message "Completed feature script for: $CheckBox" } } Write-WinUtilLog -Component "Feature" -Message "Feature action completed: $CheckBox" } function Invoke-WinUtilFontScaling { <# .SYNOPSIS Applies UI and font scaling for accessibility .PARAMETER ScaleFactor Sets the scaling from 0.75 and 2.0. Default is 1.0 (100% - no scaling) .EXAMPLE Invoke-WinUtilFontScaling -ScaleFactor 1.25 # Applies 125% scaling #> param ( [double]$ScaleFactor = 1.0 ) # Validate if scale factor is within the range if ($ScaleFactor -lt 0.75 -or $ScaleFactor -gt 2.0) { Write-Warning "Scale factor must be between 0.75 and 2.0. Using 1.0 instead." $ScaleFactor = 1.0 } # Define an array for resources to be scaled $fontResources = @( # Fonts "FontSize", "ButtonFontSize", "HeaderFontSize", "TabButtonFontSize", "ConfigTabButtonFontSize", "IconFontSize", "SettingsIconFontSize", "CloseIconFontSize", "AppEntryFontSize", "SearchBarTextBoxFontSize", "SearchBarClearButtonFontSize", "CustomDialogFontSize", "CustomDialogFontSizeHeader", "ConfigUpdateButtonFontSize", # Buttons and UI "CheckBoxBulletDecoratorSize", "ButtonWidth", "ButtonHeight", "TabButtonWidth", "TabButtonHeight", "IconButtonSize", "AppEntryWidth", "SearchBarWidth", "SearchBarHeight", "CustomDialogWidth", "CustomDialogHeight", "CustomDialogLogoSize", "ToolTipWidth" ) # Apply scaling to each resource foreach ($resourceName in $fontResources) { try { # Get the default font size from the theme configuration $originalValue = $sync.configs.themes.shared.$resourceName if ($originalValue) { # Convert string to double since values are stored as strings $originalValue = [double]$originalValue # Calculates and applies the new font size $newValue = [math]::Round($originalValue * $ScaleFactor, 1) $sync.Form.Resources[$resourceName] = $newValue } } catch { Write-Warning "Failed to scale resource $resourceName : $_" } } # Store the scale factor so it can be reapplied after theme changes $sync.FontScaleFactor = $ScaleFactor # Update the font scaling percentage displayed on the UI if ($sync.FontScalingValue) { $percentage = [math]::Round($ScaleFactor * 100) $sync.FontScalingValue.Text = "$percentage%" } } function Invoke-WinUtilInstallPSProfile { if (-not (Get-Command wt)) { Write-Host "Windows Terminal not found. Installing..." Install-WinUtilWinget winget install Microsoft.WindowsTerminal --source winget --silent } if (-not (Get-Command pwsh)) { Write-Host "PowerShell 7 not found. Installing..." Install-WinUtilWinget winget install Microsoft.PowerShell --source winget --installer-type wix --silent } wt new-tab pwsh -NoExit -Command "irm https://github.com/ChrisTitusTech/powershell-profile/raw/main/setup.ps1 | iex" } function Write-Win11ISOLog { param([string]$Message) $ts = (Get-Date).ToString("HH:mm:ss") $logLine = "[$ts] $Message" $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $current = $sync["WPFWin11ISOStatusLog"].Text if ($current -eq "Ready. Please select a Windows 11 ISO to begin.") { $sync["WPFWin11ISOStatusLog"].Text = $logLine } else { $sync["WPFWin11ISOStatusLog"].Text += "`n$logLine" } $sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length $sync["WPFWin11ISOStatusLog"].ScrollToEnd() }) } function Invoke-WinUtilISOBrowse { Add-Type -AssemblyName System.Windows.Forms $dlg = [System.Windows.Forms.OpenFileDialog]::new() $dlg.Title = "Select Windows 11 ISO" $dlg.Filter = "ISO files (*.iso)|*.iso|All files (*.*)|*.*" $dlg.InitialDirectory = [System.Environment]::GetFolderPath("Desktop") if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return } $isoPath = $dlg.FileName $fileSizeGB = [math]::Round((Get-Item $isoPath).Length / 1GB, 2) $sync["WPFWin11ISOPath"].Text = $isoPath $sync["WPFWin11ISOFileInfo"].Text = "File size: $fileSizeGB GB" $sync["WPFWin11ISOFileInfo"].Visibility = "Visible" $sync["WPFWin11ISOMountSection"].Visibility = "Visible" $sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed" $sync["WPFWin11ISOModifySection"].Visibility = "Collapsed" $sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed" Write-Win11ISOLog "ISO selected: $isoPath ($fileSizeGB GB)" } function Invoke-WinUtilISOMountAndVerify { $isoPath = $sync["WPFWin11ISOPath"].Text if ([string]::IsNullOrWhiteSpace($isoPath) -or $isoPath -eq "No ISO selected...") { [System.Windows.MessageBox]::Show("Please select an ISO file first.", "No ISO Selected", "OK", "Warning") return } Write-Win11ISOLog "Mounting ISO: $isoPath" Set-WinUtilProgressBar -Label "Mounting ISO..." -Percent 10 try { Mount-DiskImage -ImagePath $isoPath do { Start-Sleep -Milliseconds 500 } until ((Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter) $driveLetter = (Get-DiskImage -ImagePath $isoPath | Get-Volume).DriveLetter + ":" Write-Win11ISOLog "Mounted at drive $driveLetter" Set-WinUtilProgressBar -Label "Verifying ISO contents..." -Percent 30 $wimPath = Join-Path $driveLetter "sources\install.wim" $esdPath = Join-Path $driveLetter "sources\install.esd" if (-not (Test-Path $wimPath) -and -not (Test-Path $esdPath)) { Dismount-DiskImage -ImagePath $isoPath Write-Win11ISOLog "ERROR: install.wim/install.esd not found - not a valid Windows ISO." [System.Windows.MessageBox]::Show( "This does not appear to be a valid Windows ISO.`n`ninstall.wim / install.esd was not found.", "Invalid ISO", "OK", "Error") Set-WinUtilProgressBar -Label "" -Percent 0 return } $activeWim = if (Test-Path $wimPath) { $wimPath } else { $esdPath } Set-WinUtilProgressBar -Label "Reading image metadata..." -Percent 55 $imageInfo = Get-WindowsImage -ImagePath $activeWim | Select-Object ImageIndex, ImageName if (-not ($imageInfo | Where-Object { $_.ImageName -match "Windows 11" })) { Dismount-DiskImage -ImagePath $isoPath Write-Win11ISOLog "ERROR: No 'Windows 11' edition found in the image." [System.Windows.MessageBox]::Show( "No Windows 11 edition was found in this ISO.`n`nOnly official Windows 11 ISOs are supported.", "Not a Windows 11 ISO", "OK", "Error") Set-WinUtilProgressBar -Label "" -Percent 0 return } $sync["Win11ISOImageInfo"] = $imageInfo $sync["WPFWin11ISOMountDriveLetter"].Text = "Mounted at: $driveLetter | Image file: $(Split-Path $activeWim -Leaf)" $sync["WPFWin11ISOEditionComboBox"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOEditionComboBox"].Items.Clear() foreach ($img in $imageInfo) { [void]$sync["WPFWin11ISOEditionComboBox"].Items.Add("$($img.ImageIndex): $($img.ImageName)") } if ($sync["WPFWin11ISOEditionComboBox"].Items.Count -gt 0) { $proIndex = -1 for ($i = 0; $i -lt $sync["WPFWin11ISOEditionComboBox"].Items.Count; $i++) { if ($sync["WPFWin11ISOEditionComboBox"].Items[$i] -match "Windows 11 Pro(?![\w ])") { $proIndex = $i; break } } $sync["WPFWin11ISOEditionComboBox"].SelectedIndex = if ($proIndex -ge 0) { $proIndex } else { 0 } } }) $sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Visible" $sync["Win11ISODriveLetter"] = $driveLetter $sync["Win11ISOWimPath"] = $activeWim $sync["Win11ISOImagePath"] = $isoPath $sync["WPFWin11ISOModifySection"].Visibility = "Visible" Set-WinUtilProgressBar -Label "ISO verified" -Percent 100 Write-Win11ISOLog "ISO verified OK. Editions found: $($imageInfo.Count)" } catch { Write-Win11ISOLog "ERROR during mount/verify: $_" [System.Windows.MessageBox]::Show( "An error occurred while mounting or verifying the ISO:`n`n$_", "Error", "OK", "Error") } finally { Start-Sleep -Milliseconds 800 Set-WinUtilProgressBar -Label "" -Percent 0 } } function Invoke-WinUtilISOModify { $isoPath = $sync["Win11ISOImagePath"] $driveLetter = $sync["Win11ISODriveLetter"] $wimPath = $sync["Win11ISOWimPath"] if (-not $isoPath) { [System.Windows.MessageBox]::Show( "No verified ISO found. Please complete Steps 1 and 2 first.", "Not Ready", "OK", "Warning") return } $selectedItem = $sync["WPFWin11ISOEditionComboBox"].SelectedItem $selectedWimIndex = 1 if ($selectedItem -and $selectedItem -match '^(\d+):') { $selectedWimIndex = [int]$Matches[1] } elseif ($sync["Win11ISOImageInfo"]) { $selectedWimIndex = $sync["Win11ISOImageInfo"][0].ImageIndex } $selectedEditionName = if ($selectedItem) { ($selectedItem -replace '^\d+:\s*', '') } else { "Unknown" } Write-Win11ISOLog "Selected edition: $selectedEditionName (Index $selectedWimIndex)" $sync["WPFWin11ISOModifyButton"].IsEnabled = $false $sync["Win11ISOModifying"] = $true $workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')" if (Test-Path $workDir) { $workDir = Join-Path $env:TEMP "WinUtil_Win11ISO_$(Get-Date -Format 'yyyyMMdd_HHmmss')_$(([guid]::NewGuid()).ToString('N').Substring(0, 8))" } $autounattendContent = if ($WinUtilAutounattendXml) { $WinUtilAutounattendXml } else { $toolsXml = Join-Path $PSScriptRoot "..\..\tools\autounattend.xml" if (Test-Path $toolsXml) { Get-Content $toolsXml -Raw } else { "" } } $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace.ApartmentState = "STA" $runspace.ThreadOptions = "ReuseThread" $runspace.Open() $injectDrivers = $sync["WPFWin11ISOInjectDrivers"].IsChecked -eq $true $runspace.SessionStateProxy.SetVariable("sync", $sync) $runspace.SessionStateProxy.SetVariable("isoPath", $isoPath) $runspace.SessionStateProxy.SetVariable("driveLetter", $driveLetter) $runspace.SessionStateProxy.SetVariable("wimPath", $wimPath) $runspace.SessionStateProxy.SetVariable("workDir", $workDir) $runspace.SessionStateProxy.SetVariable("selectedWimIndex", $selectedWimIndex) $runspace.SessionStateProxy.SetVariable("selectedEditionName", $selectedEditionName) $runspace.SessionStateProxy.SetVariable("autounattendContent", $autounattendContent) $runspace.SessionStateProxy.SetVariable("injectDrivers", $injectDrivers) $isoScriptFuncDef = "function Invoke-WinUtilISOScript {`n" + ${function:Invoke-WinUtilISOScript}.ToString() + "`n}" $win11ISOLogFuncDef = "function Write-Win11ISOLog {`n" + ${function:Write-Win11ISOLog}.ToString() + "`n}" $runspace.SessionStateProxy.SetVariable("isoScriptFuncDef", $isoScriptFuncDef) $runspace.SessionStateProxy.SetVariable("win11ISOLogFuncDef", $win11ISOLogFuncDef) $script = [Management.Automation.PowerShell]::Create() $script.Runspace = $runspace $script.AddScript({ . ([scriptblock]::Create($isoScriptFuncDef)) . ([scriptblock]::Create($win11ISOLogFuncDef)) function Log($msg) { $ts = (Get-Date).ToString("HH:mm:ss") $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg" $sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length $sync["WPFWin11ISOStatusLog"].ScrollToEnd() }) Add-Content -Path (Join-Path $workDir "WinUtil_Win11ISO.log") -Value "[$ts] $msg" } function SetProgress($label, $pct) { $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = $label $sync.progressBarTextBlock.ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5) }) } function Get-WinUtilEditionIdFromName { param([string]$EditionName) $normalizedName = ($EditionName -replace '^Windows\s+11\s+', '').Trim() switch -Regex ($normalizedName) { '^Home Single Language$' { return 'CoreSingleLanguage' } '^Home N$' { return 'CoreN' } '^Home$' { return 'Core' } '^Pro for Workstations N$' { return 'ProfessionalWorkstationN' } '^Pro for Workstations$' { return 'ProfessionalWorkstation' } '^Pro Education N$' { return 'ProfessionalEducationN' } '^Pro Education$' { return 'ProfessionalEducation' } '^Pro N$' { return 'ProfessionalN' } '^Pro$' { return 'Professional' } '^Education N$' { return 'EducationN' } '^Education$' { return 'Education' } '^Enterprise LTSC N$' { return 'EnterpriseSN' } '^Enterprise LTSC$' { return 'EnterpriseS' } '^Enterprise N$' { return 'EnterpriseN' } '^Enterprise$' { return 'Enterprise' } default { return '' } } } function Get-WinUtilMountedImageEditionId { param( [Parameter(Mandatory)][string]$MountDir, [string]$EditionName, [scriptblock]$Logger ) try { $dismOutput = & dism /English "/Image:$MountDir" /Get-CurrentEdition 2>&1 foreach ($line in $dismOutput) { if ($line -match '^\s*Current Edition\s*:\s*(.+?)\s*$') { $editionId = $Matches[1].Trim() if ($editionId) { if ($Logger) { $null = $Logger.Invoke("Detected mounted image EditionID: $editionId") } return $editionId } } } } catch { if ($Logger) { $null = $Logger.Invoke("Warning: could not detect mounted image EditionID with DISM: $_") } } $fallbackEditionId = Get-WinUtilEditionIdFromName -EditionName $EditionName if ($fallbackEditionId -and $Logger) { $null = $Logger.Invoke("Using fallback EditionID '$fallbackEditionId' from selected edition name.") } return $fallbackEditionId } function Get-DismImageInfoMap { param( [Parameter(Mandatory)][string]$ImagePath, [int]$Index = 1 ) $map = @{} $lines = & dism /English "/Get-ImageInfo" "/ImageFile:$ImagePath" "/Index:$Index" foreach ($line in $lines) { if ($line -match '^\s*([^:]+?)\s*:\s*(.*)$') { $key = $Matches[1].Trim() $val = $Matches[2].Trim() if (-not $map.ContainsKey($key)) { $map[$key] = $val } } } return $map } function Invoke-WinUtilWimMetadataHydration { param( [Parameter(Mandatory)][string]$ImagePath, [Parameter(Mandatory)][string]$EditionName, [scriptblock]$Logger ) $metadataLogger = $Logger function LogMeta([string]$Message) { if ($metadataLogger) { $null = $metadataLogger.Invoke($Message) } } $before = Get-DismImageInfoMap -ImagePath $ImagePath -Index 1 $undefinedBefore = @($before.GetEnumerator() | Where-Object { $_.Value -eq '' } | ForEach-Object { $_.Key }) if ($undefinedBefore.Count -eq 0) { LogMeta "Metadata check: no undefined DISM fields detected." return } LogMeta "Metadata check: undefined DISM fields detected: $($undefinedBefore -join ', ')" LogMeta "Attempting best-effort metadata hydration for install.wim..." $setImage = Get-Command Set-WindowsImage -ErrorAction SilentlyContinue if (-not $setImage) { LogMeta "Set-WindowsImage is unavailable on this host; cannot write additional WIM metadata fields." return } $targetName = if ($EditionName -and $EditionName -ne 'Unknown') { $EditionName } else { $before['Name'] } if (-not $targetName) { $targetName = 'Windows 11' } $targetDescription = if ($before['Description'] -and $before['Description'] -ne '') { $before['Description'] } else { $targetName } $setArgs = @{ ImagePath = $ImagePath Index = 1 Name = $targetName Description = $targetDescription ErrorAction = 'Stop' } try { Set-WindowsImage @setArgs | Out-Null LogMeta "Applied Set-WindowsImage metadata updates (Name/Description)." } catch { LogMeta "Warning: Set-WindowsImage metadata update failed: $_" } $after = Get-DismImageInfoMap -ImagePath $ImagePath -Index 1 $undefinedAfter = @($after.GetEnumerator() | Where-Object { $_.Value -eq '' } | ForEach-Object { $_.Key }) if ($undefinedAfter.Count -eq 0) { LogMeta "Metadata hydration complete: no undefined DISM fields remain." } else { LogMeta "Metadata hydration complete. Remaining undefined DISM fields: $($undefinedAfter -join ', ')" LogMeta "Note: some DISM metadata fields are read-only and come from Microsoft image internals." } } try { $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOSelectSection"].Visibility = "Collapsed" $sync["WPFWin11ISOMountSection"].Visibility = "Collapsed" $sync["WPFWin11ISOModifySection"].Visibility = "Collapsed" }) Log "Creating working directory: $workDir" $isoContents = Join-Path $workDir "iso_contents" $mountDir = Join-Path $workDir "wim_mount" New-Item -ItemType Directory -Path $isoContents, $mountDir -Force SetProgress "Copying ISO contents..." 10 Log "Copying ISO contents from $driveLetter to $isoContents..." & robocopy $driveLetter $isoContents /E /NFL /NDL /NJH /NJS Log "ISO contents copied." SetProgress "Mounting install.wim..." 25 $sourceImageFileName = Split-Path $wimPath -Leaf $localWim = Join-Path $isoContents "sources\$sourceImageFileName" if (-not (Test-Path $localWim)) { throw "Copied ISO image file not found: sources\$sourceImageFileName" } Set-ItemProperty -Path $localWim -Name IsReadOnly -Value $false Log "Mounting install.wim (Index ${selectedWimIndex}: $selectedEditionName) at $mountDir..." Mount-WindowsImage -ImagePath $localWim -Index $selectedWimIndex -Path $mountDir SetProgress "Modifying install.wim..." 45 $selectedEditionId = Get-WinUtilMountedImageEditionId -MountDir $mountDir -EditionName $selectedEditionName -Logger ${function:Log} Log "Applying WinUtil modifications to install.wim..." Invoke-WinUtilISOScript -ScratchDir $mountDir -ISOContentsDir $isoContents -AutoUnattendXml $autounattendContent -InjectCurrentSystemDrivers $injectDrivers -InstallEditionId $selectedEditionId -InstallImageIndex 1 -Log { param($m) Log $m } SetProgress "Cleaning up component store (WinSxS)..." 56 Log "Running DISM component store cleanup (/ResetBase)..." & dism /English "/image:$mountDir" /Cleanup-Image /StartComponentCleanup /ResetBase | ForEach-Object { Log $_ } Log "Component store cleanup complete." SetProgress "Saving modified install.wim..." 65 Log "Dismounting and saving install.wim. This will take several minutes..." Dismount-WindowsImage -Path $mountDir -Save Log "install.wim saved." SetProgress "Removing unused editions from install.wim..." 70 Log "Exporting edition '$selectedEditionName' (Index $selectedWimIndex) to a single-edition install.wim..." $exportWim = Join-Path $isoContents "sources\install_export.wim" Export-WindowsImage -SourceImagePath $localWim -SourceIndex $selectedWimIndex -DestinationImagePath $exportWim Remove-Item -Path $localWim -Force Rename-Item -Path $exportWim -NewName "install.wim" -Force $localWim = Join-Path $isoContents "sources\install.wim" Log "Unused editions removed. install.wim now contains only '$selectedEditionName'." SetProgress "Hydrating WIM metadata..." 76 Invoke-WinUtilWimMetadataHydration -ImagePath $localWim -EditionName $selectedEditionName -Logger ${function:Log} SetProgress "Dismounting source ISO..." 80 Log "Dismounting original ISO..." Dismount-DiskImage -ImagePath $isoPath $sync["Win11ISOWorkDir"] = $workDir $sync["Win11ISOContentsDir"] = $isoContents SetProgress "Modification complete" 100 Log "install.wim modification complete. Choose an output option in Step 4." $sync["WPFWin11ISOOutputSection"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOOutputSection"].Visibility = "Visible" }) } catch { Log "ERROR during modification: $_" try { if (Test-Path $mountDir) { $mountedImages = Get-WindowsImage -Mounted | Where-Object { $_.Path -eq $mountDir } if ($mountedImages) { Log "Cleaning up: dismounting install.wim (discarding changes)..." Dismount-WindowsImage -Path $mountDir -Discard } } } catch { Log "Warning: could not dismount install.wim during cleanup: $_" } try { $mountedISO = Get-DiskImage -ImagePath $isoPath if ($mountedISO -and $mountedISO.Attached) { Log "Cleaning up: dismounting source ISO..." Dismount-DiskImage -ImagePath $isoPath } } catch { Log "Warning: could not dismount ISO during cleanup: $_" } try { if (Test-Path $workDir) { Log "Cleaning up: removing temp directory $workDir..." Remove-Item -Path $workDir -Recurse -Force } } catch { Log "Warning: could not remove temp directory during cleanup: $_" } $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ [System.Windows.MessageBox]::Show( "An error occurred during install.wim modification:`n`n$_", "Modification Error", "OK", "Error") }) } finally { Start-Sleep -Milliseconds 800 $sync["Win11ISOModifying"] = $false $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = "" $sync.progressBarTextBlock.ToolTip = "" $sync.ProgressBar.Value = 0 $sync["WPFWin11ISOModifyButton"].IsEnabled = $true if ($sync["WPFWin11ISOOutputSection"].Visibility -ne "Visible") { $sync["WPFWin11ISOSelectSection"].Visibility = "Visible" $sync["WPFWin11ISOMountSection"].Visibility = "Visible" $sync["WPFWin11ISOModifySection"].Visibility = "Visible" } }) } }) $script.BeginInvoke() } function Invoke-WinUtilISOCheckExistingWork { if ($sync["Win11ISOContentsDir"] -and (Test-Path $sync["Win11ISOContentsDir"])) { return } # Check if ISO modification is currently in progress if ($sync["Win11ISOModifying"]) { return } $existingWorkDir = Get-Item -Path (Join-Path $env:TEMP "WinUtil_Win11ISO*") | Where-Object { $_.PSIsContainer } | Sort-Object LastWriteTime -Descending | Select-Object -First 1 if (-not $existingWorkDir) { return } $isoContents = Join-Path $existingWorkDir.FullName "iso_contents" if (-not (Test-Path $isoContents)) { return } $sync["Win11ISOWorkDir"] = $existingWorkDir.FullName $sync["Win11ISOContentsDir"] = $isoContents $sync["WPFWin11ISOSelectSection"].Visibility = "Collapsed" $sync["WPFWin11ISOMountSection"].Visibility = "Collapsed" $sync["WPFWin11ISOModifySection"].Visibility = "Collapsed" $sync["WPFWin11ISOOutputSection"].Visibility = "Visible" $modified = $existingWorkDir.LastWriteTime.ToString("yyyy-MM-dd HH:mm") Write-Win11ISOLog "Existing working directory found: $($existingWorkDir.FullName)" Write-Win11ISOLog "Last modified: $modified - Skipping Steps 1-3 and resuming at Step 4." Write-Win11ISOLog "Click 'Clean & Reset' if you want to start over with a new ISO." [System.Windows.MessageBox]::Show( "A previous WinUtil ISO working directory was found:`n`n$($existingWorkDir.FullName)`n`n(Last modified: $modified)`n`nStep 4 (output options) has been restored so you can save the already-modified image.`n`nClick 'Clean & Reset' in Step 4 if you want to start over.", "Existing Work Found", "OK", "Info") } function Invoke-WinUtilISOCleanAndReset { $workDir = $sync["Win11ISOWorkDir"] if ($workDir -and (Test-Path $workDir)) { $confirm = [System.Windows.MessageBox]::Show( "This will delete the temporary working directory:`n`n$workDir`n`nAnd reset the interface back to the start.`n`nContinue?", "Clean & Reset", "YesNo", "Warning") if ($confirm -ne "Yes") { return } } $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $false $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace.ApartmentState = "STA" $runspace.ThreadOptions = "ReuseThread" $runspace.Open() $runspace.SessionStateProxy.SetVariable("sync", $sync) $runspace.SessionStateProxy.SetVariable("workDir", $workDir) $script = [Management.Automation.PowerShell]::Create() $script.Runspace = $runspace $script.AddScript({ function Log($msg) { $ts = (Get-Date).ToString("HH:mm:ss") $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg" $sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length $sync["WPFWin11ISOStatusLog"].ScrollToEnd() }) Add-Content -Path (Join-Path $workDir "WinUtil_Win11ISO.log") -Value "[$ts] $msg" } function SetProgress($label, $pct) { $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = $label $sync.progressBarTextBlock.ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5) }) } try { if ($workDir) { $mountDir = Join-Path $workDir "wim_mount" try { $mountedImages = Get-WindowsImage -Mounted | Where-Object { $_.Path -like "$workDir*" } if ($mountedImages) { foreach ($img in $mountedImages) { Log "Dismounting WIM at: $($img.Path) (discarding changes)..." SetProgress "Dismounting WIM image..." 3 Dismount-WindowsImage -Path $img.Path -Discard Log "WIM dismounted successfully." } } elseif (Test-Path $mountDir) { Log "No mounted WIM reported by Get-WindowsImage. Running DISM /Cleanup-Wim as a precaution..." SetProgress "Running DISM cleanup..." 3 & dism /English /Cleanup-Wim | ForEach-Object { Log $_ } } } catch { Log "Warning: could not dismount WIM cleanly. Attempting DISM /Cleanup-Wim fallback: $_" try { & dism /English /Cleanup-Wim | ForEach-Object { Log $_ } } catch { Log "Warning: DISM /Cleanup-Wim also failed: $_" } } } if ($workDir -and (Test-Path $workDir)) { Log "Scanning files to delete in: $workDir" SetProgress "Scanning files..." 5 $allFiles = @(Get-ChildItem -Path $workDir -File -Recurse -Force) $allDirs = @(Get-ChildItem -Path $workDir -Directory -Recurse -Force | Sort-Object { $_.FullName.Length } -Descending) $total = $allFiles.Count $deleted = 0 Log "Found $total files to delete." foreach ($f in $allFiles) { try { Remove-Item -Path $f.FullName -Force } catch { Log "WARNING: could not delete $($f.FullName): $_" } $deleted++ if ($deleted % 100 -eq 0 -or $deleted -eq $total) { $pct = [math]::Round(($deleted / [Math]::Max($total, 1)) * 85) + 5 SetProgress "Deleting files in $($f.Directory.Name)... ($deleted / $total)" $pct } } foreach ($d in $allDirs) { try { Remove-Item -Path $d.FullName -Force } catch { Log "WARNING: could not delete $($d.FullName): $_" } } try { Remove-Item -Path $workDir -Recurse -Force } catch { Log "WARNING: could not delete temp directory ${workDir}: $_" } if (Test-Path $workDir) { Log "WARNING: some items could not be deleted in $workDir" } else { Log "Temp directory deleted successfully." } } else { Log "No temp directory found - resetting UI." } SetProgress "Resetting UI..." 95 Log "Resetting interface..." $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["Win11ISOWorkDir"] = $null $sync["Win11ISOContentsDir"] = $null $sync["Win11ISOImagePath"] = $null $sync["Win11ISODriveLetter"] = $null $sync["Win11ISOWimPath"] = $null $sync["Win11ISOImageInfo"] = $null $sync["Win11ISOUSBDisks"] = $null $sync["WPFWin11ISOPath"].Text = "No ISO selected..." $sync["WPFWin11ISOFileInfo"].Visibility = "Collapsed" $sync["WPFWin11ISOVerifyResultPanel"].Visibility = "Collapsed" $sync["WPFWin11ISOOptionUSB"].Visibility = "Collapsed" $sync["WPFWin11ISOOutputSection"].Visibility = "Collapsed" $sync["WPFWin11ISOModifySection"].Visibility = "Collapsed" $sync["WPFWin11ISOMountSection"].Visibility = "Collapsed" $sync["WPFWin11ISOSelectSection"].Visibility = "Visible" $sync["WPFWin11ISOModifyButton"].IsEnabled = $true $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true $sync.progressBarTextBlock.Text = "" $sync.progressBarTextBlock.ToolTip = "" $sync.ProgressBar.Value = 0 $sync["WPFWin11ISOStatusLog"].Text = "Ready. Please select a Windows 11 ISO to begin." }) } catch { Log "ERROR during Clean & Reset: $_" $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = "" $sync.progressBarTextBlock.ToolTip = "" $sync.ProgressBar.Value = 0 $sync["WPFWin11ISOCleanResetButton"].IsEnabled = $true }) } }) $script.BeginInvoke() } function Invoke-WinUtilISOExport { $contentsDir = $sync["Win11ISOContentsDir"] if (-not $contentsDir -or -not (Test-Path $contentsDir)) { [System.Windows.MessageBox]::Show( "No modified ISO content found. Please complete Steps 1-3 first.", "Not Ready", "OK", "Warning") return } Add-Type -AssemblyName System.Windows.Forms $dlg = [System.Windows.Forms.SaveFileDialog]::new() $dlg.Title = "Save Modified Windows 11 ISO" $dlg.Filter = "ISO files (*.iso)|*.iso" $dlg.FileName = "Win11_Modified_$(Get-Date -Format 'yyyyMMdd').iso" $dlg.InitialDirectory = [System.Environment]::GetFolderPath("Desktop") if ($dlg.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) { return } $outputISO = $dlg.FileName # Locate oscdimg.exe (Windows ADK or winget per-user install) $oscdimg = Get-ChildItem "C:\Program Files (x86)\Windows Kits" -Recurse -Filter "oscdimg.exe" | Select-Object -First 1 -ExpandProperty FullName if (-not $oscdimg) { $oscdimg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Recurse -Filter "oscdimg.exe" | Where-Object { $_.FullName -match 'Microsoft\.OSCDIMG' } | Select-Object -First 1 -ExpandProperty FullName } if (-not $oscdimg) { Write-Win11ISOLog "oscdimg.exe not found. Attempting to install via winget..." try { # First ensure winget is installed and operational Install-WinUtilWinget $winget = Get-Command winget $result = & $winget install -e --id Microsoft.OSCDIMG --accept-package-agreements --accept-source-agreements Write-Win11ISOLog "winget output: $result" $oscdimg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Recurse -Filter "oscdimg.exe" | Where-Object { $_.FullName -match 'Microsoft\.OSCDIMG' } | Select-Object -First 1 -ExpandProperty FullName } catch { Write-Win11ISOLog "winget not available or install failed: $_" } if (-not $oscdimg) { Write-Win11ISOLog "oscdimg.exe still not found after install attempt." [System.Windows.MessageBox]::Show( "oscdimg.exe could not be found or installed automatically.`n`nPlease install it manually:`n winget install -e --id Microsoft.OSCDIMG`n`nOr install the Windows ADK from:`nhttps://learn.microsoft.com/windows-hardware/get-started/adk-install", "oscdimg Not Found", "OK", "Warning") return } Write-Win11ISOLog "oscdimg.exe installed successfully." } $sync["WPFWin11ISOChooseISOButton"].IsEnabled = $false $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace.ApartmentState = "STA" $runspace.ThreadOptions = "ReuseThread" $runspace.Open() $runspace.SessionStateProxy.SetVariable("sync", $sync) $runspace.SessionStateProxy.SetVariable("contentsDir", $contentsDir) $runspace.SessionStateProxy.SetVariable("outputISO", $outputISO) $runspace.SessionStateProxy.SetVariable("oscdimg", $oscdimg) $win11ISOLogFuncDef = "function Write-Win11ISOLog {`n" + ${function:Write-Win11ISOLog}.ToString() + "`n}" $runspace.SessionStateProxy.SetVariable("win11ISOLogFuncDef", $win11ISOLogFuncDef) $script = [Management.Automation.PowerShell]::Create() $script.Runspace = $runspace $script.AddScript({ . ([scriptblock]::Create($win11ISOLogFuncDef)) function SetProgress($label, $pct) { $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = $label $sync.progressBarTextBlock.ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5) }) } try { Write-Win11ISOLog "Exporting to ISO: $outputISO" SetProgress "Building ISO..." 10 $bootData = "2#p0,e,b`"$contentsDir\boot\etfsboot.com`"#pEF,e,b`"$contentsDir\efi\microsoft\boot\efisys.bin`"" $oscdimgArgs = @("-m", "-o", "-u2", "-udfver102", "-bootdata:$bootData", "-l`"CTOS_MODIFIED`"", "`"$contentsDir`"", "`"$outputISO`"") Write-Win11ISOLog "Running oscdimg..." $psi = [System.Diagnostics.ProcessStartInfo]::new() $psi.FileName = $oscdimg $psi.Arguments = $oscdimgArgs -join " " $psi.RedirectStandardOutput = $true $psi.RedirectStandardError = $true $psi.UseShellExecute = $false $psi.CreateNoWindow = $true $proc = [System.Diagnostics.Process]::new() $proc.StartInfo = $psi $proc.Start() # Stream stdout line-by-line as oscdimg runs while (-not $proc.StandardOutput.EndOfStream) { $line = $proc.StandardOutput.ReadLine() if ($line.Trim()) { Write-Win11ISOLog $line } } $proc.WaitForExit() # Flush any stderr after process exits $stderr = $proc.StandardError.ReadToEnd() foreach ($line in ($stderr -split "`r?`n")) { if ($line.Trim()) { Write-Win11ISOLog "[stderr]$line" } } if ($proc.ExitCode -eq 0) { SetProgress "ISO exported" 100 Write-Win11ISOLog "ISO exported successfully: $outputISO" $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ [System.Windows.MessageBox]::Show("ISO exported successfully!`n`n$outputISO", "Export Complete", "OK", "Info") }) } else { Write-Win11ISOLog "oscdimg exited with code $($proc.ExitCode)." $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ [System.Windows.MessageBox]::Show( "oscdimg exited with code $($proc.ExitCode).`nCheck the status log for details.", "Export Error", "OK", "Error") }) } } catch { Write-Win11ISOLog "ERROR during ISO export: $_" $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ [System.Windows.MessageBox]::Show("ISO export failed:`n`n$_", "Error", "OK", "Error") }) } finally { Start-Sleep -Milliseconds 800 $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = "" $sync.progressBarTextBlock.ToolTip = "" $sync.ProgressBar.Value = 0 $sync["WPFWin11ISOChooseISOButton"].IsEnabled = $true }) } }) $script.BeginInvoke() } function Invoke-WinUtilISOScript { <# .SYNOPSIS Applies WinUtil modifications to a mounted Windows 11 install.wim image. .DESCRIPTION Removes AppX bloatware and OneDrive, optionally injects all drivers exported from the running system into install.wim and boot.wim (controlled by the -InjectCurrentSystemDrivers switch), applies offline registry tweaks (hardware bypass, privacy, OOBE, telemetry, update suppression), deletes CEIP/WU scheduled-task definition files, and optionally writes autounattend.xml to the ISO root and removes the support\ folder from the ISO contents directory. All setup scripts embedded in the autounattend.xml nodes are written directly into the WIM at their target paths under C:\Windows\Setup\Scripts\ to ensure they survive Windows Setup stripping unrecognised-namespace XML elements from the Panther copy of the answer file. Mounting/dismounting the WIM is the caller's responsibility (e.g. Invoke-WinUtilISO). .PARAMETER ScratchDir Mandatory. Full path to the directory where the Windows image is currently mounted. .PARAMETER ISOContentsDir Optional. Root directory of the extracted ISO contents. When supplied, autounattend.xml is written here and the support\ folder is removed. .PARAMETER AutoUnattendXml Optional. Full XML content for autounattend.xml. If empty, the OOBE bypass file is skipped and a warning is logged. .PARAMETER InjectCurrentSystemDrivers Optional. When $true, exports all drivers from the running system and injects them into install.wim and boot.wim index 2 (Windows Setup PE). Defaults to $false. .PARAMETER InstallEditionId Optional. Windows edition ID for the selected image, for example Professional or Core. Used to write sources\ei.cfg so setup does not fall back to an embedded firmware product key for a different edition. .PARAMETER InstallImageIndex Optional. Image index that setup should install from the final install.wim. Win11 Creator exports the selected edition to a single-image WIM, so this defaults to 1. .PARAMETER Log Optional ScriptBlock for progress/status logging. Receives a single [string] argument. .EXAMPLE Invoke-WinUtilISOScript -ScratchDir "C:\Temp\wim_mount" .EXAMPLE Invoke-WinUtilISOScript ` -ScratchDir $mountDir ` -ISOContentsDir $isoRoot ` -AutoUnattendXml (Get-Content .\tools\autounattend.xml -Raw) ` -Log { param($m) Write-Host $m } .NOTES Author : Chris Titus @christitustech GitHub : https://github.com/ChrisTitusTech #> param ( [Parameter(Mandatory)][string]$ScratchDir, [string]$ISOContentsDir = "", [string]$AutoUnattendXml = "", [bool]$InjectCurrentSystemDrivers = $false, [string]$InstallEditionId = "", [int]$InstallImageIndex = 1, [scriptblock]$Log = { param($m) Write-Output $m } ) function Set-ISOScriptReg { param ([string]$Path, [string]$Name, [string]$Type, [string]$Value) try { & reg add $Path /v $Name /t $Type /d $Value /f & $Log "Set registry value: $Path\$Name" } catch { & $Log "Error setting registry value: $_" } } function Remove-ISOScriptReg { param ([string]$path) try { & reg delete $path /f & $Log "Removed registry key: $path" } catch { & $Log "Error removing registry key: $_" } } function Add-DriversToImage { param ([string]$MountPath, [string]$DriverDir, [string]$Label = "image", [scriptblock]$Logger) & dism /English "/image:$MountPath" /Add-Driver "/Driver:$DriverDir" /Recurse | ForEach-Object { & $Logger " dism[$Label]: $_" } } function Invoke-BootWimInject { param ([string]$BootWimPath, [string]$DriverDir, [scriptblock]$Logger) Set-ItemProperty -Path $BootWimPath -Name IsReadOnly -Value $false $mountDir = Join-Path $env:TEMP "WinUtil_BootMount_$(Get-Random)" New-Item -Path $mountDir -ItemType Directory -Force try { & $Logger "Mounting boot.wim (index 2) for driver injection..." Mount-WindowsImage -ImagePath $BootWimPath -Index 2 -Path $mountDir Add-DriversToImage -MountPath $mountDir -DriverDir $DriverDir -Label "boot" -Logger $Logger & $Logger "Saving boot.wim..." Dismount-WindowsImage -Path $mountDir -Save & $Logger "boot.wim driver injection complete." } catch { & $Logger "Warning: boot.wim driver injection failed: $_" try { Dismount-WindowsImage -Path $mountDir -Discard } catch { & $Logger "Warning: could not discard boot.wim mount: $_" } } finally { Remove-Item -Path $mountDir -Recurse -Force } } function Get-WinUtilISOScriptChildElement { param ( [Parameter(Mandatory)][System.Xml.XmlElement]$Parent, [Parameter(Mandatory)][string]$Name, [Parameter(Mandatory)][string]$NamespaceUri ) foreach ($childNode in $Parent.ChildNodes) { if ($childNode.NodeType -eq [System.Xml.XmlNodeType]::Element -and $childNode.LocalName -eq $Name -and $childNode.NamespaceURI -eq $NamespaceUri) { return [System.Xml.XmlElement]$childNode } } $childElement = $Parent.OwnerDocument.CreateElement($Name, $NamespaceUri) [void]$Parent.AppendChild($childElement) return $childElement } function ConvertTo-WinUtilISOAnswerFile { param ( [Parameter(Mandatory)][string]$XmlContent, [int]$ImageIndex = 1 ) if ($ImageIndex -lt 1) { $ImageIndex = 1 } $unattendNs = "urn:schemas-microsoft-com:unattend" $wcmNs = "http://schemas.microsoft.com/WMIConfig/2002/State" $xmlDoc = [xml]::new() $xmlDoc.PreserveWhitespace = $true $xmlDoc.LoadXml($XmlContent) if ($xmlDoc.DocumentElement.NamespaceURI -ne $unattendNs) { throw "Unexpected autounattend.xml namespace: $($xmlDoc.DocumentElement.NamespaceURI)" } if (-not $xmlDoc.DocumentElement.HasAttribute("xmlns:wcm")) { $xmlDoc.DocumentElement.SetAttribute("wcm", "http://www.w3.org/2000/xmlns/", $wcmNs) } $nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable) $nsMgr.AddNamespace("u", $unattendNs) $windowsPESettings = $xmlDoc.SelectSingleNode('/u:unattend/u:settings[@pass="windowsPE"]', $nsMgr) if (-not $windowsPESettings) { $windowsPESettings = $xmlDoc.CreateElement("settings", $unattendNs) $windowsPESettings.SetAttribute("pass", "windowsPE") [void]$xmlDoc.DocumentElement.PrependChild($windowsPESettings) } $setupComponent = $windowsPESettings.SelectSingleNode('u:component[@name="Microsoft-Windows-Setup"]', $nsMgr) if (-not $setupComponent) { $setupComponent = $xmlDoc.CreateElement("component", $unattendNs) $setupComponent.SetAttribute("name", "Microsoft-Windows-Setup") $setupComponent.SetAttribute("processorArchitecture", "amd64") $setupComponent.SetAttribute("publicKeyToken", "31bf3856ad364e35") $setupComponent.SetAttribute("language", "neutral") $setupComponent.SetAttribute("versionScope", "nonSxS") [void]$windowsPESettings.AppendChild($setupComponent) } $productKeyNodes = @($setupComponent.SelectNodes("u:UserData/u:ProductKey", $nsMgr)) foreach ($productKeyNode in $productKeyNodes) { $keyNode = $productKeyNode.SelectSingleNode("u:Key", $nsMgr) $keyValue = if ($keyNode) { $keyNode.InnerText.Trim() } else { "" } if ([string]::IsNullOrWhiteSpace($keyValue) -or $keyValue -eq "00000-00000-00000-00000-00000") { [void]$productKeyNode.ParentNode.RemoveChild($productKeyNode) } } $imageInstall = Get-WinUtilISOScriptChildElement -Parent $setupComponent -Name "ImageInstall" -NamespaceUri $unattendNs $osImage = Get-WinUtilISOScriptChildElement -Parent $imageInstall -Name "OSImage" -NamespaceUri $unattendNs $installFrom = Get-WinUtilISOScriptChildElement -Parent $osImage -Name "InstallFrom" -NamespaceUri $unattendNs $existingMetadataNodes = @($installFrom.SelectNodes("u:MetaData", $nsMgr)) foreach ($metadataNode in $existingMetadataNodes) { [void]$installFrom.RemoveChild($metadataNode) } $metadata = $xmlDoc.CreateElement("MetaData", $unattendNs) $actionAttribute = $xmlDoc.CreateAttribute("wcm", "action", $wcmNs) $actionAttribute.Value = "add" [void]$metadata.Attributes.Append($actionAttribute) $keyElement = $xmlDoc.CreateElement("Key", $unattendNs) $keyElement.InnerText = "/IMAGE/INDEX" [void]$metadata.AppendChild($keyElement) $valueElement = $xmlDoc.CreateElement("Value", $unattendNs) $valueElement.InnerText = [string]$ImageIndex [void]$metadata.AppendChild($valueElement) [void]$installFrom.AppendChild($metadata) return $xmlDoc.OuterXml } function Write-WinUtilISOEditionConfig { param ( [Parameter(Mandatory)][string]$ContentRoot, [string]$EditionId, [scriptblock]$Logger ) if (-not (Test-Path $ContentRoot)) { return } $sourcesDir = Join-Path $ContentRoot "sources" New-Item -Path $sourcesDir -ItemType Directory -Force | Out-Null $pidPath = Join-Path $sourcesDir "PID.txt" if (Test-Path $pidPath) { Remove-Item -Path $pidPath -Force & $Logger "Removed sources\PID.txt so setup will not force a stale or mismatched product key." } if ([string]::IsNullOrWhiteSpace($EditionId)) { & $Logger "Warning: selected edition ID is unknown - skipping sources\ei.cfg fallback." return } $eiCfgPath = Join-Path $sourcesDir "ei.cfg" $eiCfg = @" [EditionID] $EditionId [Channel] Retail [VL] 0 "@.Trim() Set-Content -Path $eiCfgPath -Value $eiCfg -Encoding ASCII -Force & $Logger "Written sources\ei.cfg for EditionID '$EditionId'." } # -- 1. Remove provisioned AppX packages ---------------------------------- & $Log "Removing provisioned AppX packages..." $packages = & dism /English "/image:$ScratchDir" /Get-ProvisionedAppxPackages | ForEach-Object { if ($_ -match 'PackageName : (.*)') { $matches[1] } } $packagePrefixes = @( 'Clipchamp.Clipchamp', 'Microsoft.BingNews', 'Microsoft.BingSearch', 'Microsoft.BingWeather', 'Microsoft.GetHelp', 'Microsoft.MicrosoftOfficeHub', 'Microsoft.MicrosoftSolitaireCollection', 'Microsoft.MicrosoftStickyNotes', 'Microsoft.OutlookForWindows', 'Microsoft.Paint', 'Microsoft.PowerAutomateDesktop', 'Microsoft.StartExperiencesApp', 'Microsoft.Todos', 'Microsoft.Windows.DevHome', 'Microsoft.WindowsFeedbackHub', 'Microsoft.WindowsSoundRecorder', 'Microsoft.ZuneMusic', 'MicrosoftCorporationII.QuickAssist', 'MSTeams' ) $packages | Where-Object { $pkg = $_; $packagePrefixes | Where-Object { $pkg -like "*$_*" } } | ForEach-Object { & dism /English "/image:$ScratchDir" /Remove-ProvisionedAppxPackage "/PackageName:$_" } # -- 2. Inject current system drivers (optional) --------------------------- if ($InjectCurrentSystemDrivers) { & $Log "Exporting all drivers from running system..." $driverExportRoot = Join-Path $env:TEMP "WinUtil_DriverExport_$(Get-Random)" New-Item -Path $driverExportRoot -ItemType Directory -Force try { Export-WindowsDriver -Online -Destination $driverExportRoot & $Log "Injecting current system drivers into install.wim..." Add-DriversToImage -MountPath $ScratchDir -DriverDir $driverExportRoot -Label "install" -Logger $Log & $Log "install.wim driver injection complete." if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) { $bootWim = Join-Path $ISOContentsDir "sources\boot.wim" if (Test-Path $bootWim) { & $Log "Injecting current system drivers into boot.wim..." Invoke-BootWimInject -BootWimPath $bootWim -DriverDir $driverExportRoot -Logger $Log } else { & $Log "Warning: boot.wim not found - skipping boot.wim driver injection." } } } catch { & $Log "Error during driver export/injection: $_" } finally { Remove-Item -Path $driverExportRoot -Recurse -Force } } else { & $Log "Driver injection skipped." } # -- 3. Registry tweaks ---------------------------------------------------- & $Log "Loading offline registry hives..." reg load HKLM\zCOMPONENTS "$ScratchDir\Windows\System32\config\COMPONENTS" reg load HKLM\zDEFAULT "$ScratchDir\Windows\System32\config\default" reg load HKLM\zNTUSER "$ScratchDir\Users\Default\ntuser.dat" reg load HKLM\zSOFTWARE "$ScratchDir\Windows\System32\config\SOFTWARE" reg load HKLM\zSYSTEM "$ScratchDir\Windows\System32\config\SYSTEM" & $Log "Bypassing system requirements..." Set-ISOScriptReg -Path 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV1' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zDEFAULT\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV2' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV1' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Control Panel\UnsupportedHardwareNotificationCache' -Name 'SV2' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassCPUCheck' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassRAMCheck' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassSecureBootCheck' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassStorageCheck' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\LabConfig' -Name 'BypassTPMCheck' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\Setup\MoSetup' -Name 'AllowUpgradesWithUnsupportedTPMOrCPU' -Type 'REG_DWORD' -Value '1' & $Log "Disabling sponsored apps..." Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'OemPreInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'PreInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SilentInstalledAppsEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableWindowsConsumerFeatures' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'ContentDeliveryAllowed' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\PolicyManager\current\device\Start' -Name 'ConfigureStartPins' -Type 'REG_SZ' -Value '{"pinnedList": [{}]}' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'FeatureManagementEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'PreInstalledAppsEverEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SoftLandingEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContentEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-310093Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338388Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338389Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-338393Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-353694Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SubscribedContent-353696Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name 'SystemPaneSuggestionsEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\PushToInstall' -Name 'DisablePushToInstall' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\MRT' -Name 'DontOfferThroughWUAU' -Type 'REG_DWORD' -Value '1' Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\Subscriptions' Remove-ISOScriptReg 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager\SuggestedApps' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableConsumerAccountStateContent' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\CloudContent' -Name 'DisableCloudOptimizedContent' -Type 'REG_DWORD' -Value '1' & $Log "Enabling local accounts on OOBE..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\OOBE' -Name 'BypassNRO' -Type 'REG_DWORD' -Value '1' if ($AutoUnattendXml) { $preparedAutoUnattendXml = $AutoUnattendXml try { $preparedAutoUnattendXml = ConvertTo-WinUtilISOAnswerFile -XmlContent $AutoUnattendXml -ImageIndex $InstallImageIndex & $Log "Prepared autounattend.xml to install image index $InstallImageIndex without forcing a product key." } catch { & $Log "Warning: could not prepare autounattend.xml image selection: $_" } try { $xmlDoc = [xml]::new() $xmlDoc.LoadXml($preparedAutoUnattendXml) $nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable) $nsMgr.AddNamespace("sg", "https://schneegans.de/windows/unattend-generator/") $fileNodes = $xmlDoc.SelectNodes("//sg:File", $nsMgr) if ($fileNodes -and $fileNodes.Count -gt 0) { foreach ($fileNode in $fileNodes) { $absPath = $fileNode.GetAttribute("path") $relPath = $absPath -replace '^[A-Za-z]:[/\\]', '' $destPath = Join-Path $ScratchDir $relPath New-Item -Path (Split-Path $destPath -Parent) -ItemType Directory -Force $ext = [IO.Path]::GetExtension($destPath).ToLower() $encoding = switch ($ext) { { $_ -in '.ps1', '.xml' } { [System.Text.Encoding]::UTF8 } { $_ -in '.reg', '.vbs', '.js' } { [System.Text.UnicodeEncoding]::new($false, $true) } default { [System.Text.Encoding]::Default } } [System.IO.File]::WriteAllBytes($destPath, ($encoding.GetPreamble() + $encoding.GetBytes($fileNode.InnerText.Trim()))) & $Log "Pre-staged setup script: $relPath" } } else { & $Log "Warning: no nodes found in autounattend.xml - setup scripts not pre-staged." } } catch { & $Log "Warning: could not pre-stage setup scripts from autounattend.xml: $_" } if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) { $isoDest = Join-Path $ISOContentsDir "autounattend.xml" Set-Content -Path $isoDest -Value $preparedAutoUnattendXml -Encoding UTF8 -Force & $Log "Written autounattend.xml to ISO root ($isoDest)." } } else { & $Log "Warning: autounattend.xml content is empty - skipping OOBE bypass file." } if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) { Write-WinUtilISOEditionConfig -ContentRoot $ISOContentsDir -EditionId $InstallEditionId -Logger $Log } & $Log "Disabling reserved storage..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\ReserveManager' -Name 'ShippedWithReserves' -Type 'REG_DWORD' -Value '0' & $Log "Disabling BitLocker device encryption..." Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Control\BitLocker' -Name 'PreventDeviceEncryption' -Type 'REG_DWORD' -Value '1' & $Log "Disabling Chat icon..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Chat' -Name 'ChatIcon' -Type 'REG_DWORD' -Value '3' Set-ISOScriptReg -Path 'HKLM\zNTUSER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name 'TaskbarMn' -Type 'REG_DWORD' -Value '0' & $Log "Disabling OneDrive folder backup..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\OneDrive' -Name 'DisableFileSyncNGSC' -Type 'REG_DWORD' -Value '1' & $Log "Disabling telemetry..." Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\AdvertisingInfo' -Name 'Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Windows\CurrentVersion\Privacy' -Name 'TailoredExperiencesWithDiagnosticDataEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Speech_OneCore\Settings\OnlineSpeechPrivacy' -Name 'HasAccepted' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Input\TIPC' -Name 'Enabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -Name 'RestrictImplicitInkCollection' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization' -Name 'RestrictImplicitTextCollection' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\InputPersonalization\TrainedDataStore' -Name 'HarvestContacts' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zNTUSER\Software\Microsoft\Personalization\Settings' -Name 'AcceptedPrivacyPolicy' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\DataCollection' -Name 'AllowTelemetry' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\dmwappushservice' -Name 'Start' -Type 'REG_DWORD' -Value '4' & $Log "Preventing installation of DevHome and Outlook..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\OutlookUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler\DevHomeUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1' Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\OutlookUpdate' Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\DevHomeUpdate' & $Log "Disabling Copilot..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsCopilot' -Name 'TurnOffWindowsCopilot' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Edge' -Name 'HubsSidebarEnabled' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Explorer' -Name 'DisableSearchBoxSuggestions' -Type 'REG_DWORD' -Value '1' & $Log "Disabling Windows Update during OOBE (re-enabled on first logon via FirstLogon.ps1)..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'NoAutoUpdate' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'AUOptions' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'UseWUServer' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'DisableWindowsUpdateAccess' -Type 'REG_DWORD' -Value '1' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'WUServer' -Type 'REG_SZ' -Value 'http://localhost:8080' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\WindowsUpdate' -Name 'WUStatusServer' -Type 'REG_SZ' -Value 'http://localhost:8080' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' -Name 'workCompleted' -Type 'REG_DWORD' -Value '1' Remove-ISOScriptReg 'HKLM\zSOFTWARE\Microsoft\WindowsUpdate\Orchestrator\UScheduler_Oobe\WindowsUpdate' Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config' -Name 'DODownloadMode' -Type 'REG_DWORD' -Value '0' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\BITS' -Name 'Start' -Type 'REG_DWORD' -Value '4' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\wuauserv' -Name 'Start' -Type 'REG_DWORD' -Value '4' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\UsoSvc' -Name 'Start' -Type 'REG_DWORD' -Value '4' Set-ISOScriptReg -Path 'HKLM\zSYSTEM\ControlSet001\Services\WaaSMedicSvc' -Name 'Start' -Type 'REG_DWORD' -Value '4' & $Log "Preventing installation of Teams..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Teams' -Name 'DisableInstallation' -Type 'REG_DWORD' -Value '1' & $Log "Preventing installation of new Outlook..." Set-ISOScriptReg -Path 'HKLM\zSOFTWARE\Policies\Microsoft\Windows\Windows Mail' -Name 'PreventRun' -Type 'REG_DWORD' -Value '1' & $Log "Unloading offline registry hives..." reg unload HKLM\zCOMPONENTS reg unload HKLM\zDEFAULT reg unload HKLM\zNTUSER reg unload HKLM\zSOFTWARE reg unload HKLM\zSYSTEM # -- 4. Delete scheduled task definition files ----------------------------- & $Log "Deleting scheduled task definition files..." $tasksPath = "$ScratchDir\Windows\System32\Tasks" Remove-Item "$tasksPath\Microsoft\Windows\Application Experience\Microsoft Compatibility Appraiser" -Force Remove-Item "$tasksPath\Microsoft\Windows\Customer Experience Improvement Program" -Recurse -Force Remove-Item "$tasksPath\Microsoft\Windows\Application Experience\ProgramDataUpdater" -Force Remove-Item "$tasksPath\Microsoft\Windows\Chkdsk\Proxy" -Force Remove-Item "$tasksPath\Microsoft\Windows\Windows Error Reporting\QueueReporting" -Force Remove-Item "$tasksPath\Microsoft\Windows\InstallService" -Recurse -Force Remove-Item "$tasksPath\Microsoft\Windows\UpdateOrchestrator" -Recurse -Force Remove-Item "$tasksPath\Microsoft\Windows\UpdateAssistant" -Recurse -Force Remove-Item "$tasksPath\Microsoft\Windows\WaaSMedic" -Recurse -Force Remove-Item "$tasksPath\Microsoft\Windows\WindowsUpdate" -Recurse -Force Remove-Item "$tasksPath\Microsoft\WindowsUpdate" -Recurse -Force & $Log "Scheduled task files deleted." # -- 5. Remove ISO support folder ----------------------------------------- if ($ISOContentsDir -and (Test-Path $ISOContentsDir)) { & $Log "Removing ISO support\ folder..." Remove-Item -Path (Join-Path $ISOContentsDir "support") -Recurse -Force & $Log "ISO support\ folder removed." } } function Invoke-WinUtilISORefreshUSBDrives { $combo = $sync["WPFWin11ISOUSBDriveComboBox"] $removable = @(Get-Disk | Where-Object { $_.BusType -eq "USB" } | Sort-Object Number) $combo.Items.Clear() if ($removable.Count -eq 0) { $combo.Items.Add("No USB drives detected.") $combo.SelectedIndex = 0 $sync["Win11ISOUSBDisks"] = @() Write-Win11ISOLog "No USB drives detected." return } foreach ($disk in $removable) { $sizeGB = [math]::Round($disk.Size / 1GB, 1) $combo.Items.Add("Disk $($disk.Number): $($disk.FriendlyName) [$sizeGB GB] - $($disk.PartitionStyle)") } $combo.SelectedIndex = 0 Write-Win11ISOLog "Found $($removable.Count) USB drive(s)." $sync["Win11ISOUSBDisks"] = $removable } function Invoke-WinUtilISOWriteUSB { $contentsDir = $sync["Win11ISOContentsDir"] $usbDisks = $sync["Win11ISOUSBDisks"] if (-not $contentsDir -or -not (Test-Path $contentsDir)) { [System.Windows.MessageBox]::Show("No modified ISO content found. Please complete Steps 1-3 first.", "Not Ready", "OK", "Warning") return } $combo = $sync["WPFWin11ISOUSBDriveComboBox"] $selectedIndex = $combo.SelectedIndex $selectedItemText = [string]$combo.SelectedItem $usbDisks = @($usbDisks) $targetDisk = $null if ($selectedIndex -ge 0 -and $selectedIndex -lt $usbDisks.Count) { $targetDisk = $usbDisks[$selectedIndex] } elseif ($selectedItemText -match 'Disk\s+(\d+):') { $selectedDiskNum = [int]$matches[1] $targetDisk = $usbDisks | Where-Object { $_.Number -eq $selectedDiskNum } | Select-Object -First 1 } if (-not $targetDisk) { [System.Windows.MessageBox]::Show("Please select a USB drive from the dropdown.", "No Drive Selected", "OK", "Warning") return } $diskNum = $targetDisk.Number $sizeGB = [math]::Round($targetDisk.Size / 1GB, 1) $confirm = [System.Windows.MessageBox]::Show( "ALL data on Disk $diskNum ($($targetDisk.FriendlyName), $sizeGB GB) will be PERMANENTLY ERASED.`n`nAre you sure you want to continue?", "Confirm USB Erase", "YesNo", "Warning") if ($confirm -ne "Yes") { Write-Win11ISOLog "USB write cancelled by user." return } $sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $false Write-Win11ISOLog "Starting USB write to Disk $diskNum..." $runspace = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace() $runspace.ApartmentState = "STA" $runspace.ThreadOptions = "ReuseThread" $runspace.Open() $runspace.SessionStateProxy.SetVariable("sync", $sync) $runspace.SessionStateProxy.SetVariable("diskNum", $diskNum) $runspace.SessionStateProxy.SetVariable("contentsDir", $contentsDir) $script = [Management.Automation.PowerShell]::Create() $script.Runspace = $runspace $script.AddScript({ function Log($msg) { $ts = (Get-Date).ToString("HH:mm:ss") $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync["WPFWin11ISOStatusLog"].Text += "`n[$ts] $msg" $sync["WPFWin11ISOStatusLog"].CaretIndex = $sync["WPFWin11ISOStatusLog"].Text.Length $sync["WPFWin11ISOStatusLog"].ScrollToEnd() }) } function SetProgress($label, $pct) { $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = $label $sync.progressBarTextBlock.ToolTip = $label $sync.ProgressBar.Value = [Math]::Max($pct, 5) }) } function Get-FreeDriveLetter { $used = (Get-PSDrive -PSProvider FileSystem).Name foreach ($c in [char[]](68..90)) { if ($used -notcontains [string]$c) { return $c } } return $null } try { SetProgress "Formatting USB drive..." 10 # Phase 1: Clean disk via diskpart (retry once if the drive is not yet ready) $dpFile1 = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt" "select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1 -Encoding ASCII Log "Running diskpart clean on Disk $diskNum..." $dpCleanOut = diskpart /s $dpFile1 $dpCleanOut | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" } Remove-Item $dpFile1 -Force if (($dpCleanOut -join ' ') -match 'device is not ready') { Log "Disk $diskNum was not ready; waiting 5 seconds and retrying clean..." Start-Sleep -Seconds 5 Update-Disk -Number $diskNum $dpFile1b = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt" "select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1b -Encoding ASCII diskpart /s $dpFile1b | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" } Remove-Item $dpFile1b -Force } # Phase 2: Initialize as GPT Start-Sleep -Seconds 2 Update-Disk -Number $diskNum $diskObj = Get-Disk -Number $diskNum if ($diskObj.PartitionStyle -eq 'RAW') { Initialize-Disk -Number $diskNum -PartitionStyle GPT Log "Disk $diskNum initialized as GPT." } else { Set-Disk -Number $diskNum -PartitionStyle GPT Log "Disk $diskNum converted to GPT (was $($diskObj.PartitionStyle))." } # Phase 3: Create FAT32 partition via diskpart, then format with Format-Volume # (diskpart's 'format' command can fail with "no volume selected" on fresh/never-formatted drives) $volLabel = "W11-" + (Get-Date).ToString('yyMMdd') $dpFile2 = Join-Path $env:TEMP "winutil_diskpart2_$(Get-Random).txt" $maxFat32PartitionMB = 32768 $diskSizeMB = [int][Math]::Floor((Get-Disk -Number $diskNum).Size / 1MB) $createPartitionCommand = "create partition primary" if ($diskSizeMB -gt $maxFat32PartitionMB) { $createPartitionCommand = "create partition primary size=$maxFat32PartitionMB" Log "Disk $diskNum is $diskSizeMB MB; creating FAT32 partition capped at $maxFat32PartitionMB MB (32 GB)." } @( "select disk $diskNum" $createPartitionCommand "exit" ) | Set-Content -Path $dpFile2 -Encoding ASCII Log "Creating partitions on Disk $diskNum..." diskpart /s $dpFile2 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" } Remove-Item $dpFile2 -Force SetProgress "Formatting USB partition..." 25 Start-Sleep -Seconds 3 Update-Disk -Number $diskNum $partitions = Get-Partition -DiskNumber $diskNum Log "Partitions on Disk $diskNum after creation: $($partitions.Count)" foreach ($p in $partitions) { Log " Partition $($p.PartitionNumber) Type=$($p.Type) Letter=$($p.DriveLetter) Size=$([math]::Round($p.Size/1MB))MB" } $winpePart = $partitions | Where-Object { $_.Type -eq "Basic" } | Select-Object -Last 1 if (-not $winpePart) { throw "Could not find the Basic partition on Disk $diskNum after creation." } # Format using Format-Volume (reliable on fresh drives; diskpart format fails # with 'no volume selected' when the partition has never been formatted before) Log "Formatting Partition $($winpePart.PartitionNumber) as FAT32 (label: $volLabel)..." Get-Partition -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber | Format-Volume -FileSystem FAT32 -NewFileSystemLabel $volLabel -Force -Confirm:$false Log "Partition $($winpePart.PartitionNumber) formatted as FAT32." SetProgress "Assigning drive letters..." 30 Start-Sleep -Seconds 2 Update-Disk -Number $diskNum try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" } catch { Log "Warning: could not remove existing partition access path: $_" } $usbLetter = Get-FreeDriveLetter if (-not $usbLetter) { throw "No free drive letters (D-Z) available to assign to the USB data partition." } Set-Partition -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -NewDriveLetter $usbLetter Log "Assigned drive letter $usbLetter to WINPE partition (Partition $($winpePart.PartitionNumber))." Start-Sleep -Seconds 2 $usbDrive = "${usbLetter}:" $retries = 0 while (-not (Test-Path $usbDrive) -and $retries -lt 6) { $retries++ Log "Waiting for $usbDrive to become accessible (attempt $retries/6)..." Start-Sleep -Seconds 2 } if (-not (Test-Path $usbDrive)) { throw "Drive $usbDrive is not accessible after letter assignment." } Log "USB data partition: $usbDrive" $contentSizeBytes = (Get-ChildItem -LiteralPath $contentsDir -File -Recurse -Force | Measure-Object -Property Length -Sum).Sum if (-not $contentSizeBytes) { $contentSizeBytes = 0 } $usbVolume = Get-Volume -DriveLetter $usbLetter $partitionCapacityBytes = [int64]$usbVolume.Size $partitionFreeBytes = [int64]$usbVolume.SizeRemaining $contentSizeGB = [math]::Round($contentSizeBytes / 1GB, 2) $partitionCapacityGB = [math]::Round($partitionCapacityBytes / 1GB, 2) $partitionFreeGB = [math]::Round($partitionFreeBytes / 1GB, 2) Log "Source content size: $contentSizeGB GB. USB partition capacity: $partitionCapacityGB GB, free: $partitionFreeGB GB." if ($contentSizeBytes -gt $partitionCapacityBytes) { throw "ISO content ($contentSizeGB GB) is larger than the USB partition capacity ($partitionCapacityGB GB). Use a larger USB drive or reduce image size." } if ($contentSizeBytes -gt $partitionFreeBytes) { throw "Insufficient free space on USB partition. Required: $contentSizeGB GB, available: $partitionFreeGB GB." } SetProgress "Copying Windows 11 files to USB..." 45 # Copy files; split install.wim if > 4 GB (FAT32 limit) $installWim = Join-Path $contentsDir "sources\install.wim" if (Test-Path $installWim) { $wimSizeMB = [math]::Round((Get-Item $installWim).Length / 1MB) if ($wimSizeMB -gt 3800) { Log "install.wim is $wimSizeMB MB - splitting for FAT32 compatibility... This will take several minutes." $splitDest = Join-Path $usbDrive "sources\install.swm" New-Item -ItemType Directory -Path (Split-Path $splitDest) -Force Split-WindowsImage -ImagePath $installWim -SplitImagePath $splitDest -FileSize 3800 -CheckIntegrity Log "install.wim split complete." Log "Copying remaining files to USB..." & robocopy $contentsDir $usbDrive /E /XF install.wim /NFL /NDL /NJH /NJS } else { & robocopy $contentsDir $usbDrive /E /NFL /NDL /NJH /NJS } } else { & robocopy $contentsDir $usbDrive /E /NFL /NDL /NJH /NJS } SetProgress "Finalising USB drive..." 90 Log "Files copied to USB." SetProgress "USB write complete" 100 Log "USB drive is ready for use." $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ [System.Windows.MessageBox]::Show( "USB drive created successfully!`n`nYou can now boot from this drive to install Windows 11.", "USB Ready", "OK", "Info") }) } catch { Log "ERROR during USB write: $_" $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ [System.Windows.MessageBox]::Show("USB write failed:`n`n$_", "USB Write Error", "OK", "Error") }) } finally { Start-Sleep -Milliseconds 800 $sync["WPFWin11ISOStatusLog"].Dispatcher.Invoke([action]{ $sync.progressBarTextBlock.Text = "" $sync.progressBarTextBlock.ToolTip = "" $sync.ProgressBar.Value = 0 $sync["WPFWin11ISOWriteUSBButton"].IsEnabled = $true }) } }) $script.BeginInvoke() } function Invoke-WinUtilScript { <# .SYNOPSIS Invokes the provided scriptblock. Intended for things that can't be handled with the other functions. .PARAMETER Name The name of the scriptblock being invoked .PARAMETER scriptblock The scriptblock to be invoked .EXAMPLE $Scriptblock = [scriptblock]::Create({"Write-output 'Hello World'"}) Invoke-WinUtilScript -ScriptBlock $scriptblock -Name "Hello World" #> param ( $Name, [scriptblock]$scriptblock ) try { Write-Host "Running Script for $Name" Write-WinUtilLog -Component "Script" -Message "Running script for $Name" Invoke-Command $scriptblock -ErrorAction Stop Write-WinUtilLog -Component "Script" -Message "Completed script for $Name" } catch [System.Management.Automation.CommandNotFoundException] { Write-Warning "The specified command was not found." Write-Warning $PSItem.Exception.message Write-WinUtilLog -Level "ERROR" -Component "Script" -Message "Command not found while running script for $Name`: $($PSItem.Exception.Message)" } catch [System.Management.Automation.RuntimeException] { Write-Warning "A runtime exception occurred." Write-Warning $PSItem.Exception.message Write-WinUtilLog -Level "ERROR" -Component "Script" -Message "Runtime exception while running script for $Name`: $($PSItem.Exception.Message)" } catch [System.Security.SecurityException] { Write-Warning "A security exception occurred." Write-Warning $PSItem.Exception.message Write-WinUtilLog -Level "ERROR" -Component "Script" -Message "Security exception while running script for $Name`: $($PSItem.Exception.Message)" } catch [System.UnauthorizedAccessException] { Write-Warning "Access denied. You do not have permission to perform this operation." Write-Warning $PSItem.Exception.message Write-WinUtilLog -Level "ERROR" -Component "Script" -Message "Access denied while running script for $Name`: $($PSItem.Exception.Message)" } catch { # Generic catch block to handle any other type of exception Write-Warning "Unable to run script for $Name due to unhandled exception." Write-Warning $psitem.Exception.StackTrace Write-WinUtilLog -Level "ERROR" -Component "Script" -Message "Unhandled exception while running script for $Name`: $($psitem.Exception.Message)" } } Function Invoke-WinUtilSponsors { $sponsors = ([regex]::Matches(([regex]::Match((Invoke-RestMethod https://github.com/sponsors/ChrisTitusTech),'(?s)(?<=Current sponsors).*?(?=Past sponsors)')).Value,'(?<=alt="@)[^"]+')).Value | Where-Object {$_ -ne "ChrisTitusTech"} return $sponsors } function Invoke-WinUtilSSHServer { <# .SYNOPSIS Enables OpenSSH server to remote into your windows device #> # Install the OpenSSH Server feature if not already installed if ((Get-WindowsCapability -Name OpenSSH.Server -Online).State -ne "Installed") { Write-Host "Enabling OpenSSH Server... This will take a long time." Add-WindowsCapability -Name OpenSSH.Server -Online } Write-Host "Starting the services" Set-Service -Name sshd -StartupType Automatic Start-Service -Name sshd Set-Service -Name ssh-agent -StartupType Automatic Start-Service -Name ssh-agent #Adding Firewall rule for port 22 Write-Host "Setting up firewall rules" if (-not ((Get-NetFirewallRule -Name 'sshd').Enabled)) { 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 = "$Home\.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." } Write-Host "Configuring sshd_config for standard authorized_keys behavior..." $sshdConfigPath = "C:\ProgramData\ssh\sshd_config" $configContent = Get-Content -Path $sshdConfigPath -Raw $updatedContent = $configContent -replace '(?m)^(Match Group administrators)$', '# $1' $updatedContent = $updatedContent -replace '(?m)^(\s+AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys)$', '# $1' if ($updatedContent -ne $configContent) { Set-Content -Path $sshdConfigPath -Value $updatedContent -Force Write-Host "Commented out administrator-specific SSH key configuration in sshd_config" Restart-Service -Name sshd -Force } 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" } 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. .EXAMPLE Invoke-WinutilThemeChange # Toggles the theme between 'Light' and 'Dark'. #> param ( [string]$theme = "Auto" ) 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 ($themeProperty in $themeProperties) { # Apply properties that deal with colors if ($themeProperty.Name -like "*color*") { Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "ColorBrush" # For certain color properties, also set complementary values (e.g., BorderColor -> CBorderColor) This is required because e.g DropShadowEffect requires a and not a object if ($themeProperty.Name -in @("BorderColor", "ButtonBackgroundMouseoverColor")) { Set-ThemeResourceProperty -Name "C$($themeProperty.Name)" -Value $themeProperty.Value -Type "Color" } } # Apply corner radius properties elseif ($themeProperty.Name -like "*Radius*") { Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "CornerRadius" } # Apply row height properties elseif ($themeProperty.Name -like "*RowHeight*") { Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "GridLength" } # Apply thickness or margin properties elseif (($themeProperty.Name -like "*Thickness*") -or ($themeProperty.Name -like "*margin")) { Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "Thickness" } # Apply font family properties elseif ($themeProperty.Name -like "*FontFamily*") { Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "FontFamily" } # Apply any other properties as doubles (numerical values) else { Set-ThemeResourceProperty -Name $themeProperty.Name -Value $themeProperty.Value -Type "Double" } } } $sync.preferences.theme = $theme Set-WinutilTheme -currentTheme "shared" switch ($sync.preferences.theme) { "Auto" { $systemUsesDarkMode = Get-WinUtilToggleStatus WPFToggleDarkMode if ($systemUsesDarkMode) { $theme = "Dark" } else{ $theme = "Light" } Set-WinutilTheme -currentTheme $theme $themeButtonIcon = [char]0xF08C } "Dark" { Set-WinutilTheme -currentTheme $sync.preferences.theme $themeButtonIcon = [char]0xE708 } "Light" { Set-WinutilTheme -currentTheme $sync.preferences.theme $themeButtonIcon = [char]0xE706 } } # Reapply font scaling if it was previously set (theme change resets shared resources) if ($sync.ContainsKey("FontScaleFactor") -and $sync.FontScaleFactor -ne 1.0) { Invoke-WinUtilFontScaling -ScaleFactor $sync.FontScaleFactor } # Update the theme selector button with the appropriate icon $ThemeButton = $sync.Form.FindName("ThemeButton") $ThemeButton.Content = [string]$themeButtonIcon } function Invoke-WinUtilTweaks { <# .SYNOPSIS Invokes the function associated with each provided checkbox .PARAMETER CheckBox The checkbox to invoke .PARAMETER undo Indicates whether to undo the operation contained in the checkbox .PARAMETER KeepServiceStartup Indicates whether to override the startup of a service with the one given from WinUtil, or to keep the startup of said service, if it was changed by the user, or another program, from its default value. #> param( $CheckBox, $undo = $false, $KeepServiceStartup = $true ) $action = if ($undo) { "Undo" } else { "Apply" } Write-WinUtilLog -Component "Tweaks" -Message "$action tweak: $CheckBox" if ($undo) { $Values = @{ Registry = "OriginalValue" Service = "OriginalType" ScriptType = "UndoScript" } } else { $Values = @{ Registry = "Value" Service = "StartupType" OriginalService = "OriginalType" ScriptType = "InvokeScript" } } if ($sync.configs.tweaks.$CheckBox.service) { $sync.configs.tweaks.$CheckBox.service | ForEach-Object { $changeservice = $true # The check for !($undo) is required, without it the script will throw an error for accessing unavailable member, which's the 'OriginalService' Property if ($KeepServiceStartup -AND !($undo)) { try { # Check if the service exists $service = Get-Service -Name $psitem.Name -ErrorAction Stop if(!($service.StartType.ToString() -eq $psitem.$($values.OriginalService))) { $changeservice = $false } } catch [System.ServiceProcess.ServiceNotFoundException] { Write-Warning "Service $($psitem.Name) was not found." } } if ($changeservice) { Set-WinUtilService -Name $psitem.Name -StartupType $psitem.$($values.Service) } } } if ($sync.configs.tweaks.$CheckBox.registry) { $sync.configs.tweaks.$CheckBox.registry | ForEach-Object { Set-WinUtilRegistry -Name $psitem.Name -Path $psitem.Path -Type $psitem.Type -Value $psitem.$($values.registry) } } if ($sync.configs.tweaks.$CheckBox.$($values.ScriptType)) { $sync.configs.tweaks.$CheckBox.$($values.ScriptType) | ForEach-Object { $Scriptblock = [scriptblock]::Create($psitem) Invoke-WinUtilScript -ScriptBlock $scriptblock -Name $CheckBox } } if (!$undo) { if($sync.configs.tweaks.$CheckBox.appx) { $sync.configs.tweaks.$CheckBox.appx | ForEach-Object { Remove-WinUtilAPPX -Name $psitem } } } Write-WinUtilLog -Component "Tweaks" -Message "$action tweak completed: $CheckBox" } function Invoke-WinUtilUninstallPSProfile { if (Test-Path ($Profile + ".bak")) { Move-Item -Path ($Profile + ".bak") -Destination $Profile } else { Remove-Item -Path $Profile } Write-Host "Successfully uninstalled CTT PowerShell Profile." -ForegroundColor Green } function Remove-WinUtilAPPX { <# .SYNOPSIS Removes all APPX packages that match the given name .PARAMETER Name The name of the APPX package to remove .EXAMPLE Remove-WinUtilAPPX -Name "Microsoft.Microsoft3DViewer" #> param ( $Name ) Write-Host "Removing $Name" Write-WinUtilLog -Component "AppX" -Message "Removing AppX package pattern: $Name" Get-AppxPackage $Name -AllUsers | Remove-AppxPackage -AllUsers Get-AppxProvisionedPackage -Online | Where-Object DisplayName -like $Name | Remove-AppxProvisionedPackage -Online Write-WinUtilLog -Component "AppX" -Message "AppX removal completed for package pattern: $Name" } function Reset-WPFCheckBoxes { <# .SYNOPSIS Set winutil checkboxs to match $sync.selected values. Should only need to be run if $sync.selected updated outside of UI (i.e. presets or import) .PARAMETER doToggles Whether or not to set UI toggles. WARNING: they will trigger if altered .PARAMETER checkboxfilterpattern The Pattern to use when filtering through CheckBoxes, defaults to "**" Used to make reset blazingly fast. #> param ( [Parameter(position=0)] [bool]$doToggles = $false, [Parameter(position=1)] [string]$checkboxfilterpattern = "**" ) $CheckBoxesToCheck = $sync.selectedApps + $sync.selectedTweaks + $sync.selectedFeatures + $sync.selectedAppx $CheckBoxes = foreach ($syncEntry in $sync.GetEnumerator()) { if ($syncEntry.Value -is [System.Windows.Controls.CheckBox] -and $syncEntry.Name -notlike "WPFToggle*" -and $syncEntry.Name -like $checkboxfilterpattern) { $syncEntry } } foreach ($CheckBox in $CheckBoxes) { $checkboxName = $CheckBox.Key if (-not $CheckBoxesToCheck) { $sync.$checkBoxName.IsChecked = $false continue } # Check if the checkbox name exists in the flattened JSON hashtable if ($CheckBoxesToCheck -contains $checkboxName) { # If it exists, set IsChecked to true $sync.$checkboxName.IsChecked = $true } else { # If it doesn't exist, set IsChecked to false $sync.$checkboxName.IsChecked = $false } } # Update Installs tab UI values $count = $sync.SelectedApps.Count $sync.WPFselectedAppsButton.Content = "Selected Apps: $count" # On every change, remove all entries inside the Popup Menu. This is done, so we can keep the alphabetical order even if elements are selected in a random way $sync.selectedAppsstackPanel.Children.Clear() $sync.selectedApps | Foreach-Object { Add-SelectedAppsMenuItem -name $($sync.configs.applicationsHashtable.$_.Content) -key $_ } if($doToggles) { # Restore toggle switch states from imported config. # Only act on toggles that are explicitly listed in the import - toggles absent # from the export file were not part of the saved config and should keep whatever # state the live system already has (set during UI initialisation via Get-WinUtilToggleStatus). $importedToggles = $sync.selectedToggles $allToggles = $sync.GetEnumerator() | Where-Object { $_.Key -like "WPFToggle*" -and $_.Value -is [System.Windows.Controls.CheckBox] } foreach ($toggle in $allToggles) { if ($importedToggles -contains $toggle.Key) { $sync[$toggle.Key].IsChecked = $true } # Toggles not present in the import are intentionally left untouched; # their current UI state already reflects the real system state. } } } function Set-WinUtilDNS { <# .SYNOPSIS Sets the DNS of all interfaces that are in the "Up" state. It will lookup the values from the DNS.Json file .PARAMETER DNSProvider The DNS provider to set the DNS server to .EXAMPLE Set-WinUtilDNS -DNSProvider "google" #> param($DNSProvider) if($DNSProvider -eq "Default") { Write-WinUtilLog -Component "DNS" -Message "DNS provider is Default; no DNS changes applied." return } try { $Adapters = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} Write-Host "Ensuring DNS is set to $DNSProvider on the following interfaces:" Write-Host $($Adapters | Out-String) Write-WinUtilLog -Component "DNS" -Message "Setting DNS provider to $DNSProvider for $(@($Adapters).Count) active adapter(s)." if($DNSProvider -ne "DHCP") { $dns = $sync.configs.dns.$DNSProvider if($null -eq $dns) { Write-Warning "DNS provider $DNSProvider was not found in configuration." Write-WinUtilLog -Level "ERROR" -Component "DNS" -Message "DNS provider $DNSProvider was not found in configuration." return } } Foreach ($Adapter in $Adapters) { if($DNSProvider -eq "DHCP") { Write-WinUtilLog -Component "DNS" -Message "Resetting DNS to DHCP on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex))." Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ResetServerAddresses netsh interface ip set dnsservers name="$($Adapter.Name)" source=dhcp netsh interface ipv6 set dnsservers name="$($Adapter.Name)" source=dhcp } else { Write-WinUtilLog -Component "DNS" -Message "Setting IPv4 DNS on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex)) to $($dns.Primary), $($dns.Secondary)." Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ($dns.Primary, $dns.Secondary) Write-WinUtilLog -Component "DNS" -Message "Setting IPv6 DNS on adapter $($Adapter.Name) (ifIndex: $($Adapter.ifIndex)) to $($dns.Primary6), $($dns.Secondary6)." Set-DnsClientServerAddress -InterfaceIndex $Adapter.ifIndex -ServerAddresses ($dns.Primary6, $dns.Secondary6) } } Write-WinUtilLog -Component "DNS" -Message "DNS provider change completed: $DNSProvider" } catch { Write-Warning "Unable to set DNS Provider due to an unhandled exception." Write-Warning $psitem.Exception.StackTrace Write-WinUtilLog -Level "ERROR" -Component "DNS" -Message "Unable to set DNS provider $DNSProvider`: $($psitem.Exception.Message)" } } 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 overlaid onto the Progress Bar .PARAMETER PERCENT The percentage of the Progress Bar that should be filled (0-100) #> param( [string]$Label, [ValidateRange(0,100)] [int]$Percent ) $progressLabel = $Label Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.Text = $progressLabel} Invoke-WPFUIThread -ScriptBlock {$sync.progressBarTextBlock.ToolTip = $progressLabel} if ($Percent -lt 5 ) { $Percent = 5 # Ensure the progress bar is not empty, as it looks weird } Invoke-WPFUIThread -ScriptBlock { $sync.ProgressBar.Value = $Percent} } function Set-WinUtilRegistry { <# .SYNOPSIS Modifies the registry based on the given inputs .PARAMETER Name The name of the key to modify .PARAMETER Path The path to the key .PARAMETER Type The type of value to set the key to .PARAMETER Value The value to set the key to .EXAMPLE Set-WinUtilRegistry -Name "PublishUserActivities" -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\System" -Type "DWord" -Value "0" #> param ( $Name, $Path, $Type, $Value ) try { if(!(Test-Path 'HKU:\')) {New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS} If (!(Test-Path $Path)) { Write-Host "$Path was not found. Creating..." Write-WinUtilLog -Component "Registry" -Message "Creating registry path: $Path" New-Item -Path $Path -Force -ErrorAction Stop | Out-Null } if ($Value -ne "") { Write-Host "Set $Path\$Name to $Value" Write-WinUtilLog -Component "Registry" -Message "Setting $Path\$Name ($Type) to $Value" Set-ItemProperty -Path $Path -Name $Name -Type $Type -Value $Value -Force -ErrorAction Stop | Out-Null } else{ Write-Host "Remove $Path\$Name" Write-WinUtilLog -Component "Registry" -Message "Removing $Path\$Name" Remove-ItemProperty -Path $Path -Name $Name -Force -ErrorAction Stop | Out-Null } } catch [System.Security.SecurityException] { Write-Warning "Unable to set $Path\$Name to $Value due to a Security Exception." Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Security exception while changing $Path\$Name to $Value`: $($psitem.Exception.Message)" } catch [System.Management.Automation.ItemNotFoundException] { Write-Warning $psitem.Exception.ErrorRecord Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Registry item not found while changing $Path\$Name`: $($psitem.Exception.Message)" } catch [System.UnauthorizedAccessException] { Write-Warning $psitem.Exception.Message Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Unauthorized while changing $Path\$Name`: $($psitem.Exception.Message)" } catch { Write-Warning "Unable to set $Name due to unhandled exception." Write-Warning $psitem.Exception.StackTrace Write-WinUtilLog -Level "ERROR" -Component "Registry" -Message "Unhandled exception while changing $Path\$Name`: $($psitem.Exception.Message)" } } Function Set-WinUtilService { <# .SYNOPSIS Changes the startup type of the given service .PARAMETER Name The name of the service to modify .PARAMETER StartupType The startup type to set the service to .EXAMPLE Set-WinUtilService -Name "HomeGroupListener" -StartupType "Manual" #> param ( $Name, $StartupType ) try { Write-Host "Setting Service $Name to $StartupType" Write-WinUtilLog -Component "Service" -Message "Setting service $Name startup type to $StartupType" # Check if the service exists $service = Get-Service -Name $Name -ErrorAction Stop if (($service.PSObject.Properties.Name -contains "StartType") -and ([string]$service.StartType -eq [string]$StartupType) ) { Write-Host "Service $Name is already set to $StartupType" Write-WinUtilLog -Component "Service" -Message "Service $Name startup type is already $StartupType; no change needed." return } # Service exists, proceed with changing properties -- while handling auto delayed start for PWSH 5 if (($PSVersionTable.PSVersion.Major -lt 7) -and ($StartupType -eq "AutomaticDelayedStart")) { sc.exe config $Name start=delayed-auto } else { $service | Set-Service -StartupType $StartupType -ErrorAction Stop } Write-WinUtilLog -Component "Service" -Message "Service $Name startup type set to $StartupType" } catch { if ($_.FullyQualifiedErrorId -like "NoServiceFoundForGivenName,*") { Write-Warning "Service $Name was not found." Write-WinUtilLog -Level "WARN" -Component "Service" -Message "Service $Name was not found." } else { Write-Warning "Unable to set $Name due to unhandled exception." Write-Warning $_.Exception.Message Write-WinUtilLog -Level "ERROR" -Component "Service" -Message "Unable to set service $Name to $StartupType`: $($_.Exception.Message)" } } } function Set-WinUtilTaskbaritem { <# .SYNOPSIS Modifies the Taskbaritem of the WPF Form .PARAMETER value Value can be between 0 and 1, 0 being no progress done yet and 1 being fully completed Value does not affect item without setting the state to 'Normal', 'Error' or 'Paused' Set-WinUtilTaskbaritem -value 0.5 .PARAMETER state State can be 'None' > No progress, 'Indeterminate' > inf. loading gray, 'Normal' > Gray, 'Error' > Red, 'Paused' > Yellow no value needed: - Set-WinUtilTaskbaritem -state "None" - Set-WinUtilTaskbaritem -state "Indeterminate" value needed: - Set-WinUtilTaskbaritem -state "Error" - Set-WinUtilTaskbaritem -state "Normal" - Set-WinUtilTaskbaritem -state "Paused" .PARAMETER overlay Overlay icon to display on the taskbar item, there are the presets 'None', 'logo' and 'checkmark' or you can specify a path/link to an image file. CTT logo preset: - Set-WinUtilTaskbaritem -overlay "logo" Checkmark preset: - Set-WinUtilTaskbaritem -overlay "checkmark" Warning preset: - Set-WinUtilTaskbaritem -overlay "warning" No overlay: - Set-WinUtilTaskbaritem -overlay "None" Custom icon (needs to be supported by WPF): - Set-WinUtilTaskbaritem -overlay "C:\path\to\icon.png" .PARAMETER description Description to display on the taskbar item preview Set-WinUtilTaskbaritem -description "This is a description" #> param ( [string]$state, [double]$value, [string]$overlay, [string]$description ) if ($value) { $sync["Form"].taskbarItemInfo.ProgressValue = $value } if ($state) { switch ($state) { 'None' { $sync["Form"].taskbarItemInfo.ProgressState = "None" } 'Indeterminate' { $sync["Form"].taskbarItemInfo.ProgressState = "Indeterminate" } 'Normal' { $sync["Form"].taskbarItemInfo.ProgressState = "Normal" } 'Error' { $sync["Form"].taskbarItemInfo.ProgressState = "Error" } 'Paused' { $sync["Form"].taskbarItemInfo.ProgressState = "Paused" } default { throw "[Set-WinUtilTaskbarItem] Invalid state" } } } if ($overlay) { switch ($overlay) { 'logo' { if (-not $sync["logorender"]) { Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo $true -IncludeStatusAssets $false } $sync["Form"].taskbarItemInfo.Overlay = $sync["logorender"] } 'checkmark' { if (-not $sync["checkmarkrender"]) { Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo $false -IncludeStatusAssets $true } $sync["Form"].taskbarItemInfo.Overlay = $sync["checkmarkrender"] } 'warning' { if (-not $sync["warningrender"]) { Initialize-WinUtilTaskbarOverlayAssets -IncludeLogo $false -IncludeStatusAssets $true } $sync["Form"].taskbarItemInfo.Overlay = $sync["warningrender"] } 'None' { $sync["Form"].taskbarItemInfo.Overlay = $null } default { if (Test-Path $overlay) { $sync["Form"].taskbarItemInfo.Overlay = $overlay } } } } if ($description) { $sync["Form"].taskbarItemInfo.Description = $description } } function Show-CustomDialog { <# .SYNOPSIS Displays a custom dialog box with an image, heading, message, and an OK button. .DESCRIPTION This function creates a custom dialog box with the specified message and additional elements such as an image, heading, and an OK button. The dialog box is designed with a green border, rounded corners, and a black background. .PARAMETER Title The Title to use for the dialog window's Title Bar, this will not be visible by the user, as window styling is set to None. .PARAMETER Message The message to be displayed in the dialog box. .PARAMETER Width The width of the custom dialog window. .PARAMETER Height The height of the custom dialog window. .PARAMETER FontSize The Font Size of message shown inside custom dialog window. .PARAMETER HeaderFontSize The Font Size for the Header of custom dialog window. .PARAMETER LogoSize The Size of the Logo used inside the custom dialog window. .PARAMETER ForegroundColor The Foreground Color of dialog window title & message. .PARAMETER BackgroundColor The Background Color of dialog window. .PARAMETER BorderColor The Color for dialog window border. .PARAMETER ButtonBackgroundColor The Background Color for Buttons in dialog window. .PARAMETER ButtonForegroundColor The Foreground Color for Buttons in dialog window. .PARAMETER ShadowColor The Color used when creating the Drop-down Shadow effect for dialog window. .PARAMETER LogoColor The Color of WinUtil Text found next to WinUtil's Logo inside dialog window. .PARAMETER LinkForegroundColor The Foreground Color for Links inside dialog window. .PARAMETER LinkHoverForegroundColor The Foreground Color for Links when the mouse pointer hovers over them inside dialog window. .PARAMETER EnableScroll A flag indicating whether to enable scrolling if the content exceeds the window size. .EXAMPLE Show-CustomDialog -Title "My Custom Dialog" -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200 Makes a new Custom Dialog with the title 'My Custom Dialog' and a message 'This is a custom dialog with a message and an image above.', with dimensions of 300 by 200 pixels. Other styling options are grabbed from '$sync.Form.Resources' global variable. .EXAMPLE $foregroundColor = New-Object System.Windows.Media.SolidColorBrush("#0088e5") $backgroundColor = New-Object System.Windows.Media.SolidColorBrush("#1e1e1e") $linkForegroundColor = New-Object System.Windows.Media.SolidColorBrush("#0088e5") $linkHoverForegroundColor = New-Object System.Windows.Media.SolidColorBrush("#005289") Show-CustomDialog -Title "My Custom Dialog" -Message "This is a custom dialog with a message and an image above." -Width 300 -Height 200 -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor -LinkForegroundColor $linkForegroundColor -LinkHoverForegroundColor $linkHoverForegroundColor Makes a new Custom Dialog with the title 'My Custom Dialog' and a message 'This is a custom dialog with a message and an image above.', with dimensions of 300 by 200 pixels, with a link foreground (and general foreground) colors of '#0088e5', background color of '#1e1e1e', and Link Color on Hover of '005289', all of which are in Hexadecimal (the '#' Symbol is required by SolidColorBrush Constructor). Other styling options are grabbed from '$sync.Form.Resources' global variable. #> param( [string]$Title, [string]$Message, [int]$Width = $sync.Form.Resources.CustomDialogWidth, [int]$Height = $sync.Form.Resources.CustomDialogHeight, [System.Windows.Media.FontFamily]$FontFamily = $sync.Form.Resources.FontFamily, [int]$FontSize = $sync.Form.Resources.CustomDialogFontSize, [int]$HeaderFontSize = $sync.Form.Resources.CustomDialogFontSizeHeader, [int]$LogoSize = $sync.Form.Resources.CustomDialogLogoSize, [System.Windows.Media.Color]$ShadowColor = "#AAAAAAAA", [System.Windows.Media.SolidColorBrush]$LogoColor = $sync.Form.Resources.LabelboxForegroundColor, [System.Windows.Media.SolidColorBrush]$BorderColor = $sync.Form.Resources.BorderColor, [System.Windows.Media.SolidColorBrush]$ForegroundColor = $sync.Form.Resources.MainForegroundColor, [System.Windows.Media.SolidColorBrush]$BackgroundColor = $sync.Form.Resources.MainBackgroundColor, [System.Windows.Media.SolidColorBrush]$ButtonForegroundColor = $sync.Form.Resources.ButtonInstallForegroundColor, [System.Windows.Media.SolidColorBrush]$ButtonBackgroundColor = $sync.Form.Resources.ButtonInstallBackgroundColor, [System.Windows.Media.SolidColorBrush]$LinkForegroundColor = $sync.Form.Resources.LinkForegroundColor, [System.Windows.Media.SolidColorBrush]$LinkHoverForegroundColor = $sync.Form.Resources.LinkHoverForegroundColor, [bool]$EnableScroll = $false ) # Create a custom dialog window $dialog = New-Object Windows.Window $dialog.Title = $Title $dialog.Height = $Height $dialog.Width = $Width $dialog.Margin = New-Object Windows.Thickness(10) # Add margin to the entire dialog box $dialog.WindowStyle = [Windows.WindowStyle]::None # Remove title bar and window controls $dialog.ResizeMode = [Windows.ResizeMode]::NoResize # Disable resizing $dialog.WindowStartupLocation = [Windows.WindowStartupLocation]::CenterScreen # Center the window $dialog.Foreground = $ForegroundColor $dialog.Background = $BackgroundColor $dialog.FontFamily = $FontFamily $dialog.FontSize = $FontSize # Create a Border for the green edge with rounded corners $border = New-Object Windows.Controls.Border $border.BorderBrush = $BorderColor $border.BorderThickness = New-Object Windows.Thickness(1) # Adjust border thickness as needed $border.CornerRadius = New-Object Windows.CornerRadius(10) # Adjust the radius for rounded corners # Create a drop shadow effect $dropShadow = New-Object Windows.Media.Effects.DropShadowEffect $dropShadow.Color = $shadowColor $dropShadow.Direction = 270 $dropShadow.ShadowDepth = 5 $dropShadow.BlurRadius = 10 # Apply drop shadow effect to the border $dialog.Effect = $dropShadow $dialog.Content = $border # Create a grid for layout inside the Border $grid = New-Object Windows.Controls.Grid $border.Child = $grid # Uncomment the following line to show gridlines #$grid.ShowGridLines = $true # Add the following line to set the background color of the grid $grid.Background = [Windows.Media.Brushes]::Transparent # Add the following line to make the Grid stretch $grid.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch $grid.VerticalAlignment = [Windows.VerticalAlignment]::Stretch # Add the following line to make the Border stretch $border.HorizontalAlignment = [Windows.HorizontalAlignment]::Stretch $border.VerticalAlignment = [Windows.VerticalAlignment]::Stretch # Set up Row Definitions $row0 = New-Object Windows.Controls.RowDefinition $row0.Height = [Windows.GridLength]::Auto $row1 = New-Object Windows.Controls.RowDefinition $row1.Height = [Windows.GridLength]::new(1, [Windows.GridUnitType]::Star) $row2 = New-Object Windows.Controls.RowDefinition $row2.Height = [Windows.GridLength]::Auto # Add Row Definitions to Grid $grid.RowDefinitions.Add($row0) $grid.RowDefinitions.Add($row1) $grid.RowDefinitions.Add($row2) # Add StackPanel for horizontal layout with margins $stackPanel = New-Object Windows.Controls.StackPanel $stackPanel.Margin = New-Object Windows.Thickness(10) # Add margins around the stack panel $stackPanel.Orientation = [Windows.Controls.Orientation]::Horizontal $stackPanel.HorizontalAlignment = [Windows.HorizontalAlignment]::Left # Align to the left $stackPanel.VerticalAlignment = [Windows.VerticalAlignment]::Top # Align to the top $grid.Children.Add($stackPanel) [Windows.Controls.Grid]::SetRow($stackPanel, 0) # Set the row to the second row (0-based index) # Add SVG path to the stack panel $stackPanel.Children.Add((Invoke-WinUtilAssets -Type "logo" -Size $LogoSize)) # Add "Winutil" text $winutilTextBlock = New-Object Windows.Controls.TextBlock $winutilTextBlock.Text = "WinUtil" $winutilTextBlock.FontSize = $HeaderFontSize $winutilTextBlock.Foreground = $LogoColor $winutilTextBlock.Margin = New-Object Windows.Thickness(10, 10, 10, 5) # Add margins around the text block $stackPanel.Children.Add($winutilTextBlock) # Add TextBlock for information with text wrapping and margins $messageTextBlock = New-Object Windows.Controls.TextBlock $messageTextBlock.FontSize = $FontSize $messageTextBlock.TextWrapping = [Windows.TextWrapping]::Wrap # Enable text wrapping $messageTextBlock.HorizontalAlignment = [Windows.HorizontalAlignment]::Left $messageTextBlock.VerticalAlignment = [Windows.VerticalAlignment]::Top $messageTextBlock.Margin = New-Object Windows.Thickness(10) # Add margins around the text block # Define the Regex to find hyperlinks formatted as HTML tags $regex = [regex]::new('([^<]+)') $lastPos = 0 $linkHoverBrush = $LinkHoverForegroundColor # Iterate through each match and add regular text and hyperlinks foreach ($match in $regex.Matches($Message)) { # Add the text before the hyperlink, if any $textBefore = $Message.Substring($lastPos, $match.Index - $lastPos) if ($textBefore.Length -gt 0) { $messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($textBefore))) } # Create and add the hyperlink $hyperlink = New-Object Windows.Documents.Hyperlink $hyperlink.NavigateUri = New-Object System.Uri($match.Groups[1].Value) $hyperlink.Inlines.Add($match.Groups[2].Value) $hyperlink.TextDecorations = [Windows.TextDecorations]::None # Remove underline $hyperlink.Foreground = $LinkForegroundColor $hyperlink.Add_Click({ param($eventSender, $routedEvent) $null = $routedEvent Start-Process $eventSender.NavigateUri.AbsoluteUri }) $hyperlink.Add_MouseEnter({ param($eventSender, $routedEvent) $null = $routedEvent $eventSender.Foreground = $linkHoverBrush $eventSender.FontSize = ($FontSize + ($FontSize / 4)) $eventSender.FontWeight = "SemiBold" }) $hyperlink.Add_MouseLeave({ param($eventSender, $routedEvent) $null = $routedEvent $eventSender.Foreground = $LinkForegroundColor $eventSender.FontSize = $FontSize $eventSender.FontWeight = "Normal" }) $messageTextBlock.Inlines.Add($hyperlink) # Update the last position $lastPos = $match.Index + $match.Length } # Add any remaining text after the last hyperlink if ($lastPos -lt $Message.Length) { $textAfter = $Message.Substring($lastPos) $messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($textAfter))) } # If no matches, add the entire message as a run if ($regex.Matches($Message).Count -eq 0) { $messageTextBlock.Inlines.Add((New-Object Windows.Documents.Run($Message))) } # Create a ScrollViewer if EnableScroll is true if ($EnableScroll) { $scrollViewer = New-Object System.Windows.Controls.ScrollViewer $scrollViewer.VerticalScrollBarVisibility = 'Auto' $scrollViewer.HorizontalScrollBarVisibility = 'Disabled' $scrollViewer.Content = $messageTextBlock $grid.Children.Add($scrollViewer) [Windows.Controls.Grid]::SetRow($scrollViewer, 1) # Set the row to the second row (0-based index) } else { $grid.Children.Add($messageTextBlock) [Windows.Controls.Grid]::SetRow($messageTextBlock, 1) # Set the row to the second row (0-based index) } # Add OK button $okButton = New-Object Windows.Controls.Button $okButton.Content = "OK" $okButton.FontSize = $FontSize $okButton.Width = 80 $okButton.Height = 30 $okButton.HorizontalAlignment = [Windows.HorizontalAlignment]::Center $okButton.VerticalAlignment = [Windows.VerticalAlignment]::Bottom $okButton.Margin = New-Object Windows.Thickness(0, 0, 0, 10) $okButton.Background = $buttonBackgroundColor $okButton.Foreground = $buttonForegroundColor $okButton.BorderBrush = $BorderColor $okButton.Add_Click({ $dialog.Close() }) $grid.Children.Add($okButton) [Windows.Controls.Grid]::SetRow($okButton, 2) # Set the row to the third row (0-based index) # Handle Escape key press to close the dialog $dialog.Add_KeyDown({ if ($_.Key -eq 'Escape') { $dialog.Close() } }) # Set the OK button as the default button (activated on Enter) $okButton.IsDefault = $true # Show the custom dialog $dialog.ShowDialog() } function Show-WinUtilMessage { <# .SYNOPSIS Shows a WinUtil message box and returns the selected result. #> param ( [string]$Message, [string]$Title = "Winutil", $Button = "OK", $Icon = "Information" ) [System.Windows.MessageBox]::Show($Message, $Title, $Button, $Icon) } function Show-WPFInstallAppBusy { <# .SYNOPSIS Displays a busy overlay in the install app area of the WPF form. This is used to indicate that an install or uninstall is in progress. Dynamically updates the size of the overlay based on the app area on each invocation. .PARAMETER text The text to display in the busy overlay. Defaults to "Installing apps...". #> param ( $text = "Installing apps..." ) $overlayText = $text Invoke-WPFUIThread -ScriptBlock { $sync.InstallAppAreaOverlay.Visibility = [Windows.Visibility]::Visible $sync.InstallAppAreaOverlay.Width = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4) $sync.InstallAppAreaOverlay.Height = $($sync.InstallAppAreaScrollViewer.ActualWidth * 0.4) $sync.InstallAppAreaOverlayText.Text = $overlayText $sync.InstallAppAreaBorder.IsEnabled = $false $sync.InstallAppAreaScrollViewer.Effect.Radius = 5 } } function Invoke-WinUtilInstallAppRenderBatch { param( [Parameter(Mandatory = $true)] $CategoryBatch ) foreach ($appKey in $CategoryBatch.AppKeys) { $sync.$appKey = Initialize-InstallAppEntry -TargetElement $CategoryBatch.TargetElement -AppKey $appKey } if ($sync.currentTab -eq "Install" -and $sync.SearchBar -and -not [string]::IsNullOrWhiteSpace($sync.SearchBar.Text)) { Find-AppsByNameOrDescription -SearchString $sync.SearchBar.Text } } function Complete-WinUtilInstallAppRendering { $sync.InstallAppEntriesRendered = $true } function Invoke-WinUtilInstallAppRenderNextBatch { if ($sync.InstallAppRenderQueue.Count -gt 0) { $categoryBatch = $sync.InstallAppRenderQueue.Dequeue() Invoke-WinUtilInstallAppRenderBatch -CategoryBatch $categoryBatch } if ($sync.InstallAppRenderQueue.Count -gt 0) { $sync.Form.Dispatcher.BeginInvoke( [System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilInstallAppRenderNextBatch } ) | Out-Null return } Complete-WinUtilInstallAppRendering } function Start-WinUtilInstallAppRendering { if ($null -eq $sync.InstallAppRenderQueue) { return } $sync.InstallAppEntriesRendered = $false if ($sync.Form -and $sync.Form.Dispatcher) { $sync.Form.Dispatcher.BeginInvoke( [System.Windows.Threading.DispatcherPriority]::Background, [action]{ Invoke-WinUtilInstallAppRenderNextBatch } ) | Out-Null return } while ($sync.InstallAppRenderQueue.Count -gt 0) { $categoryBatch = $sync.InstallAppRenderQueue.Dequeue() Invoke-WinUtilInstallAppRenderBatch -CategoryBatch $categoryBatch } Complete-WinUtilInstallAppRendering } function Test-WinUtilPackageManager { <# .SYNOPSIS Checks if WinGet and/or Choco are installed .PARAMETER winget Check if WinGet is installed .PARAMETER choco Check if Chocolatey is installed #> Param( [System.Management.Automation.SwitchParameter]$winget, [System.Management.Automation.SwitchParameter]$choco ) if ($winget) { if (Get-Command winget -ErrorAction SilentlyContinue) { Write-Host "===========================================" -ForegroundColor Green Write-Host "--- WinGet is installed ---" -ForegroundColor Green Write-Host "===========================================" -ForegroundColor Green $status = "installed" } else { Write-Host "===========================================" -ForegroundColor Red Write-Host "--- WinGet is not installed ---" -ForegroundColor Red Write-Host "===========================================" -ForegroundColor Red $status = "not-installed" } } if ($choco) { if (Get-Command choco -ErrorAction SilentlyContinue) { Write-Host "===========================================" -ForegroundColor Green Write-Host "--- Chocolatey is installed ---" -ForegroundColor Green Write-Host "===========================================" -ForegroundColor Green $status = "installed" } else { Write-Host "===========================================" -ForegroundColor Red Write-Host "--- Chocolatey is not installed ---" -ForegroundColor Red Write-Host "===========================================" -ForegroundColor Red $status = "not-installed" } } return $status } function Update-WinUtilSelections ($flatJson) { foreach ($cbkey in $flatJson) { $listName = switch -Regex ($cbkey) { '^WPFInstall' { 'selectedApps' } '^WPFTweaks' { 'selectedTweaks' } '^WPFToggle' { 'selectedToggles' } '^WPFFeature' { 'selectedFeatures' } '^WPFAppx' { 'selectedAppx' } } $sync.$listName.Add($cbkey) } } function Write-WinUtilLog { <# .SYNOPSIS Writes a timestamped WinUtil log entry to the active session log. .PARAMETER Message The message to write. .PARAMETER Level The severity level for the log entry. .PARAMETER Component The WinUtil component producing the log entry. #> param ( [Parameter(Mandatory = $true)] [string]$Message, [ValidateSet("INFO", "WARN", "ERROR", "DEBUG")] [string]$Level = "INFO", [string]$Component = "WinUtil" ) try { $logPath = $null $transcriptPath = $null if ($null -ne $sync -and $sync.ContainsKey("logPath")) { $logPath = $sync.logPath } if ($null -ne $sync -and $sync.ContainsKey("transcriptPath")) { $transcriptPath = $sync.transcriptPath } if ([string]::IsNullOrWhiteSpace($logPath) -and -not [string]::IsNullOrWhiteSpace($transcriptPath)) { $logPath = $transcriptPath } if ([string]::IsNullOrWhiteSpace($logPath) -and $null -ne $sync -and $sync.ContainsKey("winutildir")) { $logDirectory = Join-Path $sync.winutildir "logs" $logPath = Join-Path $logDirectory "winutil_$(Get-Date -Format "yyyy-MM-dd_HH-mm-ss").log" $sync.logPath = $logPath } if ([string]::IsNullOrWhiteSpace($logPath) -and -not [string]::IsNullOrWhiteSpace($env:LocalAppData)) { if ([string]::IsNullOrWhiteSpace($script:WinUtilLogPath)) { $logDirectory = Join-Path (Join-Path $env:LocalAppData "winutil") "logs" $script:WinUtilLogPath = Join-Path $logDirectory "winutil_$(Get-Date -Format "yyyy-MM-dd_HH-mm-ss").log" } $logPath = $script:WinUtilLogPath } if ([string]::IsNullOrWhiteSpace($logPath)) { return } $logDirectory = Split-Path -Path $logPath -Parent if (-not (Test-Path $logDirectory)) { New-Item -Path $logDirectory -ItemType Directory -Force | Out-Null } $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss.fff" $line = "[$timestamp] [$Level] [$Component] $Message" if (-not [string]::IsNullOrWhiteSpace($transcriptPath) -and $logPath -eq $transcriptPath) { Write-Host $line return } try { Add-Content -Path $logPath -Value $line -Encoding UTF8 -ErrorAction Stop } catch [System.IO.IOException] { Write-Host $line } } catch { Write-Warning "Unable to write WinUtil log entry: $($_.Exception.Message)" } } function Initialize-WPFUI { [OutputType([void])] param( [Parameter(Mandatory)] [string]$TargetGridName ) switch ($TargetGridName) { "appscategory"{ # TODO # Switch UI generation of the sidebar to this function # $sync.ItemsControl = Initialize-InstallAppArea -TargetElement $TargetGridName # ... # Create and configure a popup for displaying selected apps $selectedAppsPopup = New-Object Windows.Controls.Primitives.Popup $selectedAppsPopup.IsOpen = $false $selectedAppsPopup.PlacementTarget = $sync.WPFselectedAppsButton $selectedAppsPopup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Bottom $selectedAppsPopup.AllowsTransparency = $true # Style the popup with a border and background $selectedAppsBorder = New-Object Windows.Controls.Border $selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BackgroundProperty, "MainBackgroundColor") $selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderBrushProperty, "MainForegroundColor") $selectedAppsBorder.SetResourceReference([Windows.Controls.Control]::BorderThicknessProperty, "ButtonBorderThickness") $selectedAppsBorder.Width = 200 $selectedAppsBorder.Padding = 5 $selectedAppsPopup.Child = $selectedAppsBorder $sync.selectedAppsPopup = $selectedAppsPopup # Add a stack panel inside the popup's border to organize its child elements $sync.selectedAppsstackPanel = New-Object Windows.Controls.StackPanel $selectedAppsBorder.Child = $sync.selectedAppsstackPanel # Close selectedAppsPopup when mouse leaves both button and selectedAppsPopup $sync.WPFselectedAppsButton.Add_MouseLeave({ if (-not $sync.selectedAppsPopup.IsMouseOver) { $sync.selectedAppsPopup.IsOpen = $false } }) $selectedAppsPopup.Add_MouseLeave({ if (-not $sync.WPFselectedAppsButton.IsMouseOver) { $sync.selectedAppsPopup.IsOpen = $false } }) # Creates the popup that is displayed when the user right-clicks on an app entry # This popup contains buttons for installing, uninstalling, and viewing app information $appPopup = New-Object Windows.Controls.Primitives.Popup $appPopup.StaysOpen = $false $appPopup.Placement = [System.Windows.Controls.Primitives.PlacementMode]::Bottom $appPopup.AllowsTransparency = $true # Store the popup globally so the position can be set later $sync.appPopup = $appPopup $appPopupStackPanel = New-Object Windows.Controls.StackPanel $appPopupStackPanel.Orientation = "Horizontal" $appPopupStackPanel.Add_MouseLeave({ $sync.appPopup.IsOpen = $false }) $appPopup.Child = $appPopupStackPanel $appButtons = @( [PSCustomObject]@{ Name = "Install"; Icon = [char]0xE118 }, [PSCustomObject]@{ Name = "Uninstall"; Icon = [char]0xE74D }, [PSCustomObject]@{ Name = "Info"; Icon = [char]0xE946 } ) foreach ($button in $appButtons) { $newButton = New-Object Windows.Controls.Button $newButton.Style = $sync.Form.Resources.AppEntryButtonStyle $newButton.Content = $button.Icon $appPopupStackPanel.Children.Add($newButton) | Out-Null # Dynamically load the selected app object so the buttons can be reused and do not need to be created for each app switch ($button.Name) { "Install" { $newButton.Add_MouseEnter({ $appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp) $this.ToolTip = "Install or Upgrade $($appObject.content)" }) $newButton.Add_Click({ $appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp) Invoke-WPFInstall -PackagesToInstall $appObject }) } "Uninstall" { $newButton.Add_MouseEnter({ $appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp) $this.ToolTip = "Uninstall $($appObject.content)" }) $newButton.Add_Click({ $appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp) Invoke-WPFUnInstall -PackagesToUninstall $appObject }) } "Info" { $newButton.Add_MouseEnter({ $appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp) $this.ToolTip = "Open the application's website in your default browser`n$($appObject.link)" }) $newButton.Add_Click({ $appObject = $sync.configs.applicationsHashtable.$($sync.appPopupSelectedApp) Start-Process $appObject.link }) } } } } "appspanel" { $sync.ItemsControl = Initialize-InstallAppArea -TargetElement $TargetGridName Initialize-InstallCategoryAppList -TargetElement $sync.ItemsControl -Apps $sync.configs.applicationsHashtable } default { Write-Output "$TargetGridName not yet implemented" } } } function Invoke-WinUtilAutoRun { <# .SYNOPSIS Runs Install, Tweaks, and Features with optional UI invocation. #> function BusyWait { Start-Sleep -Milliseconds 100 while ($sync.ProcessRunning) { Start-Sleep -Milliseconds 100 } } if ($sync.selectedTweaks.Count -gt 0) { Write-Host "Applying tweaks..." Invoke-WPFtweaksbutton BusyWait } if ($sync.selectedFeatures.Count -gt 0) { Write-Host "Applying features..." Invoke-WPFFeatureInstall BusyWait } if ($sync.selectedApps.Count -gt 0) { Write-Host "Installing applications..." Invoke-WPFInstall BusyWait } if ($sync.selectedAppx.Count -gt 0) { Write-Host "Removing AppX packages..." Invoke-WPFAppxRemoval BusyWait } Write-Host "Done." } function Invoke-WPFAppxRemoval { if ($null -eq $sync.selectedAppx -or $sync.selectedAppx.Count -eq 0) { Show-WinUtilMessage -Message "No AppX Package selected" -Title "Error" -Button "OK" -Icon "Error" return } $selected = $sync.selectedAppx $apps = $sync.configs.appxHashtable Invoke-WPFRunspace -ParameterList @(("selected", $selected), ("apps", $apps)) -ScriptBlock { param($selected, $apps) $sync.ProcessRunning = $true Write-WinUtilLog -Component "AppX" -Message "Starting AppX removal for $(@($selected).Count) selected package(s)." foreach ($key in $selected) { if ($key -eq "WPFAppxMicrosoft_XboxGamingOverlay") { # Making sure Game Bar isn't running Write-WinUtilLog -Component "AppX" -Message "Stopping GameBarFTServer before removing Xbox Gaming Overlay." Stop-Process -Name GameBarFTServer # This stops annoying ms-gamebar popup when launching games. Write-WinUtilLog -Component "AppX" -Message "Disabling Game DVR capture before removing Xbox Gaming Overlay." Set-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\GameDVR -Name AppCaptureEnabled -Value 0 } if ($key -eq "WPFAppxMicrosoft_WindowsNotepad") { # i hope your having fun reading this Write-WinUtilLog -Component "AppX" -Message "Stopping dllhost before removing Notepad." Stop-Process -Name dllhost } Write-Host "Removing $($apps[$key].Content)" Write-WinUtilLog -Component "AppX" -Message "Removing $($apps[$key].Content) ($($apps[$key].PackageId))." Get-AppxPackage -Name $apps[$key].PackageId -AllUsers | Remove-AppxPackage -AllUsers if ($key -eq "WPFAppxMSTeams") { # Uninstalls Microsoft Teams Meeting Add-in for Microsoft Office Write-WinUtilLog -Component "AppX" -Message "Uninstalling Microsoft Teams meeting add-in package." Get-Package -Name "Microsoft Teams*" -ErrorAction SilentlyContinue | Uninstall-Package -Force } } Write-Host "=================================" Write-Host "-- AppX Removal Finished ---" Write-Host "=================================" Write-WinUtilLog -Component "AppX" -Message "AppX removal finished." $sync.ProcessRunning = $false } } function Invoke-WPFButton { <# .SYNOPSIS Invokes the function associated with the clicked button .PARAMETER Button The name of the button that was clicked #> Param ([string]$Button) # 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 } # Check if button is defined in feature config with function or InvokeScript if ($sync.configs.feature.$Button) { $buttonConfig = $sync.configs.feature.$Button # If button has a function defined, call it if ($buttonConfig.function) { $functionName = $buttonConfig.function if (Get-Command $functionName -ErrorAction SilentlyContinue) { & $functionName return } } # If button has InvokeScript defined, execute the scripts if ($buttonConfig.InvokeScript -and $buttonConfig.InvokeScript.Count -gt 0) { foreach ($script in $buttonConfig.InvokeScript) { if (-not [string]::IsNullOrWhiteSpace($script)) { Invoke-Command -ScriptBlock ([scriptblock]::Create($script)) -ErrorAction Stop } } return } } # Fallback to hard-coded switch for buttons not in feature.json Switch -Wildcard ($Button) { "WPFTab?BT" {Invoke-WPFTab $Button} "WPFInstall" {Invoke-WPFInstall} "WPFUninstall" {Invoke-WPFUnInstall} "WPFInstallUpgrade" {Invoke-WPFInstallUpgrade} "WPFCollapseAllCategories" {Invoke-WPFToggleAllCategories -Action "Collapse"} "WPFExpandAllCategories" {Invoke-WPFToggleAllCategories -Action "Expand"} "WPFStandard" {Invoke-WPFPresets "Standard" -checkboxfilterpattern "WPFTweak*"} "WPFMinimal" {Invoke-WPFPresets "Minimal" -checkboxfilterpattern "WPFTweak*"} "WPFAdvanced" {Invoke-WPFPresets "Advanced" -checkboxfilterpattern "WPFTweak*"} "WPFClearTweaksSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFTweak*"} "WPFClearInstallSelection" {Invoke-WPFPresets -imported $true -checkboxfilterpattern "WPFInstall*"} "WPFtweaksbutton" {Invoke-WPFtweaksbutton} "WPFOOSUbutton" {Invoke-WPFOOSU} "WPFAddUltPerf" {Invoke-WPFUltimatePerformance -Enable} "WPFRemoveUltPerf" {Invoke-WPFUltimatePerformance} "WPFundoall" {Invoke-WPFundoall} "WPFUpdatesdefault" {Invoke-WPFUpdatesdefault} "WPFUpdatesdisable" {Invoke-WPFUpdatesdisable} "WPFUpdatessecurity" {Invoke-WPFUpdatessecurity} "WPFGetInstalled" {Invoke-WPFGetInstalled -CheckBox "winget"} "WPFGetInstalledTweaks" {Invoke-WPFGetInstalled -CheckBox "tweaks"} "WPFRemoveSelectedAppx" {Invoke-WPFAppxRemoval} "WPFDefaultAppxSelection" {Invoke-WPFPresets "AppxDefault" -checkboxfilterpattern "WPFAppx*"} "WPFSelectAllAppx" { $sync.configs.appxHashtable.Keys | ForEach-Object {$sync.$_.IsChecked = $true} } "WPFClearAppxSelection" { $sync.configs.appxHashtable.Keys | ForEach-Object {$sync.$_.IsChecked = $false} } "WPFGetInstalledAppx" { $installedAppxPackages = Get-AppxPackage -AllUsers | Select-Object -ExpandProperty Name foreach ($appx in $sync.configs.appxHashtable.GetEnumerator()) { if ($appx.Value.PackageId -in $installedAppxPackages) { $sync.$($appx.Key).IsChecked = $true } } } "WPFCloseButton" {$sync.Form.Close(); Write-Host "Bye bye!"} "WPFMinimizeButton" {$sync.Form.WindowState = [Windows.WindowState]::Minimized} "WPFselectedAppsButton" {$sync.selectedAppsPopup.IsOpen = -not $sync.selectedAppsPopup.IsOpen} } } function Invoke-WPFFeatureInstall { <# .SYNOPSIS Installs selected Windows Features #> if($sync.ProcessRunning) { $msg = "[Invoke-WPFFeatureInstall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } Invoke-WPFRunspace -ScriptBlock { $Features = $sync.selectedFeatures $sync.ProcessRunning = $true if ($Features.count -eq 1) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" } } else { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" } } $x = 0 $Features | ForEach-Object { Invoke-WinUtilFeatureInstall $_ $X++ Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($x/$Features.Count) } } $sync.ProcessRunning = $false Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } Write-Host "===================================" Write-Host "--- Features are Installed ---" Write-Host "--- A Reboot may be required ---" Write-Host "===================================" } } function Invoke-WPFFixesNetwork { netsh winsock reset netsh int ip reset Write-Host "Network Configuration has been Reset. Please restart your computer." } function Invoke-WPFFixesNTPPool { <# .SYNOPSIS Configures Windows to use pool.ntp.org for NTP synchronization .DESCRIPTION Replaces the default Windows NTP server (time.windows.com) with pool.ntp.org for improved time synchronization accuracy and reliability. #> Start-Service w32time w32tm /config /update /manualpeerlist:"pool.ntp.org,0x8" /syncfromflags:MANUAL Restart-Service w32time w32tm /resync Write-Host "=================================" Write-Host "-- NTP Configuration Complete ---" Write-Host "=================================" } function Invoke-WPFFixesUpdate { <# .SYNOPSIS Performs various tasks in an attempt to repair Windows Update .DESCRIPTION 1. (Aggressive Only) Scans the system for corruption using the Invoke-WPFSystemRepair function 2. Stops Windows Update Services 3. Remove the QMGR Data file, which stores BITS jobs 4. (Aggressive Only) Renames the DataStore and CatRoot2 folders DataStore - Contains the Windows Update History and Log Files CatRoot2 - Contains the Signatures for Windows Update Packages 5. Renames the Windows Update Download Folder 6. Deletes the Windows Update Log 7. (Aggressive Only) Resets the Security Descriptors on the Windows Update Services 8. Reregisters the BITS and Windows Update DLLs 9. Removes the WSUS client settings 10. Resets WinSock 11. Gets and deletes all BITS jobs 12. Sets the startup type of the Windows Update Services then starts them 13. Forces Windows Update to check for updates .PARAMETER Aggressive If specified, the script will take additional steps to repair Windows Update that are more dangerous, take a significant amount of time, or are generally unnecessary #> param($Aggressive = $false) Write-Progress -Id 0 -Activity "Repairing Windows Update" -PercentComplete 0 Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo" Write-Host "Starting Windows Update Repair..." # Wait for the first progress bar to show, otherwise the second one won't show Start-Sleep -Milliseconds 200 if ($Aggressive) { Invoke-WPFSystemRepair } Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Stopping Windows Update Services..." -PercentComplete 10 # Stop the Windows Update Services Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping BITS..." -PercentComplete 0 Stop-Service -Name BITS -Force Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping wuauserv..." -PercentComplete 20 Stop-Service -Name wuauserv -Force Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping appidsvc..." -PercentComplete 40 Stop-Service -Name appidsvc -Force Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Stopping cryptsvc..." -PercentComplete 60 Stop-Service -Name cryptsvc -Force Write-Progress -Id 2 -ParentId 0 -Activity "Stopping Services" -Status "Completed" -PercentComplete 100 # Remove the QMGR Data file Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Renaming/Removing Files..." -PercentComplete 20 Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Removing QMGR Data files..." -PercentComplete 0 Remove-Item "$env:allusersprofile\Application Data\Microsoft\Network\Downloader\qmgr*.dat" -ErrorAction SilentlyContinue if ($Aggressive) { # Rename the Windows Update Log and Signature Folders Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Renaming the Windows Update Log, Download, and Signature Folder..." -PercentComplete 20 Rename-Item $env:systemroot\SoftwareDistribution\DataStore DataStore.bak -ErrorAction SilentlyContinue Rename-Item $env:systemroot\System32\Catroot2 catroot2.bak -ErrorAction SilentlyContinue } # Rename the Windows Update Download Folder Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Renaming the Windows Update Download Folder..." -PercentComplete 20 Rename-Item $env:systemroot\SoftwareDistribution\Download Download.bak -ErrorAction SilentlyContinue # Delete the legacy Windows Update Log Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Removing the old Windows Update log..." -PercentComplete 80 Remove-Item $env:systemroot\WindowsUpdate.log -ErrorAction SilentlyContinue Write-Progress -Id 3 -ParentId 0 -Activity "Renaming/Removing Files" -Status "Completed" -PercentComplete 100 if ($Aggressive) { # Reset the Security Descriptors on the Windows Update Services Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting the WU Service Security Descriptors..." -PercentComplete 25 Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the BITS Security Descriptor..." -PercentComplete 0 Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "bits", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)" -Wait Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Resetting the wuauserv Security Descriptor..." -PercentComplete 50 Start-Process -NoNewWindow -FilePath "sc.exe" -ArgumentList "sdset", "wuauserv", "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)" -Wait Write-Progress -Id 4 -ParentId 0 -Activity "Resetting the WU Service Security Descriptors" -Status "Completed" -PercentComplete 100 } # Reregister the BITS and Windows Update DLLs Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Reregistering DLLs..." -PercentComplete 40 $oldLocation = Get-Location Set-Location $env:systemroot\system32 $i = 0 $DLLs = @( "atl.dll", "urlmon.dll", "mshtml.dll", "shdocvw.dll", "browseui.dll", "jscript.dll", "vbscript.dll", "scrrun.dll", "msxml.dll", "msxml3.dll", "msxml6.dll", "actxprxy.dll", "softpub.dll", "wintrust.dll", "dssenh.dll", "rsaenh.dll", "gpkcsp.dll", "sccbase.dll", "slbcsp.dll", "cryptdlg.dll", "oleaut32.dll", "ole32.dll", "shell32.dll", "initpki.dll", "wuapi.dll", "wuaueng.dll", "wuaueng1.dll", "wucltui.dll", "wups.dll", "wups2.dll", "wuweb.dll", "qmgr.dll", "qmgrprxy.dll", "wucltux.dll", "muweb.dll", "wuwebv.dll" ) foreach ($dll in $DLLs) { Write-Progress -Id 5 -ParentId 0 -Activity "Reregistering DLLs" -Status "Registering $dll..." -PercentComplete ($i / $DLLs.Count * 100) $i++ Start-Process -NoNewWindow -FilePath "regsvr32.exe" -ArgumentList "/s", $dll } Set-Location $oldLocation Write-Progress -Id 5 -ParentId 0 -Activity "Reregistering DLLs" -Status "Completed" -PercentComplete 100 # Remove the WSUS client settings if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate") { Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing WSUS client settings..." -PercentComplete 60 Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -PercentComplete 0 Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "AccountDomainSid", "/f" -RedirectStandardError "NUL" Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "PingID", "/f" -RedirectStandardError "NUL" Start-Process -NoNewWindow -FilePath "REG" -ArgumentList "DELETE", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate", "/v", "SusClientId", "/f" -RedirectStandardError "NUL" Write-Progress -Id 6 -ParentId 0 -Activity "Removing WSUS client settings" -Status "Completed" -PercentComplete 100 } # Remove Group Policy Windows Update settings Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Removing Group Policy Windows Update settings..." -PercentComplete 60 Write-Progress -Id 7 -ParentId 0 -Activity "Removing Group Policy Windows Update settings" -PercentComplete 0 Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ExcludeWUDriversInQualityUpdate" -ErrorAction SilentlyContinue Write-Host "Defaulting driver offering through Windows Update..." Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Name "PreventDeviceMetadataFromNetwork" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontPromptForWindowsUpdate" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontSearchWindowsUpdate" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DriverUpdateWizardWuSearchEnabled" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ExcludeWUDriversInQualityUpdate" -ErrorAction SilentlyContinue Write-Host "Defaulting Windows Update automatic restart..." Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoRebootWithLoggedOnUsers" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "AUPowerManagement" -ErrorAction SilentlyContinue Write-Host "Clearing ANY Windows Update Policy settings..." Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "BranchReadinessLevel" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "DeferFeatureUpdatesPeriodInDays" -ErrorAction SilentlyContinue Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "DeferQualityUpdatesPeriodInDays" -ErrorAction SilentlyContinue Remove-Item -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKCU:\Software\Microsoft\WindowsSelfHost" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKCU:\Software\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\Microsoft\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\WindowsStore\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\Microsoft\WindowsSelfHost" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Policies" -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\WindowsStore\WindowsUpdate" -Recurse -Force -ErrorAction SilentlyContinue Start-Process -NoNewWindow -FilePath "secedit" -ArgumentList "/configure", "/cfg", "$env:windir\inf\defltbase.inf", "/db", "defltbase.sdb", "/verbose" -Wait Start-Process -NoNewWindow -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicyUsers" -Wait Start-Process -NoNewWindow -FilePath "cmd.exe" -ArgumentList "/c RD /S /Q $env:WinDir\System32\GroupPolicy" -Wait Start-Process -NoNewWindow -FilePath "gpupdate" -ArgumentList "/force" -Wait Write-Progress -Id 7 -ParentId 0 -Activity "Removing Group Policy Windows Update settings" -Status "Completed" -PercentComplete 100 # Reset WinSock Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Resetting WinSock..." -PercentComplete 65 Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Resetting WinSock..." -PercentComplete 0 Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winsock", "reset" Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "winhttp", "reset", "proxy" Start-Process -NoNewWindow -FilePath "netsh" -ArgumentList "int", "ip", "reset" Write-Progress -Id 7 -ParentId 0 -Activity "Resetting WinSock" -Status "Completed" -PercentComplete 100 # Get and delete all BITS jobs Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Deleting BITS jobs..." -PercentComplete 75 Write-Progress -Id 8 -ParentId 0 -Activity "Deleting BITS jobs" -Status "Deleting BITS jobs..." -PercentComplete 0 Get-BitsTransfer | Remove-BitsTransfer Write-Progress -Id 8 -ParentId 0 -Activity "Deleting BITS jobs" -Status "Completed" -PercentComplete 100 # Change the startup type of the Windows Update Services and start them Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Starting Windows Update Services..." -PercentComplete 90 Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting BITS..." -PercentComplete 0 Get-Service BITS | Set-Service -StartupType Manual -PassThru | Start-Service Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting wuauserv..." -PercentComplete 25 Get-Service wuauserv | Set-Service -StartupType Manual -PassThru | Start-Service Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting AppIDSvc..." -PercentComplete 50 # The AppIDSvc service is protected, so the startup type has to be changed in the registry Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\AppIDSvc" -Name "Start" -Value "3" # Manual Start-Service AppIDSvc Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Starting CryptSvc..." -PercentComplete 75 Get-Service CryptSvc | Set-Service -StartupType Manual -PassThru | Start-Service Write-Progress -Id 9 -ParentId 0 -Activity "Starting Windows Update Services" -Status "Completed" -PercentComplete 100 # Force Windows Update to check for updates Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Forcing discovery..." -PercentComplete 95 Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Forcing discovery..." -PercentComplete 0 try { (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow() } catch { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" Write-Warning "Failed to create Windows Update COM object: $_" } Start-Process -NoNewWindow -FilePath "wuauclt" -ArgumentList "/resetauthorization", "/detectnow" Write-Progress -Id 10 -ParentId 0 -Activity "Forcing discovery" -Status "Completed" -PercentComplete 100 Write-Progress -Id 0 -Activity "Repairing Windows Update" -Status "Completed" -PercentComplete 100 Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" $ButtonType = [System.Windows.MessageBoxButton]::OK $MessageboxTitle = "Reset Windows Update " $Messageboxbody = ("Stock settings loaded.`n Please reboot your computer") $MessageIcon = [System.Windows.MessageBoxImage]::Information [System.Windows.MessageBox]::Show($Messageboxbody, $MessageboxTitle, $ButtonType, $MessageIcon) Write-Host "===============================================" Write-Host "-- Reset All Windows Update Settings to Stock -" Write-Host "===============================================" # Remove the progress bars Write-Progress -Id 0 -Activity "Repairing Windows Update" -Completed Write-Progress -Id 1 -Activity "Scanning for corruption" -Completed Write-Progress -Id 2 -Activity "Stopping Services" -Completed Write-Progress -Id 3 -Activity "Renaming/Removing Files" -Completed Write-Progress -Id 4 -Activity "Resetting the WU Service Security Descriptors" -Completed Write-Progress -Id 5 -Activity "Reregistering DLLs" -Completed Write-Progress -Id 6 -Activity "Removing Group Policy Windows Update settings" -Completed Write-Progress -Id 7 -Activity "Resetting WinSock" -Completed Write-Progress -Id 8 -Activity "Deleting BITS jobs" -Completed Write-Progress -Id 9 -Activity "Starting Windows Update Services" -Completed Write-Progress -Id 10 -Activity "Forcing discovery" -Completed } function Invoke-WPFFixesWinget { <# .SYNOPSIS Fixes WinGet by running `choco install winget` .DESCRIPTION BravoNorris for the fantastic idea of a button to reinstall WinGet #> # Install Choco if not already present try { Set-WinUtilTaskbaritem -state "Indeterminate" -overlay "logo" Write-Host "==> Starting WinGet Repair" Install-WinUtilWinget } catch { Write-Error "Failed to install WinGet: $_" Set-WinUtilTaskbaritem -state "Error" -overlay "warning" } finally { Write-Host "==> Finished WinGet Repair" Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } } function Invoke-WPFGetInstalled { <# TODO: Add the Option to use Chocolatey as Engine .SYNOPSIS Invokes the function that gets the checkboxes to check in a new runspace .PARAMETER checkbox Indicates whether to check for installed 'winget' programs or applied 'tweaks' #> param($checkbox) if ($sync.ProcessRunning) { $msg = "[Invoke-WPFGetInstalled] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } if (($sync.ChocoRadioButton.IsChecked -eq $false) -and ((Test-WinUtilPackageManager -winget) -eq "not-installed") -and $checkbox -eq "winget") { return } $managerPreference = $sync.preferences.packagemanager Invoke-WPFRunspace -ParameterList @(("managerPreference", $managerPreference),("checkbox", $checkbox)) -ScriptBlock { param ( [string]$checkbox, [string]$managerPreference ) $sync.ProcessRunning = $true Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" } if ($checkbox -eq "winget") { Write-Host "Getting Installed Programs..." switch ($managerPreference) { "Choco"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox "choco"; break} "Winget"{$Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox; break} } } elseif ($checkbox -eq "tweaks") { Write-Host "Getting Installed Tweaks..." $Checkboxes = Invoke-WinUtilCurrentSystem -CheckBox $checkbox } $sync.form.Dispatcher.invoke({ foreach ($checkbox in $Checkboxes) { $sync.$checkbox.ischecked = $True } }) Write-Host "Done..." $sync.ProcessRunning = $false Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" } } } function Invoke-WPFImpex { <# .SYNOPSIS Handles importing and exporting of the checkboxes checked for the tweaks section .PARAMETER type Indicates whether to 'import' or 'export' .PARAMETER checkbox The checkbox to export to a file or apply the imported file to .EXAMPLE Invoke-WPFImpex -type "export" #> param( $type, $Config = $null ) function ConfigDialog { if (!$Config) { switch ($type) { "export" { $FileBrowser = New-Object System.Windows.Forms.SaveFileDialog } "import" { $FileBrowser = New-Object System.Windows.Forms.OpenFileDialog } } $FileBrowser.InitialDirectory = [Environment]::GetFolderPath('Desktop') $FileBrowser.Filter = "JSON Files (*.json)|*.json" $FileBrowser.ShowDialog() | Out-Null if ($FileBrowser.FileName -eq "") { return $null } else { return $FileBrowser.FileName } } else { return $Config } } switch ($type) { "export" { try { $Config = ConfigDialog if ($Config) { $allConfs = ($sync.selectedApps + $sync.selectedTweaks + $sync.selectedToggles + $sync.selectedFeatures + $sync.selectedAppx) | ForEach-Object { [string]$_ } if (-not $allConfs) { [System.Windows.MessageBox]::Show( "No settings are selected to export. Please select at least one app, tweak, toggle, feature, or AppX package before exporting.", "Nothing to Export", "OK", "Warning") return } $jsonFile = $allConfs | ConvertTo-Json $jsonFile | Out-File $Config -Force "iex ""& { `$(irm https://christitus.com/win) } -Config '$Config'""" | Set-Clipboard } } catch { 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 } } catch { Write-Error "Failed to load the JSON file from the specified path or URL: $_" return } # TODO how to handle old style? detected json type then flatten it in a func? # $flattenedJson = $jsonFile.PSObject.Properties.Where({ $_.Name -ne "Install" }).ForEach({ $_.Value }) $flattenedJson = $jsonFile if (-not $flattenedJson) { [System.Windows.MessageBox]::Show( "The selected file contains no settings to import. No changes have been made.", "Empty Configuration", "OK", "Warning") return } # Clear all existing selections before importing so the import replaces # the current state rather than merging with it $sync.selectedAppx = [System.Collections.Generic.List[string]]::new() $sync.selectedApps = [System.Collections.Generic.List[string]]::new() $sync.selectedTweaks = [System.Collections.Generic.List[string]]::new() $sync.selectedToggles = [System.Collections.Generic.List[string]]::new() $sync.selectedFeatures = [System.Collections.Generic.List[string]]::new() Update-WinUtilSelections -flatJson $flattenedJson if ($sync.Form) { Reset-WPFCheckBoxes -doToggles $true } } } catch { Write-Error "An error occurred while importing: $_" } } } } function Invoke-WPFInstall { <# .SYNOPSIS Installs the selected programs using winget, if one or more of the selected programs are already installed on the system, winget will try and perform an upgrade if there's a newer version to install. #> $PackagesToInstall = $sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ } if($sync.ProcessRunning) { $msg = "[Invoke-WPFInstall] An Install process is currently running." Show-WinUtilMessage -Message $msg -Title "Winutil" -Button "OK" -Icon "Warning" return } if ($PackagesToInstall.Count -eq 0) { $WarningMsg = "Please select the program(s) to install or upgrade." Show-WinUtilMessage -Message $WarningMsg -Title $AppTitle -Button "OK" -Icon "Warning" return } $ManagerPreference = $sync.preferences.packagemanager Write-WinUtilLog -Component "Install" -Message "Install requested for $(@($PackagesToInstall).Count) selected package(s) using preference: $ManagerPreference" $packageSummary = Get-WinUtilPackageLogSummary -Packages $PackagesToInstall -Preference $ManagerPreference Write-WinUtilLog -Component "Install" -Message "Install selected package(s): $($packageSummary -join '; ')" Invoke-WPFRunspace -ParameterList @(("PackagesToInstall", $PackagesToInstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock { param($PackagesToInstall, $ManagerPreference) $packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToInstall -Preference $ManagerPreference $packagesWinget = $packagesSorted['Winget'] $packagesChoco = $packagesSorted['Choco'] Write-WinUtilLog -Component "Install" -Message "Install package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)" try { $sync.ProcessRunning = $true if($packagesWinget.Count -gt 0 -and $packagesWinget -ne "0") { Show-WPFInstallAppBusy -text "Installing apps..." Install-WinUtilWinget Install-WinUtilProgramWinget -Action Install -Programs $packagesWinget } if($packagesChoco.Count -gt 0) { Install-WinUtilChoco Install-WinUtilProgramChoco -Action Install -Programs $packagesChoco } Hide-WPFInstallAppBusy Write-Host "===========================================" Write-Host "-- Installs have finished ---" Write-Host "===========================================" Write-WinUtilLog -Component "Install" -Message "Install workflow completed." Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } } catch { Hide-WPFInstallAppBusy Write-Host "===========================================" Write-Host "Error: $_" Write-Host "===========================================" Write-WinUtilLog -Level "ERROR" -Component "Install" -Message "Install workflow failed: $($_.Exception.Message)" Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" } } finally { $sync.ProcessRunning = $False } } } function Invoke-WPFInstallUpgrade { if ($sync.ChocoRadioButton.IsChecked) { Install-WinUtilChoco # Ensure Chocolatey is installed before upgrading Write-Host "===========================================" Write-Host "-- Updates started ---" Write-Host "-- You can close this window if desired ---" Write-Host "===========================================" Start-Process -FilePath powershell.exe -ArgumentList 'choco upgrade all -y' } else { Install-WinUtilWinget # Ensure WinGet is installed before upgrading Write-Host "===========================================" Write-Host "-- Updates started ---" Write-Host "-- You can close this window if desired ---" Write-Host "===========================================" Start-Process -FilePath powershell.exe -ArgumentList '-NoExit winget upgrade --all --include-unknown --silent --accept-source-agreements --accept-package-agreements' } } function Invoke-WPFOOSU { try { $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe -OutFile "$winutildir\ooshutup10.exe" Start-Process -FilePath "$winutildir\ooshutup10.exe" $ProgressPreference = 'Continue' } catch { Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection." } } function Invoke-WPFPanelAutologin { Invoke-WebRequest -Uri https://live.sysinternals.com/Autologon.exe -OutFile "$winutildir\autologin.exe" Start-Process -FilePath "$winutildir\autologin.exe" -ArgumentList /accepteula } function Invoke-WPFPopup { param ( [ValidateSet("Show", "Hide", "Toggle")] [string]$Action = "", [string[]]$Popups = @(), [ValidateScript({ $invalid = $_.GetEnumerator() | Where-Object { $_.Value -notin @("Show", "Hide", "Toggle") } if ($invalid) { throw "Found invalid Popup-Action pair(s): " + ($invalid | ForEach-Object { "$($_.Key) = $($_.Value)" } -join "; ") } $true })] [hashtable]$PopupActionTable = @{} ) if (-not $PopupActionTable.Count -and (-not $Action -or -not $Popups.Count)) { throw "Provide either 'PopupActionTable' or both 'Action' and 'Popups'." } if ($PopupActionTable.Count -and ($Action -or $Popups.Count)) { throw "Use 'PopupActionTable' on its own, or 'Action' with 'Popups'." } # Collect popups and actions $PopupsToProcess = if ($PopupActionTable.Count) { $PopupActionTable.GetEnumerator() | ForEach-Object { [PSCustomObject]@{ Name = "$($_.Key)Popup"; Action = $_.Value } } } else { $Popups | ForEach-Object { [PSCustomObject]@{ Name = "$_`Popup"; Action = $Action } } } $PopupsNotFound = @() # Apply actions foreach ($popupEntry in $PopupsToProcess) { $popupName = $popupEntry.Name if (-not $sync.$popupName) { $PopupsNotFound += $popupName continue } $sync.$popupName.IsOpen = switch ($popupEntry.Action) { "Show" { $true } "Hide" { $false } "Toggle" { -not $sync.$popupName.IsOpen } } } if ($PopupsNotFound.Count -gt 0) { throw "Could not find the following popups: $($PopupsNotFound -join ', ')" } } function Invoke-WPFPresets { <# .SYNOPSIS Sets the checkboxes in winutil to the given preset .PARAMETER preset The preset to set the checkboxes to .PARAMETER imported If the preset is imported from a file, defaults to false .PARAMETER checkboxfilterpattern The Pattern to use when filtering through CheckBoxes, defaults to "**" #> param ( [Parameter(position=0)] [Array]$preset = $null, [Parameter(position=1)] [bool]$imported = $false, [Parameter(position=2)] [string]$checkboxfilterpattern = "**" ) if ($imported -eq $true) { $CheckBoxesToCheck = $preset } else { $CheckBoxesToCheck = $sync.configs.preset.$preset } # clear out the filtered pattern so applying a preset replaces the current # state rather than merging with it switch ($checkboxfilterpattern) { "WPFTweak*" { $sync.selectedTweaks = [System.Collections.Generic.List[string]]::new() } "WPFInstall*" { $sync.selectedApps = [System.Collections.Generic.List[string]]::new() } "WPFAppx*" { $sync.selectedAppx = [System.Collections.Generic.List[string]]::new() } "WPFeatures" { $sync.selectedFeatures = [System.Collections.Generic.List[string]]::new() } "WPFToggle" { $sync.selectedToggles = [System.Collections.Generic.List[string]]::new() } default {} } if ($preset) { Update-WinUtilSelections -flatJson $CheckBoxesToCheck } Reset-WPFCheckBoxes -doToggles $false -checkboxfilterpattern $checkboxfilterpattern } function Invoke-WPFRunspace { <# .SYNOPSIS Creates and invokes a runspace using the given scriptblock and argumentlist .PARAMETER ScriptBlock The scriptblock to invoke in the runspace .PARAMETER ArgumentList A list of arguments to pass to the runspace .PARAMETER ParameterList A list of named parameters that should be provided. .EXAMPLE Invoke-WPFRunspace ` -ScriptBlock $sync.ScriptsInstallPrograms ` -ArgumentList "Installadvancedip,Installbitwarden" ` Invoke-WPFRunspace` -ScriptBlock $sync.ScriptsInstallPrograms ` -ParameterList @(("PackagesToInstall", @("Installadvancedip,Installbitwarden")),("ChocoPreference", $true)) #> [CmdletBinding()] [OutputType([System.IAsyncResult])] Param ( $ScriptBlock, $ArgumentList, $ParameterList ) if (-not ("WinUtilRunspaceCleanup" -as [type])) { Add-Type @" using System; using System.Management.Automation; public sealed class WinUtilRunspaceCleanupState { public PowerShell PowerShell { get; set; } public IAsyncResult Handle { get; set; } } public static class WinUtilRunspaceCleanup { public static void Cleanup(object state, bool timedOut) { var cleanupState = state as WinUtilRunspaceCleanupState; if (cleanupState == null || cleanupState.PowerShell == null || cleanupState.Handle == null) { return; } try { cleanupState.PowerShell.EndInvoke(cleanupState.Handle); } catch { } finally { cleanupState.PowerShell.Dispose(); } } } "@ } Initialize-WinUtilRunspacePool | Out-Null # Create a PowerShell instance $powershell = [powershell]::Create() # Add Scriptblock and Arguments to runspace [void]$powershell.AddScript($ScriptBlock) [void]$powershell.AddArgument($ArgumentList) foreach ($parameter in $ParameterList) { [void]$powershell.AddParameter($parameter[0], $parameter[1]) } $powershell.RunspacePool = $sync.runspace # Execute the RunspacePool $handle = $powershell.BeginInvoke() $cleanupState = [WinUtilRunspaceCleanupState]::new() $cleanupState.PowerShell = $powershell $cleanupState.Handle = $handle # PowerShell 5.1 cannot cast a static PSMethod directly to a delegate. # Use an explicit delegate wrapper so WinGet/install runspaces always clean up. $cleanupCallback = [System.Threading.WaitOrTimerCallback]{ param($state, $timedOut) [WinUtilRunspaceCleanup]::Cleanup($state, $timedOut) } [System.Threading.ThreadPool]::RegisterWaitForSingleObject($handle.AsyncWaitHandle, $cleanupCallback, $cleanupState, -1, $true) | Out-Null # Return the handle return $handle } function Invoke-WPFSelectedCheckboxesUpdate ($type, $checkboxName) { $listName = switch -Regex ($checkboxName) { '^WPFInstall' { 'selectedApps' } '^WPFTweaks' { 'selectedTweaks' } '^WPFToggle' { 'selectedToggles' } '^WPFFeature' { 'selectedFeatures' } '^WPFAppx' { 'selectedAppx' } } if ($type -eq "Add") { if (-not $sync.$listName.Contains($checkboxName)) { $sync.$listName.Add($checkboxName) } } else { $sync.$listName.Remove($checkboxName) } } function Invoke-WPFSSHServer { <# .SYNOPSIS Invokes the OpenSSH Server install in a runspace #> Invoke-WPFRunspace -ScriptBlock { Invoke-WinUtilSSHServer Write-Host "=======================================" Write-Host "-- OpenSSH Server installed! ---" Write-Host "=======================================" } } function Invoke-WPFSystemRepair { <# .SYNOPSIS Checks for system corruption using SFC, and DISM Checks for disk failure using Chkdsk .DESCRIPTION 1. Chkdsk - Checks for disk errors, which can cause system file corruption and notifies of early disk failure 2. SFC - scans protected system files for corruption and fixes them 3. DISM - Repair a corrupted Windows operating system image #> Start-Process cmd.exe -ArgumentList "/c chkdsk /scan /perf" -NoNewWindow -Wait Start-Process cmd.exe -ArgumentList "/c sfc /scannow" -NoNewWindow -Wait Start-Process cmd.exe -ArgumentList "/c dism /online /cleanup-image /restorehealth" -NoNewWindow -Wait Write-Host "==> Finished System Repair" Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } function Invoke-WPFTab { <# .SYNOPSIS Sets the selected tab to the tab that was clicked .PARAMETER ClickedTab The name of the tab that was clicked #> Param ( [Parameter(Mandatory,position=0)] [string]$ClickedTab ) $tabNav = Get-WinUtilVariables | Where-Object {$psitem -like "WPFTabNav"} $tabNumber = [int]($ClickedTab -replace "WPFTab","" -replace "BT","") - 1 $filter = Get-WinUtilVariables -Type ToggleButton | Where-Object {$psitem -like "WPFTab?BT"} ($sync.GetEnumerator()).where{$psitem.Key -in $filter} | ForEach-Object { if ($ClickedTab -ne $PSItem.name) { $sync[$PSItem.Name].IsChecked = $false } else { $sync["$ClickedTab"].IsChecked = $true $tabNumber = [int]($ClickedTab-replace "WPFTab","" -replace "BT","") - 1 $sync.$tabNav.Items[$tabNumber].IsSelected = $true } } $sync.currentTab = $sync.$tabNav.Items[$tabNumber].Header Initialize-WinUtilTabContent -TabName $sync.currentTab # Always reset the filter for the current tab if ($sync.currentTab -eq "Install") { # Reset Install tab filter Find-AppsByNameOrDescription -SearchString "" } elseif ($sync.currentTab -eq "Tweaks") { # Reset Tweaks tab filter Find-TweaksByNameOrDescription -SearchString "" } elseif ($sync.currentTab -eq "AppX") { # Reset AppX tab filter Find-TweaksByNameOrDescription -SearchString "" } # Show search bar in Install, Tweaks, and AppX tabs if ($tabNumber -eq 0 -or $tabNumber -eq 1 -or $tabNumber -eq 5) { $sync.SearchBar.Visibility = "Visible" $searchIcon = ($sync.Form.FindName("SearchBar").Parent.Children | Where-Object { $_ -is [System.Windows.Controls.TextBlock] -and $_.Text -eq [char]0xE721 })[0] if ($searchIcon) { $searchIcon.Visibility = "Visible" } } else { $sync.SearchBar.Visibility = "Collapsed" $searchIcon = ($sync.Form.FindName("SearchBar").Parent.Children | Where-Object { $_ -is [System.Windows.Controls.TextBlock] -and $_.Text -eq [char]0xE721 })[0] if ($searchIcon) { $searchIcon.Visibility = "Collapsed" } # Hide the clear button if it's visible $sync.SearchBarClearButton.Visibility = "Collapsed" } } function Invoke-WPFToggleAllCategories { <# .SYNOPSIS Expands or collapses all categories in the Install tab .PARAMETER Action The action to perform: "Expand" or "Collapse" .DESCRIPTION This function iterates through all category containers in the Install tab and expands or collapses their WrapPanels while updating the toggle button labels #> param( [Parameter(Mandatory=$true)] [ValidateSet("Expand", "Collapse")] [string]$Action ) try { if ($null -eq $sync.ItemsControl) { Write-Warning "ItemsControl not initialized" return } $targetVisibility = if ($Action -eq "Expand") { [Windows.Visibility]::Visible } else { [Windows.Visibility]::Collapsed } $targetPrefix = if ($Action -eq "Expand") { "-" } else { "+" } $sourcePrefix = if ($Action -eq "Expand") { "+" } else { "-" } # Iterate through all items in the ItemsControl $sync.ItemsControl.Items | ForEach-Object { $categoryContainer = $_ # Check if this is a category container (StackPanel with children) if ($categoryContainer -is [System.Windows.Controls.StackPanel] -and $categoryContainer.Children.Count -ge 2) { # Get the WrapPanel (second child) $wrapPanel = $categoryContainer.Children[1] $wrapPanel.Visibility = $targetVisibility # Update the label to show the correct state $categoryLabel = $categoryContainer.Children[0] if ($categoryLabel.Content -like "$sourcePrefix*") { $escapedSourcePrefix = [regex]::Escape($sourcePrefix) $categoryLabel.Content = $categoryLabel.Content -replace "^$escapedSourcePrefix ", "$targetPrefix " } } } } catch { Write-Error "Error toggling categories: $_" } } function Invoke-WPFtweaksbutton { <# .SYNOPSIS Invokes the functions associated with each group of checkboxes #> if($sync.ProcessRunning) { $msg = "[Invoke-WPFtweaksbutton] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } $Tweaks = $sync.selectedTweaks $dnsProvider = $sync["WPFchangedns"].text if (-not ($dnsProvider)) { $dnsProvider = "Default" } $restorePointTweak = "WPFTweaksRestorePoint" $restorePointSelected = $Tweaks -contains $restorePointTweak $tweaksToRun = @($Tweaks | Where-Object { $_ -ne $restorePointTweak }) $totalSteps = [Math]::Max($Tweaks.Count, 1) $completedSteps = 0 Write-WinUtilLog -Component "Tweaks" -Message "Tweaks requested: $(@($Tweaks).Count) selected tweak(s), DNS provider: $dnsProvider" if ($tweaks.count -eq 0 -and $dnsProvider -eq "Default") { $msg = "Please check the tweaks you wish to perform." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } if ($restorePointSelected) { $sync.ProcessRunning = $true if ($Tweaks.Count -eq 1) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" } } else { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" } } Set-WinUtilProgressBar -Label "Creating restore point" -Percent 0 Write-WinUtilLog -Component "Tweaks" -Message "Creating restore point before applying selected tweaks." Invoke-WinUtilTweaks $restorePointTweak $completedSteps = 1 if ($tweaksToRun.Count -eq 0 -and $dnsProvider -eq "Default") { Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100 $sync.ProcessRunning = $false Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } Write-Host "=================================" Write-Host "-- Tweaks are Finished ---" Write-Host "=================================" Write-WinUtilLog -Component "Tweaks" -Message "Tweaks workflow completed after restore point." return } } # The leading "," in the ParameterList is necessary because we only provide one argument and powershell cannot be convinced that we want a nested loop with only one argument otherwise Invoke-WPFRunspace -ParameterList @(("tweaks", $tweaksToRun), ("dnsProvider", $dnsProvider), ("completedSteps", $completedSteps), ("totalSteps", $totalSteps)) -ScriptBlock { param($tweaks, $dnsProvider, $completedSteps, $totalSteps) $sync.ProcessRunning = $true if ($completedSteps -eq 0) { if ($Tweaks.count -eq 1) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" } } else { Invoke-WPFUIThread -ScriptBlock{ Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" } } } if ($dnsProvider -ne "Default") { Set-WinUtilDNS -DNSProvider $dnsProvider } for ($i = 0; $i -lt $tweaks.Count; $i++) { Set-WinUtilProgressBar -Label "Applying $($tweaks[$i])" -Percent ($completedSteps / $totalSteps * 100) Invoke-WinUtilTweaks $tweaks[$i] $completedSteps++ $progress = $completedSteps / $totalSteps Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value $progress } } Set-WinUtilProgressBar -Label "Tweaks finished" -Percent 100 $sync.ProcessRunning = $false Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } Write-Host "=================================" Write-Host "-- Tweaks are Finished ---" Write-Host "=================================" Write-WinUtilLog -Component "Tweaks" -Message "Tweaks workflow completed." } } function Invoke-WPFUIElements { <# .SYNOPSIS Adds UI elements to a specified Grid in the WinUtil GUI based on a JSON configuration. .PARAMETER configVariable The variable/link containing the JSON configuration. .PARAMETER targetGridName The name of the grid to which the UI elements should be added. .PARAMETER columncount The number of columns to be used in the Grid. If not provided, a default value is used based on the panel. .EXAMPLE Invoke-WPFUIElements -configVariable $sync.configs.applications -targetGridName "install" -columncount 5 .NOTES Future me/contributor: If possible, please wrap this into a runspace to make it load all panels at the same time. #> param( [Parameter(Mandatory, Position = 0)] [PSCustomObject]$configVariable, [Parameter(Mandatory, Position = 1)] [string]$targetGridName, [Parameter(Mandatory, Position = 2)] [int]$columncount ) $window = $sync.form $borderstyle = $window.FindResource("BorderStyle") $HoverTextBlockStyle = $window.FindResource("HoverTextBlockStyle") $ColorfulToggleSwitchStyle = $window.FindResource("ColorfulToggleSwitchStyle") $ToggleButtonStyle = $window.FindResource("ToggleButtonStyle") if (!$borderstyle -or !$HoverTextBlockStyle -or !$ColorfulToggleSwitchStyle) { throw "Failed to retrieve Styles using 'FindResource' from main window element." } $targetGrid = $window.FindName($targetGridName) if (!$targetGrid) { throw "Failed to retrieve Target Grid by name, provided name: $targetGrid" } # Clear existing ColumnDefinitions and Children $targetGrid.ColumnDefinitions.Clear() | Out-Null $targetGrid.Children.Clear() | Out-Null # Add ColumnDefinitions to the target Grid for ($i = 0; $i -lt $columncount; $i++) { $colDef = New-Object Windows.Controls.ColumnDefinition $colDef.Width = New-Object Windows.GridLength(1, [Windows.GridUnitType]::Star) $targetGrid.ColumnDefinitions.Add($colDef) | Out-Null } # Convert PSCustomObject to Hashtable $configHashtable = @{} $configVariable.PSObject.Properties.Name | ForEach-Object { $configHashtable[$_] = $configVariable.$_ } $radioButtonGroups = @{} $organizedData = @{} # Iterate through JSON data and organize by panel and category foreach ($entry in $configHashtable.Keys) { $entryInfo = $configHashtable[$entry] # Create an object for the application $entryObject = [PSCustomObject]@{ Name = $entry Category = $entryInfo.Category Content = $entryInfo.Content Panel = if ($entryInfo.Panel) { $entryInfo.Panel } else { "0" } Link = $entryInfo.link Description = $entryInfo.description Type = $entryInfo.type ComboItems = $entryInfo.ComboItems Checked = $entryInfo.Checked ButtonWidth = $entryInfo.ButtonWidth GroupName = $entryInfo.GroupName # Added for RadioButton groupings } if (-not $organizedData.ContainsKey($entryObject.Panel)) { $organizedData[$entryObject.Panel] = @{} } if (-not $organizedData[$entryObject.Panel].ContainsKey($entryObject.Category)) { $organizedData[$entryObject.Panel][$entryObject.Category] = @() } # Store application data in an array under the category $organizedData[$entryObject.Panel][$entryObject.Category] += $entryObject } # Initialize panel count $panelcount = 0 # Iterate through 'organizedData' by panel, category, and application $count = 0 foreach ($panelKey in ($organizedData.Keys | Sort-Object)) { # Create a Border for each column $border = New-Object Windows.Controls.Border $border.VerticalAlignment = "Stretch" [System.Windows.Controls.Grid]::SetColumn($border, $panelcount) $border.style = $borderstyle $targetGrid.Children.Add($border) | Out-Null # Use a DockPanel to contain the content $dockPanelContainer = New-Object Windows.Controls.DockPanel $border.Child = $dockPanelContainer # Create an ItemsControl for application content $itemsControl = New-Object Windows.Controls.ItemsControl $itemsControl.HorizontalAlignment = 'Stretch' $itemsControl.VerticalAlignment = 'Stretch' # Set the ItemsPanel to a VirtualizingStackPanel $itemsPanelTemplate = New-Object Windows.Controls.ItemsPanelTemplate $factory = New-Object Windows.FrameworkElementFactory ([Windows.Controls.VirtualizingStackPanel]) $itemsPanelTemplate.VisualTree = $factory $itemsControl.ItemsPanel = $itemsPanelTemplate # Set virtualization properties $itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::IsVirtualizingProperty, $true) $itemsControl.SetValue([Windows.Controls.VirtualizingStackPanel]::VirtualizationModeProperty, [Windows.Controls.VirtualizationMode]::Recycling) # Add the ItemsControl directly to the DockPanel [Windows.Controls.DockPanel]::SetDock($itemsControl, [Windows.Controls.Dock]::Bottom) $dockPanelContainer.Children.Add($itemsControl) | Out-Null $panelcount++ # Now proceed with adding category labels and entries to $itemsControl foreach ($category in ($organizedData[$panelKey].Keys | Sort-Object)) { $count++ $label = New-Object Windows.Controls.Label $label.Content = $category -replace ".*__", "" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "HeaderFontSize") $label.SetResourceReference([Windows.Controls.Control]::FontFamilyProperty, "HeaderFontFamily") $label.UseLayoutRounding = $true $itemsControl.Items.Add($label) | Out-Null $sync[$category] = $label # Sort entries by type (checkboxes first, then buttons, then comboboxes) and then alphabetically by Content $entries = $organizedData[$panelKey][$category] | Sort-Object @{Expression = { switch ($_.Type) { 'Button' { 1 } 'Combobox' { 2 } default { 0 } } }}, Content foreach ($entryInfo in $entries) { $count++ # Create the UI elements based on the entry type switch ($entryInfo.Type) { "Toggle" { $dockPanel = New-Object Windows.Controls.DockPanel [System.Windows.Automation.AutomationProperties]::SetName($dockPanel, $entryInfo.Content) $checkBox = New-Object Windows.Controls.CheckBox $checkBox.Name = $entryInfo.Name $checkBox.HorizontalAlignment = "Right" $checkBox.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($checkBox, $entryInfo.Content) $dockPanel.Children.Add($checkBox) | Out-Null $checkBox.Style = $ColorfulToggleSwitchStyle $label = New-Object Windows.Controls.Label $label.Content = $entryInfo.Content $label.ToolTip = $entryInfo.Description $label.HorizontalAlignment = "Left" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $label.SetResourceReference([Windows.Controls.Control]::ForegroundProperty, "MainForegroundColor") $label.UseLayoutRounding = $true $dockPanel.Children.Add($label) | Out-Null $itemsControl.Items.Add($dockPanel) | Out-Null $sync[$entryInfo.Name] = $checkBox $sync[$entryInfo.Name].IsChecked = (Get-WinUtilToggleStatus $entryInfo.Name) $sync[$entryInfo.Name].Add_Checked({ [System.Object]$Sender = $args[0] Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name # Skip applying tweaks while an import is restoring toggle states if (-not $sync.ImportInProgress) { Invoke-WinUtilTweaks $Sender.name } }) $sync[$entryInfo.Name].Add_Unchecked({ [System.Object]$Sender = $args[0] Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkboxName $Sender.name # Skip undoing tweaks while an import is restoring toggle states if (-not $sync.ImportInProgress) { Invoke-WinUtiltweaks $Sender.name -undo $true } }) } "ToggleButton" { $toggleButton = New-Object Windows.Controls.Primitives.ToggleButton $toggleButton.Name = $entryInfo.Name $toggleButton.Content = $entryInfo.Content[1] $toggleButton.ToolTip = $entryInfo.Description $toggleButton.HorizontalAlignment = "Left" $toggleButton.Style = $ToggleButtonStyle [System.Windows.Automation.AutomationProperties]::SetName($toggleButton, $entryInfo.Content[0]) $toggleButton.Tag = @{ contentOn = if ($entryInfo.Content.Count -ge 1) { $entryInfo.Content[0] } else { "" } contentOff = if ($entryInfo.Content.Count -ge 2) { $entryInfo.Content[1] } else { $contentOn } } $itemsControl.Items.Add($toggleButton) | Out-Null $sync[$entryInfo.Name] = $toggleButton $sync[$entryInfo.Name].Add_Checked({ $this.Content = $this.Tag.contentOn }) $sync[$entryInfo.Name].Add_Unchecked({ $this.Content = $this.Tag.contentOff }) if ($null -eq $sync.Buttons) { $sync.Buttons = [System.Collections.Generic.List[PSObject]]::new() } if ($sync.Buttons -notcontains $toggleButton.Name) { $toggleButton.Add_Click({ [System.Object]$Sender = $args[0] Invoke-WPFButton $Sender.name }) $sync.Buttons.Add($toggleButton.Name) | Out-Null } } "Combobox" { $horizontalStackPanel = New-Object Windows.Controls.StackPanel $horizontalStackPanel.Orientation = "Horizontal" $horizontalStackPanel.Margin = "0,5,0,0" [System.Windows.Automation.AutomationProperties]::SetName($horizontalStackPanel, $entryInfo.Content) $label = New-Object Windows.Controls.Label $label.Content = $entryInfo.Content $label.HorizontalAlignment = "Left" $label.VerticalAlignment = "Center" $label.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") $label.UseLayoutRounding = $true $horizontalStackPanel.Children.Add($label) | Out-Null $comboBox = New-Object Windows.Controls.ComboBox $comboBox.Name = $entryInfo.Name $comboBox.SetResourceReference([Windows.Controls.Control]::HeightProperty, "ButtonHeight") $comboBox.SetResourceReference([Windows.Controls.Control]::WidthProperty, "ButtonWidth") $comboBox.HorizontalAlignment = "Left" $comboBox.VerticalAlignment = "Center" $comboBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin") $comboBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") $comboBox.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($comboBox, $entryInfo.Content) foreach ($comboitem in ($entryInfo.ComboItems -split " ")) { $comboBoxItem = New-Object Windows.Controls.ComboBoxItem $comboBoxItem.Content = $comboitem $comboBoxItem.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") $comboBoxItem.UseLayoutRounding = $true $comboBox.Items.Add($comboBoxItem) | Out-Null } $horizontalStackPanel.Children.Add($comboBox) | Out-Null $itemsControl.Items.Add($horizontalStackPanel) | Out-Null $comboBox.SelectedIndex = 0 # Set initial text if ($comboBox.Items.Count -gt 0) { $comboBox.Text = $comboBox.Items[0].Content } # Add SelectionChanged event handler to update the text property $comboBox.Add_SelectionChanged({ $selectedItem = $this.SelectedItem if ($selectedItem) { $this.Text = $selectedItem.Content } }) $sync[$entryInfo.Name] = $comboBox } "Button" { $button = New-Object Windows.Controls.Button $button.Name = $entryInfo.Name $button.Content = $entryInfo.Content $button.HorizontalAlignment = "Left" $button.SetResourceReference([Windows.Controls.Control]::MarginProperty, "ButtonMargin") $button.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") if ($entryInfo.ButtonWidth) { $baseWidth = [int]$entryInfo.ButtonWidth $button.Width = [math]::Max($baseWidth, 350) } [System.Windows.Automation.AutomationProperties]::SetName($button, $entryInfo.Content) $itemsControl.Items.Add($button) | Out-Null $sync[$entryInfo.Name] = $button if ($null -eq $sync.Buttons) { $sync.Buttons = [System.Collections.Generic.List[PSObject]]::new() } if ($sync.Buttons -notcontains $button.Name) { $button.Add_Click({ [System.Object]$Sender = $args[0] Invoke-WPFButton $Sender.name }) $sync.Buttons.Add($button.Name) | Out-Null } } "RadioButton" { # Check if a container for this GroupName already exists if (-not $radioButtonGroups.ContainsKey($entryInfo.GroupName)) { # Create a StackPanel for this group $groupStackPanel = New-Object Windows.Controls.StackPanel $groupStackPanel.Orientation = "Vertical" [System.Windows.Automation.AutomationProperties]::SetName($groupStackPanel, $entryInfo.GroupName) # Add the group container to the ItemsControl $itemsControl.Items.Add($groupStackPanel) | Out-Null } else { # Retrieve the existing group container $groupStackPanel = $radioButtonGroups[$entryInfo.GroupName] } # Create the RadioButton $radioButton = New-Object Windows.Controls.RadioButton $radioButton.Name = $entryInfo.Name $radioButton.GroupName = $entryInfo.GroupName $radioButton.Content = $entryInfo.Content $radioButton.HorizontalAlignment = "Left" $radioButton.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin") $radioButton.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "ButtonFontSize") $radioButton.ToolTip = $entryInfo.Description $radioButton.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($radioButton, $entryInfo.Content) if ($entryInfo.Checked -eq $true) { $radioButton.IsChecked = $true } # Add the RadioButton to the group container $groupStackPanel.Children.Add($radioButton) | Out-Null $sync[$entryInfo.Name] = $radioButton } "Note" { $textBlock = New-Object Windows.Controls.TextBlock $textBlock.TextWrapping = "Wrap" $textBlock.Margin = "5,5,5,5" $textBlock.UseLayoutRounding = $true $bulletRun = New-Object Windows.Documents.Run $bulletRun.Text = [char]0x25CF $bulletRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(110, 255, 114)) $bulletRun.FontSize = 11.5 $textRun = New-Object Windows.Documents.Run $textRun.Text = " $($entryInfo.Content)" $textRun.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $textRun.Foreground = [Windows.Media.SolidColorBrush]::new([Windows.Media.Color]::FromRgb(19, 143, 83)) $textBlock.Inlines.Add($bulletRun) $textBlock.Inlines.Add($textRun) $itemsControl.Items.Add($textBlock) | Out-Null } default { $horizontalStackPanel = New-Object Windows.Controls.StackPanel $horizontalStackPanel.Orientation = "Horizontal" [System.Windows.Automation.AutomationProperties]::SetName($horizontalStackPanel, $entryInfo.Content) $checkBox = New-Object Windows.Controls.CheckBox $checkBox.Name = $entryInfo.Name $checkBox.Content = $entryInfo.Content $checkBox.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $checkBox.ToolTip = $entryInfo.Description $checkBox.SetResourceReference([Windows.Controls.Control]::MarginProperty, "CheckBoxMargin") $checkBox.UseLayoutRounding = $true [System.Windows.Automation.AutomationProperties]::SetName($checkBox, $entryInfo.Content) if ($entryInfo.Checked -eq $true) { $checkBox.IsChecked = $entryInfo.Checked } $horizontalStackPanel.Children.Add($checkBox) | Out-Null if ($entryInfo.Link) { $textBlock = New-Object Windows.Controls.TextBlock $textBlock.Name = $checkBox.Name + "Link" $textBlock.Text = "(?)" $textBlock.ToolTip = $entryInfo.Link $textBlock.Style = $HoverTextBlockStyle $textBlock.UseLayoutRounding = $true $textBlock.VerticalAlignment = "Center" $textBlock.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize") $textBlock.Tag = $checkBox $updateLinkMargin = { [System.Object]$Sender = $args[0] $linkedCheckBox = $Sender.Tag $MarginTopBase = if ($linkedCheckBox) { $linkedCheckBox.Margin.Top } else { 0 } $Sender.Margin = New-Object Windows.Thickness( [math]::Round($Sender.FontSize * 0.5), ($MarginTopBase - [math]::Round($Sender.FontSize / 2)), 0, 0 ) } $textBlock.Add_Loaded($updateLinkMargin) $fontSizeDescriptor = [System.ComponentModel.DependencyPropertyDescriptor]::FromProperty( [Windows.Controls.Control]::FontSizeProperty, [Windows.Controls.TextBlock] ) $fontSizeDescriptor.AddValueChanged($textBlock, $updateLinkMargin) $horizontalStackPanel.Children.Add($textBlock) | Out-Null $sync[$textBlock.Name] = $textBlock } $itemsControl.Items.Add($horizontalStackPanel) | Out-Null $sync[$entryInfo.Name] = $checkBox $sync[$entryInfo.Name].Add_Checked({ [System.Object]$Sender = $args[0] Invoke-WPFSelectedCheckboxesUpdate -type "Add" -checkboxName $Sender.name }) $sync[$entryInfo.Name].Add_Unchecked({ [System.Object]$Sender = $args[0] Invoke-WPFSelectedCheckboxesUpdate -type "Remove" -checkbox $Sender.name }) } } } } } } function Invoke-WPFUIThread ($ScriptBlock) { $sync.form.Dispatcher.Invoke([action]$ScriptBlock) } function Invoke-WPFUltimatePerformance ([switch]$Enable) { if ($Enable) { powercfg /setactive (powercfg /duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61 | Select-String -Pattern '[A-Fa-f0-9-]{36}').Matches.Value [System.Windows.MessageBox]::Show("Ultimate Power Plan plan installed and activated.","Success","OK","Information") } else { powercfg /restoredefaultschemes [System.Windows.MessageBox]::Show("Power Plan was reset to defaults.","Success","OK","Information") } } function Invoke-WPFundoall { <# .SYNOPSIS Undoes every selected tweak #> if($sync.ProcessRunning) { $msg = "[Invoke-WPFundoall] Install process is currently running." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } $tweaks = $sync.selectedTweaks if ($tweaks.count -eq 0) { $msg = "Please check the tweaks you wish to undo." [System.Windows.MessageBox]::Show($msg, "Winutil", [System.Windows.MessageBoxButton]::OK, [System.Windows.MessageBoxImage]::Warning) return } Invoke-WPFRunspace -ArgumentList $tweaks -ScriptBlock { param($tweaks) $sync.ProcessRunning = $true Write-WinUtilLog -Component "Tweaks" -Message "Undo tweaks requested: $(@($tweaks).Count) selected tweak(s)." if ($tweaks.count -eq 1) { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Indeterminate" -value 0.01 -overlay "logo" } } else { Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Normal" -value 0.01 -overlay "logo" } } 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 Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -value ($i/$tweaks.Count) } } Set-WinUtilProgressBar -Label "Undo Tweaks Finished" -Percent 100 $sync.ProcessRunning = $false Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } Write-Host "==================================" Write-Host "--- Undo Tweaks are Finished ---" Write-Host "==================================" Write-WinUtilLog -Component "Tweaks" -Message "Undo tweaks workflow completed." } } function Invoke-WPFUnInstall { param( [Parameter(Mandatory=$false)] [PSObject[]]$PackagesToUninstall = $($sync.selectedApps | Foreach-Object { $sync.configs.applicationsHashtable.$_ }) ) <# .SYNOPSIS Uninstalls the selected programs #> if($sync.ProcessRunning) { $msg = "[Invoke-WPFUnInstall] Install process is currently running" Show-WinUtilMessage -Message $msg -Title "Winutil" -Button "OK" -Icon "Warning" return } if ($PackagesToUninstall.Count -eq 0) { $WarningMsg = "Please select the program(s) to uninstall" Show-WinUtilMessage -Message $WarningMsg -Title $AppTitle -Button "OK" -Icon "Warning" return } $ButtonType = "YesNo" $MessageboxTitle = "Are you sure?" $Messageboxbody = ("This will uninstall the following applications: `n $($PackagesToUninstall | Select-Object Name, Description| Out-String)") $MessageIcon = "Information" $confirm = Show-WinUtilMessage -Message $Messageboxbody -Title $MessageboxTitle -Button $ButtonType -Icon $MessageIcon if($confirm -eq "No") {return} $ManagerPreference = $sync.preferences.packagemanager Write-WinUtilLog -Component "Uninstall" -Message "Uninstall requested for $(@($PackagesToUninstall).Count) selected package(s) using preference: $ManagerPreference" $packageSummary = Get-WinUtilPackageLogSummary -Packages $PackagesToUninstall -Preference $ManagerPreference Write-WinUtilLog -Component "Uninstall" -Message "Uninstall selected package(s): $($packageSummary -join '; ')" Invoke-WPFRunspace -ParameterList @(("PackagesToUninstall", $PackagesToUninstall),("ManagerPreference", $ManagerPreference)) -ScriptBlock { param($PackagesToUninstall, $ManagerPreference) $packagesSorted = Get-WinUtilSelectedPackages -PackageList $PackagesToUninstall -Preference $ManagerPreference $packagesWinget = $packagesSorted['Winget'] $packagesChoco = $packagesSorted['Choco'] Write-WinUtilLog -Component "Uninstall" -Message "Uninstall package manager split: winget=$(@($packagesWinget).Count), choco=$(@($packagesChoco).Count)" try { $sync.ProcessRunning = $true Show-WPFInstallAppBusy -text "Uninstalling apps..." if ($packagesWinget -contains "Microsoft.Edge") { New-Item -Path "$Env:SystemRoot\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\MicrosoftEdge.exe" -Force } # Uninstall all selected programs in new window if($packagesWinget.Count -gt 0) { Install-WinUtilProgramWinget -Action Uninstall -Programs $packagesWinget } if($packagesChoco.Count -gt 0) { Install-WinUtilProgramChoco -Action Uninstall -Programs $packagesChoco } Hide-WPFInstallAppBusy Write-Host "===========================================" Write-Host "-- Uninstalls have finished ---" Write-Host "===========================================" Write-WinUtilLog -Component "Uninstall" -Message "Uninstall workflow completed." Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "None" -overlay "checkmark" } } catch { Hide-WPFInstallAppBusy Write-Host "===========================================" Write-Host "Error: $_" Write-Host "===========================================" Write-WinUtilLog -Level "ERROR" -Component "Uninstall" -Message "Uninstall workflow failed: $($_.Exception.Message)" Invoke-WPFUIThread -ScriptBlock { Set-WinUtilTaskbaritem -state "Error" -overlay "warning" } } finally { $sync.ProcessRunning = $False } } } function Invoke-WPFUpdatesdefault { <# .SYNOPSIS Resets Windows Update settings to default #> $ErrorActionPreference = 'SilentlyContinue' Write-WinUtilLog -Component "Updates" -Message "Resetting Windows Update settings to default." Write-Host "Removing Windows Update policy settings..." -ForegroundColor Green Write-WinUtilLog -Component "Updates" -Message "Removing Windows Update policy registry paths." Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Recurse -Force Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization" -Recurse -Force Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Recurse -Force Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Recurse -Force Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Recurse -Force Remove-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Recurse -Force Write-Host "Showing Windows Updates in settings..." Write-WinUtilLog -Component "Updates" -Message "Showing Windows Update settings page." Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name SettingsPageVisibility Write-Host "Reenabling Windows Update Services..." -ForegroundColor Green Write-WinUtilLog -Component "Updates" -Message "Restoring Windows Update service startup types." Write-Host "Restored BITS to Manual." Write-WinUtilLog -Component "Updates" -Message "Restoring BITS service to Manual." Set-Service -Name BITS -StartupType Manual Write-Host "Restored wuauserv to Manual." Write-WinUtilLog -Component "Updates" -Message "Restoring wuauserv service to Manual." Set-Service -Name wuauserv -StartupType Manual Write-Host "Restored UsoSvc to Automatic." Write-WinUtilLog -Component "Updates" -Message "Starting UsoSvc service and restoring startup type to Automatic." Start-Service -Name UsoSvc Set-Service -Name UsoSvc -StartupType Automatic Write-Host "Restored WaaSMedicSvc to Manual." Write-WinUtilLog -Component "Updates" -Message "Restoring WaaSMedicSvc service to Manual." Set-Service -Name WaaSMedicSvc -StartupType Manual Write-Host "Enabling update related scheduled tasks..." -ForegroundColor Green Write-WinUtilLog -Component "Updates" -Message "Enabling update related scheduled tasks." $Tasks = '\Microsoft\Windows\InstallService\*', '\Microsoft\Windows\UpdateOrchestrator\*', '\Microsoft\Windows\UpdateAssistant\*', '\Microsoft\Windows\WaaSMedic\*', '\Microsoft\Windows\WindowsUpdate\*', '\Microsoft\WindowsUpdate\*' foreach ($Task in $Tasks) { Get-ScheduledTask -TaskPath $Task | Enable-ScheduledTask -ErrorAction SilentlyContinue } Write-Host "Windows Local Policies Reset to Default." Write-WinUtilLog -Component "Updates" -Message "Resetting local security policy to defaults with secedit." secedit /configure /cfg "$Env:SystemRoot\inf\defltbase.inf" /db defltbase.sdb Write-Host "===================================================" -ForegroundColor Green Write-Host "--- Windows Update Settings Reset to Default ---" -ForegroundColor Green Write-Host "===================================================" -ForegroundColor Green Write-Host "Note: You must restart your system in order for all changes to take effect." -ForegroundColor Yellow Write-WinUtilLog -Component "Updates" -Message "Windows Update default workflow completed. Restart required." } function Invoke-WPFUpdatesdisable { <# .SYNOPSIS Disables Windows Update .NOTES Disabling Windows Update is not recommended. This is only for advanced users who know what they are doing. #> $ErrorActionPreference = 'SilentlyContinue' Write-WinUtilLog -Component "Updates" -Message "Disabling Windows Update settings." Write-Host "Configuring registry settings..." -ForegroundColor Yellow Write-WinUtilLog -Component "Updates" -Message "Configuring Windows Update registry policy values for disable mode." New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoUpdate" -Type DWord -Value 1 Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "AUOptions" -Type DWord -Value 1 New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Name "DODownloadMode" -Type DWord -Value 0 Write-Host "Hiding Windows Updates from settings..." Write-WinUtilLog -Component "Updates" -Message "Hiding Windows Update settings page." Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer -Name SettingsPageVisibility -Value hide:windowsupdate Write-Host "Disabled BITS Service." Write-WinUtilLog -Component "Updates" -Message "Disabling BITS service." Set-Service -Name BITS -StartupType Disabled Write-Host "Disabled wuauserv Service." Write-WinUtilLog -Component "Updates" -Message "Disabling wuauserv service." Set-Service -Name wuauserv -StartupType Disabled Write-Host "Disabled UsoSvc Service." Write-WinUtilLog -Component "Updates" -Message "Stopping and disabling UsoSvc service." Stop-Service -Name UsoSvc -Force Set-Service -Name UsoSvc -StartupType Disabled Remove-Item "C:\Windows\SoftwareDistribution\*" -Recurse -Force Write-Host "Cleared SoftwareDistribution folder." Write-WinUtilLog -Component "Updates" -Message "Cleared SoftwareDistribution folder." Write-Host "Disabling update related scheduled tasks..." -ForegroundColor Yellow Write-WinUtilLog -Component "Updates" -Message "Disabling update related scheduled tasks." $Tasks = '\Microsoft\Windows\InstallService\*', '\Microsoft\Windows\UpdateOrchestrator\*', '\Microsoft\Windows\UpdateAssistant\*', '\Microsoft\Windows\WaaSMedic\*', '\Microsoft\Windows\WindowsUpdate\*', '\Microsoft\WindowsUpdate\*' foreach ($Task in $Tasks) { Get-ScheduledTask -TaskPath $Task | Disable-ScheduledTask -ErrorAction SilentlyContinue } Write-Host "=================================" -ForegroundColor Green Write-Host "--- Updates Are Disabled ---" -ForegroundColor Green Write-Host "=================================" -ForegroundColor Green Write-Host "Note: You must restart your system in order for all changes to take effect." -ForegroundColor Yellow Write-WinUtilLog -Component "Updates" -Message "Windows Update disable workflow completed. Restart required." } function Invoke-WPFUpdatessecurity { <# .SYNOPSIS Sets Windows Update to recommended settings .DESCRIPTION 1. Disables driver offering through Windows Update 2. Disables Windows Update automatic restart 3. Sets Windows Update to Semi-Annual Channel (Targeted) 4. Defers feature updates for 365 days 5. Defers quality updates for 4 days #> Write-Host "Disabling driver offering through Windows Update..." Write-WinUtilLog -Component "Updates" -Message "Applying recommended Windows Update settings." Write-WinUtilLog -Component "Updates" -Message "Disabling driver offering through Windows Update." New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata" -Name "PreventDeviceMetadataFromNetwork" -Type DWord -Value 1 New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontPromptForWindowsUpdate" -Type DWord -Value 1 Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DontSearchWindowsUpdate" -Type DWord -Value 1 Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching" -Name "DriverUpdateWizardWuSearchEnabled" -Type DWord -Value 0 New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -Name "ExcludeWUDriversInQualityUpdate" -Type DWord -Value 1 Write-Host "Setting cumulative updates back by 1 year and security updates by 4 days..." Write-WinUtilLog -Component "Updates" -Message "Deferring feature updates by 365 days and quality updates by 4 days." New-Item -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "BranchReadinessLevel" -Type DWord -Value 20 Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "DeferFeatureUpdatesPeriodInDays" -Type DWord -Value 365 Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -Name "DeferQualityUpdatesPeriodInDays" -Type DWord -Value 4 Write-Host "Disabling Windows Update automatic restart..." Write-WinUtilLog -Component "Updates" -Message "Disabling Windows Update automatic restart while users are logged in." New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoRebootWithLoggedOnUsers" -Type DWord -Value 1 Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "AUPowerManagement" -Type DWord -Value 0 Write-Host "=================================" Write-Host "-- Updates Set to Recommended ---" Write-Host "=================================" Write-WinUtilLog -Component "Updates" -Message "Recommended Windows Update settings workflow completed." } $sync.configs.applications = @' { "WPFInstall1password": { "category": "Utilities", "choco": "1password", "content": "1Password", "description": "1Password is a password manager that allows you to store and manage your passwords securely.", "link": "https://1password.com/", "winget": "AgileBits.1Password", "foss": false }, "WPFInstall7zip": { "category": "Utilities", "choco": "7zip", "content": "7-Zip", "description": "7-Zip is a free and open-source file archiver utility. It supports several compression formats and provides a high compression ratio, making it a popular choice for file compression.", "link": "https://www.7-zip.org/", "winget": "7zip.7zip", "foss": true }, "WPFInstalladobe": { "category": "Multimedia Tools", "choco": "adobereader", "content": "Adobe Acrobat Reader", "description": "Adobe Acrobat Reader is a free PDF viewer with essential features for viewing, printing, and annotating PDF documents.", "link": "https://www.adobe.com/acrobat/pdf-reader.html", "winget": "Adobe.Acrobat.Reader.64-bit", "foss": false }, "WPFInstalladvancedip": { "category": "Pro Tools", "choco": "advanced-ip-scanner", "content": "Advanced IP Scanner", "description": "Advanced IP Scanner is a fast and easy-to-use network scanner. It is designed to analyze LAN networks and provides information about connected devices.", "link": "https://www.advanced-ip-scanner.com/", "winget": "Famatech.AdvancedIPScanner", "foss": false }, "WPFInstallaimp": { "category": "Multimedia Tools", "choco": "aimp", "content": "AIMP (Music Player)", "description": "AIMP is a feature-rich music player with support for various audio formats, playlists, and customizable user interface.", "link": "https://www.aimp.ru/", "winget": "AIMP.AIMP", "foss": false }, "WPFInstallangryipscanner": { "category": "Pro Tools", "choco": "angryip", "content": "Angry IP Scanner", "description": "Angry IP Scanner is an open-source and cross-platform network scanner. It is used to scan IP addresses and ports, providing information about network connectivity.", "link": "https://angryip.org/", "winget": "angryziber.AngryIPScanner", "foss": true }, "WPFInstallanydesk": { "category": "Utilities", "choco": "anydesk", "content": "AnyDesk", "description": "AnyDesk is a remote desktop software that enables users to access and control computers remotely. It is known for its fast connection and low latency.", "link": "https://anydesk.com/", "winget": "AnyDesk.AnyDesk", "foss": false }, "WPFInstallaudacity": { "category": "Multimedia Tools", "choco": "audacity", "content": "Audacity", "description": "Audacity is a free and open-source audio editing software known for its powerful recording and editing capabilities.", "link": "https://www.audacityteam.org/", "winget": "Audacity.Audacity", "foss": true }, "WPFInstallautoruns": { "category": "Microsoft Tools", "choco": "autoruns", "content": "Autoruns", "description": "This utility shows you what programs are configured to run during system bootup or login.", "link": "https://learn.microsoft.com/en-us/sysinternals/downloads/autoruns", "winget": "Microsoft.Sysinternals.Autoruns", "foss": false }, "WPFInstallrdcman": { "category": "Microsoft Tools", "choco": "rdcman", "content": "RDCMan", "description": "RDCMan manages multiple remote desktop connections. It is useful for managing server labs where you need regular access to each machine such as automated checkin systems and data centers.", "link": "https://learn.microsoft.com/en-us/sysinternals/downloads/rdcman", "winget": "Microsoft.Sysinternals.RDCMan", "foss": false }, "WPFInstallautohotkey": { "category": "Utilities", "choco": "autohotkey", "content": "AutoHotkey", "description": "AutoHotkey is a scripting language for Windows that allows users to create custom automation scripts and macros. It is often used for automating repetitive tasks and customizing keyboard shortcuts.", "link": "https://www.autohotkey.com/", "winget": "AutoHotkey.AutoHotkey", "foss": true }, "WPFInstallbitwarden": { "category": "Utilities", "choco": "bitwarden", "content": "Bitwarden", "description": "Bitwarden is an open-source password management solution. It allows users to store and manage their passwords in a secure and encrypted vault, accessible across multiple devices.", "link": "https://bitwarden.com/", "winget": "Bitwarden.Bitwarden", "foss": true }, "WPFInstallblender": { "category": "Multimedia Tools", "choco": "blender", "content": "Blender (3D Graphics)", "description": "Blender is a powerful open-source 3D creation suite, offering modeling, sculpting, animation, and rendering tools.", "link": "https://www.blender.org/", "winget": "BlenderFoundation.Blender", "foss": true }, "WPFInstallbrave": { "category": "Browsers", "choco": "brave", "content": "Brave", "description": "Brave is a privacy-focused web browser that blocks ads and trackers, offering a faster and safer browsing experience.", "link": "https://www.brave.com", "winget": "Brave.Brave", "foss": true }, "WPFInstallbulkcrapuninstaller": { "category": "Utilities", "choco": "bulk-crap-uninstaller", "content": "Bulk Crap Uninstaller", "description": "Bulk Crap Uninstaller is a free and open-source uninstaller utility for Windows. It helps users remove unwanted programs and clean up their system by uninstalling multiple applications at once.", "link": "https://www.bcuninstaller.com/", "winget": "Klocman.BulkCrapUninstaller", "foss": true }, "WPFInstallblurautoclicker": { "category": "Utilities", "choco": "na", "content": "BlurAutoClicker", "description": "An Auto-clicker with a few advanced features and generally better performance than popular alternatives.", "link": "https://blur009.vercel.app/projects/blur-autoclicker/", "winget": "Blur009.BlurAutoClicker", "foss": true }, "WPFInstallcalibre": { "category": "Multimedia Tools", "choco": "calibre", "content": "Calibre", "description": "Calibre is a powerful and easy-to-use e-book manager, viewer, and converter.", "link": "https://calibre-ebook.com/", "winget": "calibre.calibre", "foss": true }, "WPFInstallcemu": { "category": "Games", "choco": "cemu", "content": "Cemu", "description": "Cemu is a highly experimental software to emulate Wii U applications on PC.", "link": "https://cemu.info/", "winget": "Cemu.Cemu", "foss": true }, "WPFInstallchatgpt": { "category": "Development", "choco": "na", "content": "ChatGPT Desktop", "description": "The official ChatGPT desktop app for Windows, distributed through the Microsoft Store.", "link": "https://apps.microsoft.com/detail/9nt1r1c2hh7j", "winget": "msstore:9NT1R1C2HH7J", "foss": false }, "WPFInstallchatterino": { "category": "Communications", "choco": "chatterino", "content": "Chatterino", "description": "Chatterino is a chat client for Twitch chat that offers a clean and customizable interface for a better streaming experience.", "link": "https://www.chatterino.com/", "winget": "ChatterinoTeam.Chatterino", "foss": true }, "WPFInstallchrome": { "category": "Browsers", "choco": "googlechrome", "content": "Chrome", "description": "Google Chrome is a widely used web browser known for its speed, simplicity, and seamless integration with Google services.", "link": "https://www.google.com/chrome/", "winget": "Google.Chrome", "foss": false }, "WPFInstallchromium": { "category": "Browsers", "choco": "chromium", "content": "Chromium", "description": "Chromium is the open-source project that serves as the foundation for various web browsers, including Chrome.", "link": "https://github.com/Hibbiki/chromium-win64", "winget": "Hibbiki.Chromium", "foss": true }, "WPFInstallcinebenchr23": { "category": "Pro Tools", "choco": "na", "content": "Cinebench R23", "description": "Cinebench R23 is a benchmark tool for comparing CPU rendering performance across systems.", "link": "https://www.maxon.net/en/cinebench", "winget": "Maxon.CinebenchR23", "foss": false }, "WPFInstallclaude": { "category": "Development", "choco": "claude", "content": "Claude Desktop", "description": "Anthropic\u0027s Claude desktop application for focused AI-assisted work and chat.", "link": "https://claude.ai/download", "winget": "Anthropic.Claude", "foss": false }, "WPFInstallclaude-code": { "category": "Development", "choco": "claude-code", "content": "Claude Code", "description": "Anthropic\u0027s agentic coding tool for terminal and IDE development workflows.", "link": "https://code.claude.com/", "winget": "Anthropic.ClaudeCode", "foss": false }, "WPFInstallcmake": { "category": "Development", "choco": "cmake", "content": "CMake", "description": "CMake is an open-source, cross-platform family of tools designed to build, test and package software.", "link": "https://cmake.org/", "winget": "Kitware.CMake", "foss": true }, "WPFInstallcodex": { "category": "Development", "choco": "codex", "content": "Codex", "description": "Codex CLI is an OpenAI coding agent that runs locally in your terminal.", "link": "https://developers.openai.com/codex/cli", "winget": "OpenAI.Codex", "foss": true }, "WPFInstallcpuz": { "category": "Pro Tools", "choco": "cpu-z", "content": "CPU-Z", "description": "CPU-Z is a system monitoring and diagnostic tool for Windows. It provides detailed information about the computer\u0027s hardware components, including the CPU, memory, and motherboard.", "link": "https://www.cpuid.com/softwares/cpu-z.html", "winget": "CPUID.CPU-Z", "foss": false }, "WPFInstallcrystaldiskinfo": { "category": "Utilities", "choco": "crystaldiskinfo", "content": "Crystal Disk Info", "description": "Crystal Disk Info is a disk health monitoring tool that provides information about the status and performance of hard drives. It helps users anticipate potential issues and monitor drive health.", "link": "https://crystalmark.info/en/software/crystaldiskinfo/", "winget": "CrystalDewWorld.CrystalDiskInfo", "foss": true }, "WPFInstallcrystaldiskmark": { "category": "Utilities", "choco": "crystaldiskmark", "content": "Crystal Disk Mark", "description": "Crystal Disk Mark is a disk benchmarking tool that measures the read and write speeds of storage devices. It helps users assess the performance of their hard drives and SSDs.", "link": "https://crystalmark.info/en/software/crystaldiskmark/", "winget": "CrystalDewWorld.CrystalDiskMark", "foss": true }, "WPFInstallcursor": { "category": "Development", "choco": "cursoride", "content": "Cursor", "description": "AI-powered code editor (VS Code-based) with agentic coding features and integrated AI assistance for development workflows.", "link": "https://cursor.com/", "winget": "Anysphere.Cursor", "foss": false }, "WPFInstallddu": { "category": "Pro Tools", "choco": "ddu", "content": "Display Driver Uninstaller", "description": "Display Driver Uninstaller (DDU) is a tool for completely uninstalling graphics drivers from NVIDIA, AMD, and Intel. It is useful for troubleshooting graphics driver-related issues.", "link": "https://www.wagnardsoft.com/display-driver-uninstaller-DDU-", "winget": "Wagnardsoft.DisplayDriverUninstaller", "foss": true }, "WPFInstalldiscord": { "category": "Communications", "choco": "discord", "content": "Discord", "description": "Discord is a popular communication platform with voice, video, and text chat, designed for gamers but used by a wide range of communities.", "link": "https://discord.com/", "winget": "Discord.Discord", "foss": false }, "WPFInstalldismtools": { "category": "Microsoft Tools", "choco": "dismtools", "content": "DISMTools", "description": "DISMTools is a fast, customizable GUI for the DISM utility, supporting Windows images from Windows 7 onward. It handles installations on any drive, offers project support, and lets users tweak settings like color modes, language, and DISM versions; powered by both native DISM and a managed DISM API.", "link": "https://github.com/CodingWonders/DISMTools", "winget": "CodingWondersSoftware.DISMTools.Stable", "foss": true }, "WPFInstallntlite": { "category": "Microsoft Tools", "choco": "ntlite-free", "content": "NTLite", "description": "Integrate updates, drivers, automate Windows and application setup, speedup Windows deployment process and have it all set for the next time.", "link": "https://ntlite.com", "winget": "Nlitesoft.NTLite", "foss": false }, "WPFInstalldorion": { "category": "Communications", "choco": "dorion", "content": "Dorion", "description": "Tiny alternative Discord client with a smaller footprint, snappier startup, themes, plugins and more!", "link": "https://github.com/SpikeHD/Dorion", "winget": "SpikeHD.Dorion", "foss": true }, "WPFInstalldotnet6": { "category": "Microsoft Tools", "choco": "dotnet-6.0-runtime", "content": ".NET Desktop Runtime 6", "description": ".NET Desktop Runtime 6 is a runtime environment required for running applications developed with .NET 6.", "link": "https://dotnet.microsoft.com/download/dotnet/6.0", "winget": "Microsoft.DotNet.DesktopRuntime.6", "foss": true }, "WPFInstalldotnet8": { "category": "Microsoft Tools", "choco": "dotnet-8.0-runtime", "content": ".NET Desktop Runtime 8", "description": ".NET Desktop Runtime 8 is a runtime environment required for running applications developed with .NET 8.", "link": "https://dotnet.microsoft.com/download/dotnet/8.0", "winget": "Microsoft.DotNet.DesktopRuntime.8", "foss": true }, "WPFInstalldotnet9": { "category": "Microsoft Tools", "choco": "dotnet-9.0-runtime", "content": ".NET Desktop Runtime 9", "description": ".NET Desktop Runtime 9 is a runtime environment required for running applications developed with .NET 9.", "link": "https://dotnet.microsoft.com/download/dotnet/9.0", "winget": "Microsoft.DotNet.DesktopRuntime.9", "foss": true }, "WPFInstalldotnet10": { "category": "Microsoft Tools", "choco": "dotnet-10.0-runtime", "content": ".NET Desktop Runtime 10", "description": ".NET Desktop Runtime 10 is a runtime environment required for running applications developed with .NET 10.", "link": "https://dotnet.microsoft.com/download/dotnet/10.0", "winget": "Microsoft.DotNet.DesktopRuntime.10", "foss": true }, "WPFInstalldropbox": { "category": "Utilities", "choco": "dropbox", "content": "Dropbox", "description": "Dropbox is a cloud storage client for syncing files, sharing content, and keeping documents available across devices.", "link": "https://www.dropbox.com/desktop", "winget": "Dropbox.Dropbox", "foss": false }, "WPFInstalleaapp": { "category": "Games", "choco": "ea-app", "content": "EA App", "description": "EA App is a platform for accessing and playing Electronic Arts games.", "link": "https://www.ea.com/ea-app", "winget": "ElectronicArts.EADesktop", "foss": false }, "WPFInstalleartrumpet": { "category": "Multimedia Tools", "choco": "eartrumpet", "content": "EarTrumpet (Audio)", "description": "EarTrumpet is an audio control app for Windows, providing a simple and intuitive interface for managing sound settings.", "link": "https://eartrumpet.app/", "winget": "File-New-Project.EarTrumpet", "foss": true }, "WPFInstalledge": { "category": "Browsers", "choco": "microsoft-edge", "content": "Edge", "description": "Microsoft Edge is a modern web browser built on Chromium, offering performance, security, and integration with Microsoft services.", "link": "https://www.microsoft.com/edge", "winget": "Microsoft.Edge", "foss": false }, "WPFInstallenteauth": { "category": "Utilities", "choco": "ente-auth", "content": "Ente Auth", "description": "Ente Auth is a free, cross-platform, end-to-end encrypted authenticator app.", "link": "https://ente.io/auth/", "winget": "ente-io.auth-desktop", "foss": true }, "WPFInstallepicgames": { "category": "Games", "choco": "epicgameslauncher", "content": "Epic Games Launcher", "description": "Epic Games Launcher is the client for accessing and playing games from the Epic Games Store.", "link": "https://www.epicgames.com/store/en-US/", "winget": "EpicGames.EpicGamesLauncher", "foss": false }, "WPFInstallfiles": { "category": "Utilities", "choco": "files", "content": "Files", "description": "Alternative file explorer.", "link": "https://github.com/files-community/Files", "winget": "FilesCommunity.Files", "foss": true }, "WPFInstallfirefox": { "category": "Browsers", "choco": "firefox", "content": "Firefox", "description": "Mozilla Firefox is an open-source web browser known for its customization options, privacy features, and extensions.", "link": "https://www.mozilla.org/en-US/firefox/new/", "winget": "Mozilla.Firefox", "foss": true }, "WPFInstallfirefoxesr": { "category": "Browsers", "choco": "FirefoxESR", "content": "Firefox ESR", "description": "Mozilla Firefox is an open-source web browser known for its customization options, privacy features, and extensions. Firefox ESR (Extended Support Release) receives major updates every 42 weeks with minor updates such as crash fixes, security fixes and policy updates as needed, but at least every four weeks.", "link": "https://www.mozilla.org/en-US/firefox/enterprise/", "winget": "Mozilla.Firefox.ESR", "foss": true }, "WPFInstallfloorp": { "category": "Browsers", "choco": "floorp", "content": "Floorp", "description": "Floorp is an open-source web browser project that aims to provide a simple and fast browsing experience.", "link": "https://floorp.app/", "winget": "Ablaze.Floorp", "foss": true }, "WPFInstallflux": { "category": "Utilities", "choco": "flux", "content": "F.lux", "description": "f.lux adjusts the color temperature of your screen to reduce eye strain during nighttime use.", "link": "https://justgetflux.com/", "winget": "flux.flux", "foss": false }, "WPFInstallgeforcenow": { "category": "Games", "choco": "nvidia-geforce-now", "content": "GeForce NOW", "description": "GeForce NOW is a cloud gaming service that allows you to play high-quality PC games on your device.", "link": "https://www.nvidia.com/en-us/geforce-now/", "winget": "Nvidia.GeForceNow", "foss": false }, "WPFInstallgimp": { "category": "Multimedia Tools", "choco": "gimp", "content": "GIMP (Image Editor)", "description": "GIMP is a versatile open-source raster graphics editor used for tasks such as photo retouching, image editing, and image composition.", "link": "https://www.gimp.org/", "winget": "GIMP.GIMP.3", "foss": true }, "WPFInstallgit": { "category": "Development", "choco": "git", "content": "Git", "description": "Git is a distributed version control system widely used for tracking changes in source code during software development.", "link": "https://git-scm.com/", "winget": "Git.Git", "foss": true }, "WPFInstallgithubdesktop": { "category": "Development", "choco": "git;github-desktop", "content": "GitHub Desktop", "description": "GitHub Desktop is a visual Git client that simplifies collaboration on GitHub repositories with an easy-to-use interface.", "link": "https://desktop.github.com/", "winget": "GitHub.GitHubDesktop", "foss": true }, "WPFInstallgog": { "category": "Games", "choco": "goggalaxy", "content": "GOG Galaxy", "description": "GOG Galaxy is a gaming client that offers DRM-free games, additional content, and more.", "link": "https://www.gog.com/galaxy", "winget": "GOG.Galaxy", "foss": false }, "WPFInstallgolang": { "category": "Development", "choco": "golang", "content": "Go", "description": "Go (or Golang) is a statically typed, compiled programming language designed for simplicity, reliability, and efficiency.", "link": "https://go.dev/", "winget": "GoLang.Go", "foss": true }, "WPFInstallgoogledrive": { "category": "Utilities", "choco": "googledrive", "content": "Google Drive", "description": "File syncing across devices all tied to your Google account.", "link": "https://www.google.com/drive/", "winget": "Google.GoogleDrive", "foss": false }, "WPFInstallgpuz": { "category": "Pro Tools", "choco": "gpu-z", "content": "GPU-Z", "description": "GPU-Z provides detailed information about your graphics card and GPU.", "link": "https://www.techpowerup.com/gpuz/", "winget": "TechPowerUp.GPU-Z", "foss": false }, "WPFInstallhelium": { "category": "Browsers", "choco": "helium", "content": "Helium", "description": "Private, fast, and honest web browser.", "link": "https://github.com/imputnet/helium/", "winget": "ImputNet.Helium", "foss": true }, "WPFInstallhugo": { "category": "Utilities", "choco": "hugo-extended", "content": "Hugo", "description": "The world\u0027s fastest framework for building websites.", "link": "https://github.com/gohugoio/hugo/", "winget": "Hugo.Hugo.Extended", "foss": true }, "WPFInstallhandbrake": { "category": "Multimedia Tools", "choco": "handbrake", "content": "HandBrake", "description": "HandBrake is an open-source video transcoder, allowing you to convert video from nearly any format to a selection of widely supported codecs.", "link": "https://handbrake.fr/", "winget": "HandBrake.HandBrake", "foss": true }, "WPFInstallheroiclauncher": { "category": "Games", "choco": "heroic-games-launcher", "content": "Heroic Games Launcher", "description": "Heroic Games Launcher is an open-source alternative game launcher for Epic Games Store.", "link": "https://heroicgameslauncher.com/", "winget": "HeroicGamesLauncher.HeroicGamesLauncher", "foss": true }, "WPFInstallhwinfo": { "category": "Pro Tools", "choco": "hwinfo", "content": "HWiNFO", "description": "HWiNFO provides comprehensive hardware information and diagnostics for Windows.", "link": "https://www.hwinfo.com/", "winget": "REALiX.HWiNFO", "foss": false }, "WPFInstallhwmonitor": { "category": "Pro Tools", "choco": "hwmonitor", "content": "HWMonitor", "description": "HWMonitor is a hardware monitoring program that reads PC systems main health sensors.", "link": "https://www.cpuid.com/softwares/hwmonitor.html", "winget": "CPUID.HWMonitor", "foss": false }, "WPFInstallimageglass": { "category": "Multimedia Tools", "choco": "imageglass", "content": "ImageGlass (Image Viewer)", "description": "ImageGlass is a versatile image viewer with support for various image formats and a focus on simplicity and speed.", "link": "https://imageglass.org/", "winget": "DuongDieuPhap.ImageGlass", "foss": true }, "WPFInstallinternetdownloadmanager": { "category": "Utilities", "choco": "internet-download-manager", "content": "Internet Download Manager", "description": "Internet Download Manager is a download manager for accelerating, resuming, and scheduling file downloads.", "link": "https://www.internetdownloadmanager.com/", "winget": "Tonec.InternetDownloadManager", "foss": false }, "WPFInstallirfanview": { "category": "Multimedia Tools", "choco": "irfanview", "content": "IrfanView", "description": "IrfanView is a lightweight, fast, and free image viewer and editor. Supports multiple formats, batch processing, and powerful plugins.", "link": "https://irfanview.com/", "winget": "IrfanSkiljan.IrfanView", "foss": false }, "WPFInstallitch": { "category": "Games", "choco": "itch", "content": "Itch.io", "description": "Itch.io is a digital distribution platform for indie games and creative projects.", "link": "https://itch.io/", "winget": "ItchIo.Itch", "foss": true }, "WPFInstallitunes": { "category": "Multimedia Tools", "choco": "itunes", "content": "iTunes", "description": "iTunes is a media player, media library, and online radio broadcaster application developed by Apple Inc.", "link": "https://www.apple.com/itunes/", "winget": "Apple.iTunes", "foss": false }, "WPFInstalljava8": { "category": "Development", "choco": "corretto8jdk", "content": "Amazon Corretto 8 (LTS)", "description": "Amazon Corretto is a no-cost, multiplatform, production-ready distribution of the Open Java Development Kit (OpenJDK).", "link": "https://aws.amazon.com/corretto", "winget": "Amazon.Corretto.8.JDK", "foss": true }, "WPFInstalljava21": { "category": "Development", "choco": "corretto21jdk", "content": "Amazon Corretto 21 (LTS)", "description": "Amazon Corretto is a no-cost, multiplatform, production-ready distribution of the Open Java Development Kit (OpenJDK).", "link": "https://aws.amazon.com/corretto", "winget": "Amazon.Corretto.21.JDK", "foss": true }, "WPFInstalljava25": { "category": "Development", "choco": "corretto25jdk", "content": "Amazon Corretto 25 (LTS)", "description": "Amazon Corretto is a no-cost, multiplatform, production-ready distribution of the Open Java Development Kit (OpenJDK).", "link": "https://aws.amazon.com/corretto", "winget": "Amazon.Corretto.25.JDK", "foss": true }, "WPFInstalljellyfinmediaplayer": { "category": "Selfhosted Tools", "choco": "jellyfin-media-player", "content": "Jellyfin Media Player", "description": "Jellyfin Media Player is a client application for the Jellyfin media server, providing access to your media library.", "link": "https://github.com/jellyfin/jellyfin-media-player", "winget": "Jellyfin.JellyfinMediaPlayer", "foss": true }, "WPFInstalljellyfinserver": { "category": "Selfhosted Tools", "choco": "jellyfin", "content": "Jellyfin Server", "description": "Jellyfin Server is an open-source media server software, allowing you to organize and stream your media library.", "link": "https://jellyfin.org/", "winget": "Jellyfin.Server", "foss": true }, "WPFInstalljetbrains": { "category": "Development", "choco": "jetbrainstoolbox", "content": "Jetbrains Toolbox", "description": "Jetbrains Toolbox is a platform for easy installation and management of JetBrains developer tools.", "link": "https://www.jetbrains.com/toolbox/", "winget": "JetBrains.Toolbox", "foss": false }, "WPFInstalljpegview": { "category": "Utilities", "choco": "jpegview", "content": "JPEG View", "description": "JPEGView is a lean, fast and highly configurable viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF, JXL, HEIC, HEIF, AVIF, and TIFF images with a minimal GUI.", "link": "https://github.com/sylikc/jpegview", "winget": "sylikc.JPEGView", "foss": true }, "WPFInstallkeepassxc": { "category": "Utilities", "choco": "keepassxc", "content": "KeePassXC", "description": "KeePassXC is a modern, secure, and open-source password manager that stores and manages your most sensitive information. You can run KeePassXC on Windows, macOS, and Linux systems. KeePassXC is for people with extremely high demands of secure personal data management. It saves many different types of information, such as usernames, passwords, URLs, attachments, and notes in an offline, encrypted file that can be stored in any location, including private and public cloud solutions. For easy identification and management, user-defined titles and icons can be specified for entries. In addition, entries are sorted into customizable groups. An integrated search function allows you to use advanced patterns to easily find any entry in your database. A customizable, fast, and easy-to-use password generator utility allows you to create passwords with any combination of characters or easy to remember passphrases.", "link": "https://keepassxc.org/", "winget": "KeePassXCTeam.KeePassXC", "foss": true }, "WPFInstallklite": { "category": "Multimedia Tools", "choco": "k-litecodecpack-standard", "content": "K-Lite Codec Standard", "description": "K-Lite Codec Pack Standard is a collection of audio and video codecs and related tools, providing essential components for media playback.", "link": "https://www.codecguide.com/", "winget": "CodecGuide.K-LiteCodecPack.Standard", "foss": false }, "WPFInstallkodi": { "category": "Selfhosted Tools", "choco": "kodi", "content": "Kodi Media Center", "description": "Kodi is an open-source media center application that allows you to play and view most videos, music, podcasts, and other digital media files.", "link": "https://kodi.tv/", "winget": "XBMCFoundation.Kodi", "foss": true }, "WPFInstalllazygit": { "category": "Development", "choco": "lazygit", "content": "Lazygit", "description": "Simple terminal UI for git commands.", "link": "https://github.com/jesseduffield/lazygit/", "winget": "JesseDuffield.lazygit", "foss": true }, "WPFInstalllibreoffice": { "category": "Multimedia Tools", "choco": "libreoffice-fresh", "content": "LibreOffice", "description": "LibreOffice is a powerful and free office suite, compatible with other major office suites.", "link": "https://www.libreoffice.org/", "winget": "TheDocumentFoundation.LibreOffice", "foss": true }, "WPFInstalllibrewolf": { "category": "Browsers", "choco": "librewolf", "content": "LibreWolf", "description": "LibreWolf is a privacy-focused web browser based on Firefox, with additional privacy and security enhancements.", "link": "https://librewolf-community.gitlab.io/", "winget": "LibreWolf.LibreWolf", "foss": true }, "WPFInstalllocalsend": { "category": "Selfhosted Tools", "choco": "localsend.install", "content": "LocalSend", "description": "An open-source cross-platform alternative to AirDrop.", "link": "https://localsend.org/", "winget": "LocalSend.LocalSend", "foss": true }, "WPFInstallmpc-qt": { "category": "Multimedia Tools", "choco": "mediainfo", "content": "mpc-qt", "description": "Media Player Classic Qute Theater", "link": "https://github.com/mpc-qt/mpc-qt", "winget": "mpc-qt.mpc-qt", "foss": true }, "WPFInstallmatrix": { "category": "Communications", "choco": "element-desktop", "content": "Element", "description": "Element is a client for Matrix; an open network for secure, decentralized communication.", "link": "https://element.io/", "winget": "Element.Element", "foss": true }, "WPFInstallminitoolpartitionwizard": { "category": "Utilities", "choco": "minitoolpartitionwizard", "content": "MiniTool Partition Wizard", "description": "Comprehensive free partition manager that performs advanced operations Windows natively cannot, such as merging partitions, converting file systems, and organizing disk capacity.", "link": "https://www.partitionwizard.com/", "winget": "MiniTool.PartitionWizard.Free", "foss": false }, "WPFInstallmodrinth": { "category": "Games", "choco": "modrinth-app", "content": "Modrinth App", "description": "Modrinth App is a desktop application for managing Minecraft mods and modpacks.", "link": "https://modrinth.com/app", "winget": "Modrinth.ModrinthApp", "foss": true }, "WPFInstallmoonlight": { "category": "Selfhosted Tools", "choco": "moonlight-qt", "content": "Moonlight/GameStream Client", "description": "Moonlight/GameStream Client allows you to stream PC games to other devices over your local network.", "link": "https://moonlight-stream.org/", "winget": "MoonlightGameStreamingProject.Moonlight", "foss": true }, "WPFInstallmpchc": { "category": "Multimedia Tools", "choco": "mpc-hc-clsid2", "content": "Media Player Classic - Home Cinema", "description": "Media Player Classic - Home Cinema (MPC-HC) is a free and open-source video and audio player for Windows. MPC-HC is based on the original Guliverkli project and contains many additional features and bug fixes.", "link": "https://github.com/clsid2/mpc-hc/", "winget": "clsid2.mpc-hc", "foss": true }, "WPFInstallmsedgeredirect": { "category": "Utilities", "choco": "msedgeredirect", "content": "MSEdgeRedirect", "description": "A Tool to Redirect News, Search, Widgets, Weather, and More to your default browser.", "link": "https://github.com/rcmaehl/MSEdgeRedirect", "winget": "rcmaehl.MSEdgeRedirect", "foss": true }, "WPFInstallmsiafterburner": { "category": "Utilities", "choco": "msiafterburner", "content": "MSI Afterburner", "description": "MSI Afterburner is a graphics card overclocking utility with advanced features.", "link": "https://www.msi.com/Landing/afterburner", "winget": "Guru3D.Afterburner", "foss": false }, "WPFInstallmullvadvpn": { "category": "Pro Tools", "choco": "mullvad-app", "content": "Mullvad VPN", "description": "This is the VPN client software for the Mullvad VPN service.", "link": "https://github.com/mullvad/mullvadvpn-app", "winget": "MullvadVPN.MullvadVPN", "foss": true }, "WPFInstallmullvadbrowser": { "category": "Browsers", "choco": "na", "content": "Mullvad Browser", "description": "Mullvad Browser is a privacy-focused web browser, developed in partnership with the Tor Project.", "link": "https://mullvad.net/browser", "winget": "MullvadVPN.MullvadBrowser", "foss": true }, "WPFInstallnomacs": { "category": "Multimedia Tools", "choco": "nomacs", "content": "nomacs", "description": "nomacs is a free, open-source image viewer, which supports multiple platforms. You can use it for viewing all common image formats, including RAW and .psd images.", "link": "https://nomacs.org/", "winget": "nomacs.nomacs", "foss": true }, "WPFInstallnanazip": { "category": "Utilities", "choco": "nanazip", "content": "NanaZip", "description": "NanaZip is a fast and efficient file compression and decompression tool.", "link": "https://github.com/M2Team/NanaZip", "winget": "M2Team.NanaZip", "foss": true }, "WPFInstallnetbird": { "category": "Selfhosted Tools", "choco": "netbird", "content": "NetBird", "description": "NetBird is an open-source alternative comparable to TailScale that can be connected to a self-hosted server.", "link": "https://netbird.io/", "winget": "Netbird.Netbird", "foss": true }, "WPFInstallnaps2": { "category": "Multimedia Tools", "choco": "naps2", "content": "NAPS2 (Document Scanner)", "description": "NAPS2 is a document scanning application that simplifies the process of creating electronic documents.", "link": "https://www.naps2.com/", "winget": "Cyanfish.NAPS2", "foss": true }, "WPFInstallneovim": { "category": "Development", "choco": "neovim", "content": "Neovim", "description": "Neovim is a highly extensible text editor and an improvement over the original Vim editor.", "link": "https://neovim.io/", "winget": "Neovim.Neovim", "foss": true }, "WPFInstallnextclouddesktop": { "category": "Selfhosted Tools", "choco": "nextcloud-client", "content": "Nextcloud Desktop", "description": "Nextcloud Desktop is the official desktop client for the Nextcloud file synchronization and sharing platform.", "link": "https://nextcloud.com/install/#install-clients", "winget": "Nextcloud.NextcloudDesktop", "foss": true }, "WPFInstallnmap": { "category": "Pro Tools", "choco": "nmap", "content": "Nmap", "description": "Nmap (Network Mapper) is an open-source tool for network exploration and security auditing. It discovers devices on a network and provides information about their ports and services.", "link": "https://nmap.org/", "winget": "Insecure.Nmap", "foss": true }, "WPFInstallnodejs": { "category": "Development", "choco": "nodejs", "content": "NodeJS", "description": "NodeJS is a JavaScript runtime built on Chrome\u0027s V8 JavaScript engine for building server-side and networking applications.", "link": "https://nodejs.org/", "winget": "OpenJS.NodeJS", "foss": true }, "WPFInstallnodejslts": { "category": "Development", "choco": "nodejs-lts", "content": "NodeJS LTS", "description": "NodeJS LTS provides Long-Term Support releases for stable and reliable server-side JavaScript development.", "link": "https://nodejs.org/", "winget": "OpenJS.NodeJS.LTS", "foss": true }, "WPFInstallpnpm": { "category": "Development", "content": "pnpm", "description": "pnpm is a fast and disk space efficient package manager for JavaScript and Node.js applications.", "link": "https://pnpm.io/", "winget": "pnpm.pnpm", "foss": true }, "WPFInstallnotepadplus": { "category": "Multimedia Tools", "choco": "notepadplusplus", "content": "Notepad++", "description": "Notepad++ is a free, open-source code editor and Notepad replacement with support for multiple languages.", "link": "https://notepad-plus-plus.org/", "winget": "Notepad++.Notepad++", "foss": true }, "WPFInstallnuget": { "category": "Microsoft Tools", "choco": "nuget.commandline", "content": "NuGet", "description": "NuGet is a package manager for the .NET framework, enabling developers to manage and share libraries in their .NET applications.", "link": "https://www.nuget.org/", "winget": "Microsoft.NuGet", "foss": true }, "WPFInstallnvclean": { "category": "Utilities", "choco": "na", "content": "NVCleanstall", "description": "NVCleanstall is a tool designed to customize NVIDIA driver installations, allowing advanced users to control more aspects of the installation process.", "link": "https://www.techpowerup.com/nvcleanstall/", "winget": "TechPowerUp.NVCleanstall", "foss": false }, "WPFInstallobs": { "category": "Multimedia Tools", "choco": "obs-studio", "content": "OBS Studio", "description": "OBS Studio is a free and open-source software for video recording and live streaming. It supports real-time video/audio capturing and mixing, making it popular among content creators.", "link": "https://obsproject.com/", "winget": "OBSProject.OBSStudio", "foss": true }, "WPFInstallobsidian": { "category": "Multimedia Tools", "choco": "obsidian", "content": "Obsidian", "description": "Obsidian is a powerful note-taking and knowledge management application.", "link": "https://obsidian.md/", "winget": "Obsidian.Obsidian", "foss": false }, "WPFInstallonedrive": { "category": "Microsoft Tools", "choco": "onedrive", "content": "OneDrive", "description": "OneDrive is a cloud storage service provided by Microsoft, allowing users to store and share files securely across devices.", "link": "https://onedrive.live.com/", "winget": "Microsoft.OneDrive", "foss": false }, "WPFInstallonlyoffice": { "category": "Multimedia Tools", "choco": "onlyoffice", "content": "ONLYOFFICE Desktop", "description": "ONLYOFFICE Desktop is a comprehensive office suite for document editing and collaboration.", "link": "https://www.onlyoffice.com/desktop.aspx", "winget": "ONLYOFFICE.DesktopEditors", "foss": true }, "WPFInstallOPAutoClicker": { "category": "Utilities", "choco": "autoclicker", "content": "OPAutoClicker", "description": "A full-fledged autoclicker with two modes of autoclicking, at your dynamic cursor location or at a prespecified location.", "link": "https://www.opautoclicker.com", "winget": "OPAutoClicker.OPAutoClicker", "foss": false }, "WPFInstallopenrgb": { "category": "Utilities", "choco": "openrgb", "content": "OpenRGB", "description": "OpenRGB is an open-source RGB lighting control software designed to manage and control RGB lighting for various components and peripherals.", "link": "https://openrgb.org/", "winget": "OpenRGB.OpenRGB", "foss": true }, "WPFInstallOpenVPN": { "category": "Pro Tools", "choco": "openvpn-connect", "content": "OpenVPN Connect", "description": "OpenVPN Connect is a VPN client that allows you to connect securely to a VPN server. It provides a secure and encrypted connection for protecting your online privacy.", "link": "https://openvpn.net/", "winget": "OpenVPNTechnologies.OpenVPNConnect", "foss": false }, "WPFInstallOVirtualBox": { "category": "Utilities", "choco": "virtualbox", "content": "Oracle VirtualBox", "description": "Oracle VirtualBox is a powerful and free open-source virtualization tool for x86 and AMD64/Intel64 architectures.", "link": "https://www.virtualbox.org/", "winget": "Oracle.VirtualBox", "foss": true }, "WPFInstallpolicyplus": { "category": "Utilities", "choco": "na", "content": "Policy Plus", "description": "Local Group Policy Editor plus more, for all Windows editions.", "link": "https://github.com/Fleex255/PolicyPlus", "winget": "Fleex255.PolicyPlus", "foss": true }, "WPFInstallprocessexplorer": { "category": "Microsoft Tools", "choco": "procexp", "content": "Process Explorer", "description": "Process Explorer is a task manager and system monitor.", "link": "https://learn.microsoft.com/sysinternals/downloads/process-explorer", "winget": "Microsoft.Sysinternals.ProcessExplorer", "foss": false }, "WPFInstallPaintdotnet": { "category": "Multimedia Tools", "choco": "paint.net", "content": "Paint.NET", "description": "Paint.NET is a free image and photo editing software for Windows. It features an intuitive user interface and supports a wide range of powerful editing tools.", "link": "https://www.getpaint.net/", "winget": "dotPDN.PaintDotNet", "foss": false }, "WPFInstallparsec": { "category": "Utilities", "choco": "parsec", "content": "Parsec", "description": "Parsec is a low-latency, high-quality remote desktop sharing application for collaborating and gaming across devices.", "link": "https://parsec.app/", "winget": "Parsec.Parsec", "foss": false }, "WPFInstallpeazip": { "category": "Utilities", "choco": "peazip", "content": "PeaZip", "description": "PeaZip is a free, open-source file archiver utility that supports multiple archive formats and provides encryption features.", "link": "https://peazip.github.io/", "winget": "Giorgiotani.Peazip", "foss": true }, "WPFInstallplaynite": { "category": "Games", "choco": "playnite", "content": "Playnite", "description": "Playnite is an open-source video game library manager with one simple goal: To provide a unified interface for all of your games.", "link": "https://playnite.link/", "winget": "Playnite.Playnite", "foss": true }, "WPFInstallplex": { "category": "Selfhosted Tools", "choco": "plexmediaserver", "content": "Plex Media Server", "description": "Plex Media Server is a media server software that allows you to organize and stream your media library. It supports various media formats and offers a wide range of features.", "link": "https://www.plex.tv/your-media/", "winget": "Plex.PlexMediaServer", "foss": false }, "WPFInstallplexdesktop": { "category": "Selfhosted Tools", "choco": "plex", "content": "Plex Desktop", "description": "Plex Desktop for Windows is the front end for Plex Media Server.", "link": "https://www.plex.tv", "winget": "Plex.Plex", "foss": false }, "WPFInstallposh": { "category": "Development", "choco": "oh-my-posh", "content": "Oh My Posh (Prompt)", "description": "Oh My Posh is a cross-platform prompt theme engine for any shell.", "link": "https://ohmyposh.dev/", "winget": "JanDeDobbeleer.OhMyPosh", "foss": true }, "WPFInstallpowershell": { "category": "Microsoft Tools", "choco": "powershell-core", "content": "PowerShell", "description": "PowerShell is a task automation framework and scripting language designed for system administrators, offering powerful command-line capabilities.", "link": "https://github.com/PowerShell/PowerShell", "winget": "Microsoft.PowerShell", "foss": true }, "WPFInstallpowertoys": { "category": "Microsoft Tools", "choco": "powertoys", "content": "PowerToys", "description": "PowerToys is a set of utilities for power users to enhance productivity, featuring tools like FancyZones, PowerRename, and more.", "link": "https://github.com/microsoft/PowerToys", "winget": "Microsoft.PowerToys", "foss": true }, "WPFInstallprismlauncher": { "category": "Games", "choco": "prismlauncher", "content": "Prism Launcher", "description": "Prism Launcher is an open-source Minecraft launcher with the ability to manage multiple instances, accounts, and mods.", "link": "https://prismlauncher.org/", "winget": "PrismLauncher.PrismLauncher", "foss": true }, "WPFInstallprocesslasso": { "category": "Utilities", "choco": "plasso", "content": "Process Lasso", "description": "Process Lasso is a system optimization and automation tool that improves system responsiveness and stability by adjusting process priorities and CPU affinities.", "link": "https://bitsum.com/", "winget": "BitSum.ProcessLasso", "foss": false }, "WPFInstallprotonauth": { "category": "Utilities", "choco": "protonauth", "content": "Proton Authenticator", "description": "2FA app from Proton to securely sync and backup 2FA codes.", "link": "https://proton.me/authenticator", "winget": "Proton.ProtonAuthenticator", "foss": true }, "WPFInstallprotonmail": { "category": "Communications", "choco": "protonmail", "content": "Proton Mail", "description": "Proton Mail is an end-to-end encrypted email service by Proton, protecting your privacy with zero-access encryption.", "link": "https://proton.me/mail", "winget": "Proton.ProtonMail", "foss": true }, "WPFInstallprotondrive": { "category": "Utilities", "choco": "protondrive", "content": "Proton Drive", "description": "Proton Drive is an end-to-end encrypted Swiss vault for your files that protects your data.", "link": "https://proton.me/drive", "winget": "Proton.ProtonDrive", "foss": true }, "WPFInstallprotonpass": { "category": "Utilities", "choco": "protonpass", "content": "Proton Pass", "description": "Proton Pass is a cloud-based password manager with end-to-end encryption and unique email aliases.", "link": "https://proton.me/pass", "winget": "Proton.ProtonPass", "foss": true }, "WPFInstallprotonvpn": { "category": "Pro Tools", "choco": "protonvpn", "content": "Proton VPN", "description": "Proton VPN is a no-logs VPN service that protects your privacy online with features like Secure Core and Tor over VPN.", "link": "https://protonvpn.com/", "winget": "Proton.ProtonVPN", "foss": true }, "WPFInstallprocessmonitor": { "category": "Microsoft Tools", "choco": "procexp", "content": "Process Monitor", "description": "SysInternals Process Monitor is an advanced monitoring tool that shows real-time file system, registry, and process/thread activity.", "link": "https://docs.microsoft.com/en-us/sysinternals/downloads/procmon", "winget": "Microsoft.Sysinternals.ProcessMonitor", "foss": false }, "WPFInstallputty": { "category": "Pro Tools", "choco": "putty", "content": "PuTTY", "description": "PuTTY is a free and open-source terminal emulator, serial console, and network file transfer application. It supports various network protocols such as SSH, Telnet, and SCP.", "link": "https://www.chiark.greenend.org.uk/~sgtatham/putty/", "winget": "PuTTY.PuTTY", "foss": true }, "WPFInstallpython3": { "category": "Development", "choco": "python", "content": "Python3", "description": "Python is a versatile programming language used for web development, data analysis, artificial intelligence, and more.", "link": "https://www.python.org/", "winget": "Python.Python.3.14", "foss": true }, "WPFInstallqbittorrent": { "category": "Utilities", "choco": "qbittorrent", "content": "qBittorrent", "description": "qBittorrent is a free and open-source BitTorrent client that aims to provide a feature-rich and lightweight alternative to other torrent clients.", "link": "https://www.qbittorrent.org/", "winget": "qBittorrent.qBittorrent", "foss": true }, "WPFInstallqtox": { "category": "Communications", "choco": "qtox", "content": "QTox", "description": "QTox is a free and open-source messaging app that prioritizes user privacy and security in its design.", "link": "https://qtox.github.io/", "winget": "Tox.qTox", "foss": true }, "WPFInstallrevo": { "category": "Utilities", "choco": "revo-uninstaller", "content": "Revo Uninstaller", "description": "Revo Uninstaller is an advanced uninstaller tool that helps you remove unwanted software and clean up your system.", "link": "https://www.revouninstaller.com/", "winget": "RevoUninstaller.RevoUninstaller", "foss": false }, "WPFInstallWiseProgramUninstaller": { "category": "Utilities", "choco": "na", "content": "Wise Program Uninstaller (WiseCleaner)", "description": "Wise Program Uninstaller is the perfect solution for uninstalling Windows programs, allowing you to uninstall applications quickly and completely using its simple and user-friendly interface.", "link": "https://www.wisecleaner.com/wise-program-uninstaller.html", "winget": "WiseCleaner.WiseProgramUninstaller", "foss": false }, "WPFInstallrufus": { "category": "Utilities", "choco": "rufus", "content": "Rufus Imager", "description": "Rufus is a utility that helps format and create bootable USB drives, such as USB keys or pen drives.", "link": "https://rufus.ie/", "winget": "Rufus.Rufus", "foss": true }, "WPFInstallrustlang": { "category": "Development", "choco": "rust", "content": "Rust", "description": "Rust is a programming language designed for safety and performance, particularly focused on systems programming.", "link": "https://www.rust-lang.org/", "winget": "Rustlang.Rust.MSVC", "foss": true }, "WPFInstallsdio": { "category": "Utilities", "choco": "sdio", "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.", "link": "https://www.glenn.delahoy.com/snappy-driver-installer-origin/", "winget": "GlennDelahoy.SnappyDriverInstallerOrigin", "foss": true }, "WPFInstallsharex": { "category": "Multimedia Tools", "choco": "sharex", "content": "ShareX (Screenshots)", "description": "ShareX is a free and open-source screen capture and file sharing tool. It supports various capture methods and offers advanced features for editing and sharing screenshots.", "link": "https://getsharex.com/", "winget": "ShareX.ShareX", "foss": true }, "WPFInstallnilesoftShell": { "category": "Utilities", "choco": "nilesoft-shell", "content": "Nilesoft Shell", "description": "Shell is an expanded context menu tool that adds extra functionality and customization options to the Windows context menu.", "link": "https://nilesoft.org/", "winget": "Nilesoft.Shell", "foss": false }, "WPFInstallsysteminformer": { "category": "Development", "choco": "systeminformer", "content": "System Informer", "description": "A free, powerful, multi-purpose tool that helps you monitor system resources, debug software and detect malware.", "link": "https://systeminformer.com/", "winget": "WinsiderSS.SystemInformer", "foss": true }, "WPFInstallsignal": { "category": "Communications", "choco": "signal", "content": "Signal", "description": "Signal is a privacy-focused messaging app that offers end-to-end encryption for secure and private communication.", "link": "https://signal.org/", "winget": "OpenWhisperSystems.Signal", "foss": true }, "WPFInstallsignalrgb": { "category": "Utilities", "choco": "na", "content": "SignalRGB", "description": "SignalRGB lets you control and sync your favorite RGB devices with one free application.", "link": "https://www.signalrgb.com/", "winget": "WhirlwindFX.SignalRgb", "foss": false }, "WPFInstallsimplewall": { "category": "Pro Tools", "choco": "simplewall", "content": "Simplewall", "description": "Simplewall is a free and open-source firewall application for Windows. It allows users to control and manage the inbound and outbound network traffic of applications.", "link": "https://github.com/henrypp/simplewall", "winget": "Henry++.simplewall", "foss": true }, "WPFInstallslack": { "category": "Communications", "choco": "slack", "content": "Slack", "description": "Slack is a collaboration hub that connects teams and facilitates communication through channels, messaging, and file sharing.", "link": "https://slack.com/", "winget": "SlackTechnologies.Slack", "foss": false }, "WPFInstallstartallback": { "category": "Utilities", "choco": "StartAllBack", "content": "StartAllBack", "description": "StartAllBack restores and improves Windows taskbar, Start menu, File Explorer, and shell UI behavior.", "link": "https://www.startallback.com/", "winget": "StartIsBack.StartAllBack", "foss": false }, "WPFInstallsteam": { "category": "Games", "choco": "steam-client", "content": "Steam", "description": "Steam is a digital distribution platform for purchasing and playing video games, offering multiplayer gaming, video streaming, and more.", "link": "https://store.steampowered.com/about/", "winget": "Valve.Steam", "foss": false }, "WPFInstallsublimetext": { "category": "Development", "choco": "sublimetext4", "content": "Sublime Text", "description": "Sublime Text is a sophisticated text editor for code, markup, and prose.", "link": "https://www.sublimetext.com/", "winget": "SublimeHQ.SublimeText.4", "foss": false }, "WPFInstallsunshine": { "category": "Selfhosted Tools", "choco": "sunshine", "content": "Sunshine/GameStream Server", "description": "Sunshine is a GameStream server that allows you to remotely play PC games on Android devices, offering low-latency streaming.", "link": "https://github.com/LizardByte/Sunshine", "winget": "LizardByte.Sunshine", "foss": true }, "WPFInstalltcpview": { "category": "Microsoft Tools", "choco": "tcpview", "content": "TCPView", "description": "SysInternals TCPView is a network monitoring tool that displays a detailed list of all TCP and UDP endpoints on your system.", "link": "https://docs.microsoft.com/en-us/sysinternals/downloads/tcpview", "winget": "Microsoft.Sysinternals.TCPView", "foss": false }, "WPFInstallteams": { "category": "Communications", "choco": "microsoft-teams", "content": "Teams", "description": "Microsoft Teams is a collaboration platform that integrates with Office 365 and offers chat, video conferencing, file sharing, and more.", "link": "https://www.microsoft.com/en-us/microsoft-teams/group-chat-software", "winget": "Microsoft.Teams", "foss": false }, "WPFInstallteamviewer": { "category": "Utilities", "choco": "teamviewer9", "content": "TeamViewer", "description": "TeamViewer is a popular remote access and support software that allows you to connect to and control remote devices.", "link": "https://www.teamviewer.com/", "winget": "TeamViewer.TeamViewer", "foss": false }, "WPFInstallteamspeak3": { "category": "Communications", "choco": "teamspeak", "content": "TeamSpeak 3", "description": "TEAMSPEAK. YOUR TEAM. YOUR RULES. Use crystal clear sound to communicate with your teammates cross-platform with military-grade security, lag-free performance \u0026 unparalleled reliability and uptime.", "link": "https://www.teamspeak.com/", "winget": "TeamSpeakSystems.TeamSpeakClient", "foss": false }, "WPFInstalltelegram": { "category": "Communications", "choco": "telegram", "content": "Telegram", "description": "Telegram is a cloud-based instant messaging app known for its security features, speed, and simplicity.", "link": "https://telegram.org/", "winget": "Telegram.TelegramDesktop", "foss": true }, "WPFInstallterminal": { "category": "Microsoft Tools", "choco": "microsoft-windows-terminal", "content": "Windows Terminal", "description": "Windows Terminal is a modern, fast, and efficient terminal application for command-line users, supporting multiple tabs, panes, and more.", "link": "https://aka.ms/terminal", "winget": "Microsoft.WindowsTerminal", "foss": true }, "WPFInstallthunderbird": { "category": "Communications", "choco": "thunderbird", "content": "Thunderbird", "description": "Mozilla Thunderbird is a free and open-source email client, news client, and chat client with advanced features.", "link": "https://www.thunderbird.net/", "winget": "Mozilla.Thunderbird", "foss": true }, "WPFInstallbetterbird": { "category": "Communications", "choco": "betterbird", "content": "Betterbird", "description": "Betterbird is a fork of Mozilla Thunderbird with additional features and bugfixes.", "link": "https://www.betterbird.eu/", "winget": "Betterbird.Betterbird", "foss": true }, "WPFInstalltor": { "category": "Browsers", "choco": "tor-browser", "content": "Tor Browser", "description": "Tor Browser is designed for anonymous web browsing, utilizing the Tor network to protect user privacy and security.", "link": "https://www.torproject.org/", "winget": "TorProject.TorBrowser", "foss": true }, "WPFInstalltotalcommander": { "category": "Utilities", "choco": "TotalCommander", "content": "Total Commander", "description": "Total Commander is a file manager for Windows that provides a powerful and intuitive interface for file management.", "link": "https://www.ghisler.com/", "winget": "Ghisler.TotalCommander", "foss": false }, "WPFInstalltreesize": { "category": "Utilities", "choco": "treesizefree", "content": "TreeSize Free", "description": "TreeSize Free is a disk space manager that helps you analyze and visualize the space usage on your drives.", "link": "https://www.jam-software.com/treesize_free/", "winget": "JAMSoftware.TreeSize.Free", "foss": false }, "WPFInstallttaskbar": { "category": "Utilities", "choco": "translucenttb", "content": "TranslucentTB", "description": "TranslucentTB is a tool that allows you to customize the transparency of the Windows Taskbar.", "link": "https://github.com/TranslucentTB/TranslucentTB", "winget": "CharlesMilette.TranslucentTB", "foss": true }, "WPFInstallubisoft": { "category": "Games", "choco": "ubisoft-connect", "content": "Ubisoft Connect", "description": "Ubisoft Connect is Ubisoft\u0027s digital distribution and online gaming service, providing access to Ubisoft\u0027s games and services.", "link": "https://ubisoftconnect.com/", "winget": "Ubisoft.Connect", "foss": false }, "WPFInstallungoogled": { "category": "Browsers", "choco": "ungoogled-chromium", "content": "Ungoogled Chromium", "description": "Ungoogled Chromium is a version of Chromium without Google\u0027s integration for enhanced privacy and control.", "link": "https://github.com/Eloston/ungoogled-chromium", "winget": "eloston.ungoogled-chromium", "foss": true }, "WPFInstallunity": { "category": "Development", "choco": "unityhub", "content": "Unity Game Engine", "description": "Unity is a powerful game development platform for creating 2D, 3D, augmented reality, and virtual reality games.", "link": "https://unity.com/", "winget": "Unity.UnityHub", "foss": false }, "WPFInstalleverything": { "category": "Utilities", "choco": "everything", "content": "Everything", "description": "Everything is a search engine that locates files and folders by filename instantly for Windows. Unlike Windows search Everything initially displays every file and folder on your computer (hence the name Everything). You type in a search filter to limit what files and folders are displayed.", "link": "https://www.voidtools.com/", "winget": "voidtools.Everything", "foss": false }, "WPFInstallvc2015_32": { "category": "Microsoft Tools", "choco": "vcredist2015", "content": "Visual C++ 2015-2022 32-bit", "description": "Visual C++ 2015-2022 32-bit redistributable package installs runtime components of Visual C++ libraries required to run 32-bit applications.", "link": "https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads", "winget": "Microsoft.VCRedist.2015+.x86", "foss": false }, "WPFInstallvc2015_64": { "category": "Microsoft Tools", "choco": "vcredist2015", "content": "Visual C++ 2015-2022 64-bit", "description": "Visual C++ 2015-2022 64-bit redistributable package installs runtime components of Visual C++ libraries required to run 64-bit applications.", "link": "https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads", "winget": "Microsoft.VCRedist.2015+.x64", "foss": false }, "WPFInstallventoy": { "category": "Pro Tools", "choco": "ventoy", "content": "Ventoy", "description": "Ventoy is an open-source tool for creating bootable USB drives. It supports multiple ISO files on a single USB drive, making it a versatile solution for installing operating systems.", "link": "https://www.ventoy.net/", "winget": "Ventoy.Ventoy", "foss": true }, "WPFInstallvesktop": { "category": "Communications", "choco": "na", "content": "Vesktop", "description": "A cross platform electron-based desktop app aiming to give you a snappier Discord experience with Vencord pre-installed.", "link": "https://github.com/Vencord/Vesktop", "winget": "Vencord.Vesktop", "foss": true }, "WPFInstallviber": { "category": "Communications", "choco": "viber", "content": "Viber", "description": "Viber is a free messaging and calling app with features like group chats, video calls, and more.", "link": "https://www.viber.com/", "winget": "Rakuten.Viber", "foss": false }, "WPFInstallvisualstudio2022": { "category": "Development", "choco": "visualstudio2022community", "content": "Visual Studio 2022", "description": "Visual Studio 2022 is an integrated development environment (IDE) for building, debugging, and deploying applications.", "link": "https://visualstudio.microsoft.com/", "winget": "Microsoft.VisualStudio.2022.Community", "foss": false }, "WPFInstallvisualstudio2026": { "category": "Development", "choco": "visualstudio2026community", "content": "Visual Studio 2026", "description": "Visual Studio 2026 is an integrated development environment (IDE) for building, debugging, and deploying applications.", "link": "https://visualstudio.microsoft.com/", "winget": "Microsoft.VisualStudio.Community", "foss": false }, "WPFInstallvivaldi": { "category": "Browsers", "choco": "vivaldi", "content": "Vivaldi", "description": "Vivaldi is a highly customizable web browser with a focus on user personalization and productivity features.", "link": "https://vivaldi.com/", "winget": "Vivaldi.Vivaldi", "foss": false }, "WPFInstallvlc": { "category": "Multimedia Tools", "choco": "vlc", "content": "VLC (Video Player)", "description": "VLC Media Player is a free and open-source multimedia player that supports a wide range of audio and video formats. It is known for its versatility and cross-platform compatibility.", "link": "https://www.videolan.org/vlc/", "winget": "VideoLAN.VLC", "foss": true }, "WPFInstallvrdesktopstreamer": { "category": "Games", "choco": "na", "content": "Virtual Desktop Streamer", "description": "Virtual Desktop Streamer is a tool that allows you to stream your desktop screen to VR devices.", "link": "https://www.vrdesktop.net/", "winget": "VirtualDesktop.Streamer", "foss": false }, "WPFInstallvscode": { "category": "Development", "choco": "vscode", "content": "VS Code", "description": "Visual Studio Code is a free, open-source code editor with support for multiple programming languages.", "link": "https://code.visualstudio.com/", "winget": "Microsoft.VisualStudioCode", "foss": true }, "WPFInstallvscodium": { "category": "Development", "choco": "vscodium", "content": "VS Codium", "description": "VSCodium is a community-driven, freely-licensed binary distribution of Microsoft\u0027s VS Code.", "link": "https://vscodium.com/", "winget": "VSCodium.VSCodium", "foss": true }, "WPFInstallwaterfox": { "category": "Browsers", "choco": "waterfox", "content": "Waterfox", "description": "Waterfox is a fast, privacy-focused web browser based on Firefox, designed to preserve user choice and privacy.", "link": "https://www.waterfox.net/", "winget": "Waterfox.Waterfox", "foss": true }, "WPFInstallwhatsapp": { "category": "Communications", "choco": "na", "content": "WhatsApp Desktop", "description": "WhatsApp Desktop is the official Windows desktop messaging app from Meta, distributed through the Microsoft Store.", "link": "https://apps.microsoft.com/detail/9nksqgp7f2nh", "winget": "msstore:9NKSQGP7F2NH", "foss": false }, "WPFInstallwingetui": { "category": "Utilities", "choco": "wingetui", "content": "UniGetUI", "description": "UniGetUI is a GUI for WinGet, Chocolatey, and other Windows CLI package managers.", "link": "https://devolutions.net/unigetui/", "winget": "Devolutions.UniGetUI", "foss": true }, "WPFInstallwinrar": { "category": "Utilities", "choco": "winrar", "content": "WinRAR", "description": "WinRAR is a powerful archive manager that allows you to create, manage, and extract compressed files.", "link": "https://www.win-rar.com/", "winget": "RARLab.WinRAR", "foss": false }, "WPFInstallwinscp": { "category": "Pro Tools", "choco": "winscp", "content": "WinSCP", "description": "WinSCP is a popular open-source SFTP, FTP, and SCP client for Windows. It allows secure file transfers between a local and a remote computer.", "link": "https://winscp.net/", "winget": "WinSCP.WinSCP", "foss": true }, "WPFInstallwireguard": { "category": "Pro Tools", "choco": "wireguard", "content": "WireGuard", "description": "WireGuard is a fast and modern VPN (Virtual Private Network) protocol. It aims to be simpler and more efficient than other VPN protocols, providing secure and reliable connections.", "link": "https://www.wireguard.com/", "winget": "WireGuard.WireGuard", "foss": true }, "WPFInstallwireshark": { "category": "Pro Tools", "choco": "wireshark", "content": "Wireshark", "description": "Wireshark is a widely-used open-source network protocol analyzer. It allows users to capture and analyze network traffic in real-time, providing detailed insights into network activities.", "link": "https://www.wireshark.org/", "winget": "WiresharkFoundation.Wireshark", "foss": true }, "WPFInstallwiztree": { "category": "Utilities", "choco": "wiztree", "content": "WizTree", "description": "WizTree is a fast disk space analyzer that helps you quickly find the files and folders consuming the most space on your hard drive.", "link": "https://wiztreefree.com/", "winget": "AntibodySoftware.WizTree", "foss": false }, "WPFInstallxeheditor": { "category": "Utilities", "choco": "HxD", "content": "HxD Hex Editor", "description": "HxD is a free hex editor that allows you to edit, view, search, and analyze binary files.", "link": "https://mh-nexus.de/en/hxd/", "winget": "MHNexus.HxD", "foss": false }, "WPFInstallyarn": { "category": "Development", "choco": "yarn", "content": "Yarn", "description": "Yarn is a fast, reliable, and secure dependency management tool for JavaScript projects.", "link": "https://yarnpkg.com/", "winget": "Yarn.Yarn", "foss": true }, "WPFInstallzoom": { "category": "Communications", "choco": "zoom", "content": "Zoom", "description": "Zoom is a popular video conferencing and web conferencing service for online meetings, webinars, and collaborative projects.", "link": "https://zoom.us/", "winget": "Zoom.Zoom", "foss": false }, "WPFInstalluv": { "category": "Development", "choco": "uv", "content": "uv", "description": "uv is a fast Python package and project manager written in Rust.", "link": "https://docs.astral.sh/uv/getting-started/installation/", "winget": "astral-sh.uv", "foss": true }, "WPFInstalltightvnc": { "category": "Utilities", "choco": "TightVNC", "content": "TightVNC", "description": "TightVNC is a free and open-source remote desktop software that lets you access and control a computer over the network. With its intuitive interface, you can interact with the remote screen as if you were sitting in front of it. You can open files, launch applications, and perform other actions on the remote desktop almost as if you were physically there.", "link": "https://www.tightvnc.com/", "winget": "GlavSoft.TightVNC", "foss": true }, "WPFInstallglazewm": { "category": "Utilities", "choco": "glazewm", "content": "GlazeWM", "description": "GlazeWM is a tiling window manager for Windows inspired by i3 and Polybar.", "link": "https://github.com/glzr-io/glazewm", "winget": "glzr-io.glazewm", "foss": true }, "WPFInstallOverwolf": { "category": "Games", "choco": "overwolf", "content": "Overwolf", "description": "Popular platform for game overlays and companion apps (mod managers, trackers, etc.), widely used by gamers.", "link": "https://www.overwolf.com/app/overwolf-curseforge", "winget": "Overwolf.CurseForge", "foss": false }, "WPFInstallOFGB": { "category": "Utilities", "choco": "ofgb", "content": "OFGB (Oh Frick Go Back)", "description": "GUI Tool to remove ads from various places around Windows 11", "link": "https://github.com/xM4ddy/OFGB", "winget": "xM4ddy.OFGB", "foss": true }, "WPFInstallZenBrowser": { "category": "Browsers", "choco": "zen-browser", "content": "Zen Browser", "description": "The modern, privacy-focused, performance-driven browser built on Firefox.", "link": "https://zen-browser.app/", "winget": "Zen-Team.Zen-Browser", "foss": true }, "WPFInstallZed": { "category": "Development", "choco": "zed", "content": "Zed", "description": "Zed is a modern, high-performance code editor designed from the ground up for speed and collaboration.", "link": "https://zed.dev/", "winget": "ZedIndustries.Zed", "foss": true }, "WPFInstalldeskflow": { "category": "Utilities", "choco": "deskflow", "content": "Deskflow", "description": "Deskflow is a free and open-source software KVM that lets you share a single keyboard and mouse across multiple computers.", "link": "https://github.com/deskflow/deskflow", "winget": "Deskflow.Deskflow", "foss": true }, "WPFInstallRuby": { "category": "Development", "choco": "ruby", "winget": "RubyInstallerTeam.Ruby.4.0", "description": "A Ruby language execution environment with a MSYS2 installation.", "content": "Ruby", "link": "https://rubyinstaller.org/", "foss": true }, "WPFInstallLua": { "category": "Development", "choco": "lua", "winget": "rjpcomputing.luaforwindows", "description": "A \u0027batteries included environment\u0027 for the Lua scripting language on Windows.", "content": "Lua", "link": "https://github.com/rjpcomputing/luaforwindows", "foss": true } } '@ | ConvertFrom-Json $sync.configs.appnavigation = @' { "WPFInstall": { "Content": "Install/Upgrade Applications", "Category": "____Actions", "Type": "Button", "Order": "1", "Description": "Install or upgrade the selected applications" }, "WPFUninstall": { "Content": "Uninstall Applications", "Category": "____Actions", "Type": "Button", "Order": "2", "Description": "Uninstall the selected applications" }, "WPFInstallUpgrade": { "Content": "Upgrade all Applications", "Category": "____Actions", "Type": "Button", "Order": "3", "Description": "Upgrade all applications to the latest version" }, "WingetRadioButton": { "Content": "WinGet", "Category": "__Package Manager", "Type": "RadioButton", "GroupName": "PackageManagerGroup", "Checked": true, "Order": "1", "Description": "Use WinGet for package management" }, "ChocoRadioButton": { "Content": "Chocolatey", "Category": "__Package Manager", "Type": "RadioButton", "GroupName": "PackageManagerGroup", "Checked": false, "Order": "2", "Description": "Use Chocolatey for package management" }, "WPFCollapseAllCategories": { "Content": "Collapse All Categories", "Category": "__Selection", "Type": "Button", "Order": "1", "Description": "Collapse all application categories" }, "WPFExpandAllCategories": { "Content": "Expand All Categories", "Category": "__Selection", "Type": "Button", "Order": "2", "Description": "Expand all application categories" }, "WPFClearInstallSelection": { "Content": "Clear Selection", "Category": "__Selection", "Type": "Button", "Order": "3", "Description": "Clear the selection of applications" }, "WPFGetInstalled": { "Content": "Show Installed Apps", "Category": "__Selection", "Type": "Button", "Order": "4", "Description": "Show installed applications" }, "WPFselectedAppsButton": { "Content": "Selected Apps: 0", "Category": "__Selection", "Type": "Button", "Order": "5", "Description": "Show the selected applications" }, "WPFInstallFOSSInfo": { "Content": "Free and Open Source Software", "Category": "__Selection", "Type": "Note", "Order": "0", "Description": "Information about the #FOSS label on application entries" } } '@ | ConvertFrom-Json $sync.configs.appx = @' { "WPFAppxMicrosoft_WindowsFeedbackHub": { "Category": "Microsoft Apps", "Content": "Feedback Hub", "Description": "Allows users to submit bug reports, feature suggestions, and diagnostic data directly to Microsoft.", "Panel": "0", "PackageId": "Microsoft.WindowsFeedbackHub" }, "WPFAppxMicrosoft_GetHelp": { "Category": "Microsoft Apps", "Content": "Get Help", "Description": "Provides access to automated troubleshooting guides, support documentation, and direct Microsoft customer assistance.", "Panel": "0", "PackageId": "Microsoft.GetHelp" }, "WPFAppxMicrosoft_OutlookForWindows": { "Category": "Microsoft Apps", "Content": "Outlook for Windows", "Description": "Provides modern email management, calendar scheduling, and contact organization features.", "Panel": "0", "PackageId": "Microsoft.OutlookForWindows" }, "WPFAppxMSTeams": { "Category": "Microsoft Apps", "Content": "Microsoft Teams", "Description": "Facilitates instant messaging, video conferencing, file sharing, and workspace collaboration.", "Panel": "0", "PackageId": "MSTeams" }, "WPFAppxClipchamp_Clipchamp": { "Category": "Utilities \u0026 Productivity", "Content": "Clipchamp", "Description": "Provides a user-friendly video editor with built-in templates, effects, and timeline editing tools.", "Panel": "0", "PackageId": "Clipchamp.Clipchamp" }, "WPFAppxMicrosoft_MicrosoftOfficeHub": { "Category": "Microsoft Apps", "Content": "Microsoft 365", "Description": "Serves as a centralized launcher and dashboard for accessing cloud-based Microsoft 365 apps and recent documents.", "Panel": "0", "PackageId": "Microsoft.MicrosoftOfficeHub" }, "WPFAppxMicrosoft_ZuneMusic": { "Category": "Utilities \u0026 Productivity", "Content": "Media Player", "Description": "Plays local audio and video files with modern playlist management and casting capabilities.", "Panel": "0", "PackageId": "Microsoft.ZuneMusic" }, "WPFAppxMicrosoft_BingSearch": { "Category": "Bing \u0026 Web Services", "Content": "Bing Search", "Description": "Integrates Microsoft Bing search capabilities and web services directly into the operating system.", "Panel": "1", "PackageId": "Microsoft.BingSearch" }, "WPFAppxMicrosoftCorporationII_QuickAssist": { "Category": "Utilities \u0026 Productivity", "Content": "Quick Assist", "Description": "Enables secure remote technical support and screen sharing over an internet connection.", "Panel": "0", "PackageId": "MicrosoftCorporationII.QuickAssist" }, "WPFAppxMicrosoft_WindowsDevHome": { "Category": "Developer Tools", "Content": "Dev Home", "Description": "Provides a specialized dashboard for software developer environment setups, repository syncing, and hardware widgets.", "Panel": "1", "PackageId": "Microsoft.Windows.DevHome" }, "WPFAppxMicrosoft_WindowsCrossDevice": { "Category": "Microsoft Ecosystem", "Content": "Mobile Devices", "Description": "Manages system-level background connectivity with paired mobile devices. Removing this may disable cross-device features such as phone screen mirroring, file transfer, and mobile hotspot handoff integrated into Windows Settings.", "Panel": "0", "PackageId": "MicrosoftWindows.CrossDevice" }, "WPFAppxMicrosoft_Todos": { "Category": "Utilities \u0026 Productivity", "Content": "To Do", "Description": "Creates, tracks, and synchronizes personal tasks, smart lists, and daily reminders.", "Panel": "0", "PackageId": "Microsoft.Todos" }, "WPFAppxMicrosoft_PowerAutomateDesktop": { "Category": "Developer Tools", "Content": "Power Automate", "Description": "Automates repetitive workflows and desktop tasks using low-code visual scripting.", "Panel": "1", "PackageId": "Microsoft.PowerAutomateDesktop" }, "WPFAppxMicrosoft_YourPhone": { "Category": "Microsoft Ecosystem", "Content": "Phone Link", "Description": "Synchronizes text messages, phone notifications, photos, and calls from a mobile device to the desktop.", "Panel": "0", "PackageId": "Microsoft.YourPhone" }, "WPFAppxMicrosoft_MicrosoftStickyNotes": { "Category": "Utilities \u0026 Productivity", "Content": "Sticky Notes", "Description": "Creates quick, floating text notes on the desktop that automatically sync across devices.", "Panel": "0", "PackageId": "Microsoft.MicrosoftStickyNotes" }, "WPFAppxMicrosoft_WindowsSoundRecorder": { "Category": "Utilities \u0026 Productivity", "Content": "Sound Recorder", "Description": "Records and trims live audio inputs with simple microphone adjustment controls.", "Panel": "0", "PackageId": "Microsoft.WindowsSoundRecorder" }, "WPFAppxMicrosoft_WindowsAlarms": { "Category": "Utilities \u0026 Productivity", "Content": "Clock", "Description": "Features world clocks, alarms, countdown timers, stopwatches, and dedicated focus session tracking.", "Panel": "0", "PackageId": "Microsoft.WindowsAlarms" }, "WPFAppxMicrosoft_Paint": { "Category": "Utilities \u0026 Productivity", "Content": "Paint", "Description": "Provides built-in digital sketching, basic image editing, and pixel-level graphic manipulation tools.", "Panel": "0", "PackageId": "Microsoft.Paint" }, "WPFAppxMicrosoft_WindowsNotepad": { "Category": "Utilities \u0026 Productivity", "Content": "Notepad", "Description": "Provides a lightweight text editor with multi-tab support for plain text files and code snippets.", "Panel": "0", "PackageId": "Microsoft.WindowsNotepad" }, "WPFAppxMicrosoft_ScreenSketch": { "Category": "Utilities \u0026 Productivity", "Content": "Snipping Tool", "Description": "Captures screenshots or screen recordings with built-in markup, image cropping, and optical character recognition (OCR).", "Panel": "0", "PackageId": "Microsoft.ScreenSketch" }, "WPFAppxMicrosoft_Copilot": { "Category": "Bing \u0026 Web Services", "Content": "Copilot", "Description": "Launches the Microsoft AI companion for contextual answers, creative writing assistance, and intelligent web search.", "Panel": "1", "PackageId": "Microsoft.Copilot" }, "WPFAppxMicrosoft_WindowsCalculator": { "Category": "Utilities \u0026 Productivity", "Content": "Calculator", "Description": "Performs standard arithmetic, scientific operations, programming calculations, and unit conversions.", "Panel": "0", "PackageId": "Microsoft.WindowsCalculator" }, "WPFAppxMicrosoft_WindowsCamera": { "Category": "Utilities \u0026 Productivity", "Content": "Camera", "Description": "Captures photographs and records video files via connected webcams or imaging hardware.", "Panel": "0", "PackageId": "Microsoft.WindowsCamera" }, "WPFAppxMicrosoft_WindowsPhotos": { "Category": "Utilities \u0026 Productivity", "Content": "Photos", "Description": "Organizes, views, and crops local images with basic color adjustment and album creation tools.", "Panel": "0", "PackageId": "Microsoft.Windows.Photos" }, "WPFAppxMicrosoft_BingNews": { "Category": "Bing \u0026 Web Services", "Content": "News", "Description": "Aggregates breaking news headlines, personalized article feeds, and world current events.", "Panel": "1", "PackageId": "Microsoft.BingNews" }, "WPFAppxMicrosoft_BingWeather": { "Category": "Bing \u0026 Web Services", "Content": "Weather", "Description": "Displays local real-time weather tracking, radar maps, and historical meteorological forecasts.", "Panel": "1", "PackageId": "Microsoft.BingWeather" }, "WPFAppxMicrosoft_GamingApp": { "Category": "Xbox \u0026 Gaming", "Content": "Xbox App", "Description": "Serves as the primary gaming library manager, social community interface, and PC Game Pass dashboard.", "Panel": "1", "PackageId": "Microsoft.GamingApp" }, "WPFAppxMicrosoft_XboxGamingOverlay": { "Category": "Xbox \u0026 Gaming", "Content": "Xbox Game Bar", "Description": "Provides customizable in-game status widgets, audio balancing sliders, system monitoring tools, and gameplay recording.", "Panel": "1", "PackageId": "Microsoft.XboxGamingOverlay" }, "WPFAppxMicrosoft_XboxIdentityProvider": { "Category": "Xbox \u0026 Gaming", "Content": "Xbox Identity Provider", "Description": "Manages Xbox network user authentication and background account validation for connected titles. Warning: removing this may break Microsoft account sign-in for non-Xbox games and apps that rely on this authentication pipeline.", "Panel": "1", "PackageId": "Microsoft.XboxIdentityProvider" }, "WPFAppxMicrosoft_XboxSpeechToTextOverlay": { "Category": "Xbox \u0026 Gaming", "Content": "Xbox Speech To Text Overlay", "Description": "Provides system-level live accessibility captions and voice-to-text translation for gaming chat networks.", "Panel": "1", "PackageId": "Microsoft.XboxSpeechToTextOverlay" }, "WPFAppxMicrosoft_Xbox_TCUI": { "Category": "Xbox \u0026 Gaming", "Content": "Xbox TCUI", "Description": "Provides core account connection UI modules for single sign-on flows within game titles. Warning: removing this may break Microsoft account authentication in games and apps that do not otherwise require the Xbox app.", "Panel": "1", "PackageId": "Microsoft.Xbox.TCUI" }, "WPFAppxMicrosoft_StartExperiencesApp": { "Category": "Bing \u0026 Web Services", "Content": "Start Experiences App", "Description": "Powers the Windows Widgets board, delivering a personalized feed of news, weather, sports, and finance content.", "Panel": "1", "PackageId": "Microsoft.StartExperiencesApp" }, "WPFAppxMicrosoft_MicrosoftSolitaireCollection": { "Category": "Xbox \u0026 Gaming", "Content": "Solitaire Collection", "Description": "Bundles built-in card game modes including Klondike, Spider, FreeCell, Pyramid, and TriPeaks alongside daily challenges.", "Panel": "1", "PackageId": "Microsoft.MicrosoftSolitaireCollection" } } '@ | ConvertFrom-Json $sync.configs.dns = @' { "Google": { "Primary": "8.8.8.8", "Secondary": "8.8.4.4", "Primary6": "2001:4860:4860::8888", "Secondary6": "2001:4860:4860::8844" }, "Cloudflare": { "Primary": "1.1.1.1", "Secondary": "1.0.0.1", "Primary6": "2606:4700:4700::1111", "Secondary6": "2606:4700:4700::1001" }, "Cloudflare_Malware": { "Primary": "1.1.1.2", "Secondary": "1.0.0.2", "Primary6": "2606:4700:4700::1112", "Secondary6": "2606:4700:4700::1002" }, "Cloudflare_Malware_Adult": { "Primary": "1.1.1.3", "Secondary": "1.0.0.3", "Primary6": "2606:4700:4700::1113", "Secondary6": "2606:4700:4700::1003" }, "Open_DNS": { "Primary": "208.67.222.222", "Secondary": "208.67.220.220", "Primary6": "2620:119:35::35", "Secondary6": "2620:119:53::53" }, "Quad9": { "Primary": "9.9.9.9", "Secondary": "149.112.112.112", "Primary6": "2620:fe::fe", "Secondary6": "2620:fe::9" }, "AdGuard_Ads_Trackers": { "Primary": "94.140.14.14", "Secondary": "94.140.15.15", "Primary6": "2a10:50c0::ad1:ff", "Secondary6": "2a10:50c0::ad2:ff" }, "AdGuard_Ads_Trackers_Malware_Adult": { "Primary": "94.140.14.15", "Secondary": "94.140.15.16", "Primary6": "2a10:50c0::bad1:ff", "Secondary6": "2a10:50c0::bad2:ff" } } '@ | ConvertFrom-Json $sync.configs.feature = @' { "WPFFeaturesdotnet": { "Content": ".NET Framework (Versions 2, 3, 4) - Enable", "Description": ".NET and .NET Framework is a developer platform made up of tools, programming languages, and libraries for building many different types of applications.", "category": "Features", "panel": "1", "feature": [ "NetFx4-AdvSrvs", "NetFx3" ], "InvokeScript": [ ], "link": "https://winutil.christitus.com/dev/features/features/dotnet" }, "WPFFixesNTPPool": { "Content": "NTP Server - Enable", "Description": "Replaces the default Windows NTP server (time.windows.com) with pool.ntp.org for improved time synchronization accuracy and reliability.", "category": "Fixes", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFFixesNTPPool", "link": "https://winutil.christitus.com/dev/features/fixes/ntppool" }, "WPFFeatureshyperv": { "Content": "Hyper-V - Enable", "Description": "Hyper-V is a hardware virtualization product developed by Microsoft that allows users to create and manage virtual machines.", "category": "Features", "panel": "1", "feature": [ "Microsoft-Hyper-V-All" ], "link": "https://winutil.christitus.com/dev/features/features/hyperv" }, "WPFFeatureslegacymedia": { "Content": "Legacy Media Components (WMP, DirectPlay) - Enable", "Description": "Enables legacy programs from previous versions of Windows.", "category": "Features", "panel": "1", "feature": [ "WindowsMediaPlayer", "MediaPlayback", "DirectPlay", "LegacyComponents" ], "InvokeScript": [ ], "link": "https://winutil.christitus.com/dev/features/features/legacymedia" }, "WPFFeaturewsl": { "Content": "Windows Subsystem for Linux (WSL) - Enable", "Description": "Windows Subsystem for Linux is an optional feature of Windows that allows Linux programs to run natively on Windows without the need for a separate virtual machine or dual booting.", "category": "Features", "panel": "1", "feature": [ "VirtualMachinePlatform", "Microsoft-Windows-Subsystem-Linux" ], "InvokeScript": [ ], "link": "https://winutil.christitus.com/dev/features/features/wsl" }, "WPFFeaturenfs": { "Content": "Network File System (NFS) - Enable", "Description": "Network File System (NFS) is a mechanism for storing files on a network.", "category": "Features", "panel": "1", "feature": [ "ServicesForNFS-ClientOnly", "ClientForNFS-Infrastructure", "NFS-Administration" ], "InvokeScript": [ "nfsadmin client stop", "Set-ItemProperty -Path \u0027HKLM:\\SOFTWARE\\Microsoft\\ClientForNFS\\CurrentVersion\\Default\u0027 -Name \u0027AnonymousUID\u0027 -Type DWord -Value 0", "Set-ItemProperty -Path \u0027HKLM:\\SOFTWARE\\Microsoft\\ClientForNFS\\CurrentVersion\\Default\u0027 -Name \u0027AnonymousGID\u0027 -Type DWord -Value 0", "nfsadmin client start", "nfsadmin client localhost config fileaccess=755 SecFlavors=+sys -krb5 -krb5i" ], "link": "https://winutil.christitus.com/dev/features/features/nfs" }, "WPFFeatureRegBackup": { "Content": "Registry Backup (Daily Task 12:30am) - Enable", "Description": "Enables daily registry backup, previously disabled by Microsoft in Windows 10 1803.", "category": "Features", "panel": "1", "feature": [ ], "InvokeScript": [ "\r\n New-ItemProperty -Path \u0027HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\u0027 -Name \u0027EnablePeriodicBackup\u0027 -Type DWord -Value 1 -Force\r\n New-ItemProperty -Path \u0027HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Configuration Manager\u0027 -Name \u0027BackupCount\u0027 -Type DWord -Value 2 -Force\r\n $action = New-ScheduledTaskAction -Execute \u0027schtasks\u0027 -Argument \u0027/run /i /tn \"\\Microsoft\\Windows\\Registry\\RegIdleBackup\"\u0027\r\n $trigger = New-ScheduledTaskTrigger -Daily -At 00:30\r\n Register-ScheduledTask -Action $action -Trigger $trigger -TaskName \u0027AutoRegBackup\u0027 -Description \u0027Create System Registry Backups\u0027 -User \u0027System\u0027\r\n " ], "link": "https://winutil.christitus.com/dev/features/features/regbackup" }, "WPFFeatureEnableLegacyRecovery": { "Content": "Legacy F8 Boot Recovery - Enable", "Description": "Enables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.", "category": "Features", "panel": "1", "feature": [ ], "InvokeScript": [ "bcdedit /set bootmenupolicy legacy" ], "link": "https://winutil.christitus.com/dev/features/features/enablelegacyrecovery" }, "WPFFeatureDisableLegacyRecovery": { "Content": "Legacy F8 Boot Recovery - Disable", "Description": "Disables Advanced Boot Options screen that lets you start Windows in advanced troubleshooting modes.", "category": "Features", "panel": "1", "feature": [ ], "InvokeScript": [ "bcdedit /set bootmenupolicy standard" ], "link": "https://winutil.christitus.com/dev/features/features/disablelegacyrecovery" }, "WPFFeaturesSandbox": { "Content": "Windows Sandbox - Enable", "Description": "Windows Sandbox is a lightweight virtual machine that provides a temporary desktop environment to safely run applications and programs in isolation.", "category": "Features", "panel": "1", "feature": [ "Containers-DisposableClientVM" ], "link": "https://winutil.christitus.com/dev/features/features/sandbox" }, "WPFFeatureInstall": { "Content": "Install Features", "category": "Features", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFFeatureInstall", "link": "https://winutil.christitus.com/dev/features/features/install" }, "WPFPanelAutologin": { "Content": "AutoLogon - Run", "category": "Fixes", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFPanelAutologin", "link": "https://winutil.christitus.com/dev/features/fixes/autologin" }, "WPFFixesUpdate": { "Content": "Windows Update - Reset", "category": "Fixes", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFFixesUpdate", "link": "https://winutil.christitus.com/dev/features/fixes/update" }, "WPFFixesNetwork": { "Content": "Network - Reset", "category": "Fixes", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFFixesNetwork", "link": "https://winutil.christitus.com/dev/features/fixes/network" }, "WPFPanelDISM": { "Content": "System Corruption Scan - Run", "category": "Fixes", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFSystemRepair", "link": "https://winutil.christitus.com/dev/features/fixes/dism" }, "WPFFixesWinget": { "Content": "WinGet - Reinstall", "category": "Fixes", "panel": "1", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFFixesWinget", "link": "https://winutil.christitus.com/dev/features/fixes/winget" }, "WPFPanelControl": { "Content": "Control Panel", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "control" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/control" }, "WPFPanelComputer": { "Content": "Computer Management", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "compmgmt.msc" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/computer" }, "WPFPanelNetwork": { "Content": "Network Connections", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "ncpa.cpl" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/network" }, "WPFPanelPower": { "Content": "Power Panel", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "powercfg.cpl" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/power" }, "WPFPanelPrinter": { "Content": "Printer Panel", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "Start-Process \u0027shell:::{A8A91A66-3A7D-4424-8D24-04E180695C7A}\u0027" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/printer" }, "WPFPanelRegion": { "Content": "Region", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "intl.cpl" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/region" }, "WPFPanelRestore": { "Content": "Windows Restore", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "rstrui.exe" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/restore" }, "WPFPanelSound": { "Content": "Sound Settings", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "mmsys.cpl" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/sound" }, "WPFPanelSystem": { "Content": "System Properties", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "sysdm.cpl" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/system" }, "WPFPanelTimedate": { "Content": "Time and Date", "category": "Legacy Windows Panels", "panel": "2", "Type": "Button", "ButtonWidth": "300", "InvokeScript": [ "timedate.cpl" ], "link": "https://winutil.christitus.com/dev/features/legacy-windows-panels/timedate" }, "WPFWinUtilInstallPSProfile": { "Content": "AtiqSoft PowerShell Profile - Install", "category": "Powershell Profile Powershell 7+ Only", "panel": "2", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WinUtilInstallPSProfile", "link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/installpsprofile" }, "WPFWinUtilUninstallPSProfile": { "Content": "AtiqSoft PowerShell Profile - Remove", "category": "Powershell Profile Powershell 7+ Only", "panel": "2", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WinUtilUninstallPSProfile", "link": "https://winutil.christitus.com/dev/features/powershell-profile-powershell-7--only/uninstallpsprofile" }, "WPFWinUtilSSHServer": { "Content": "OpenSSH Server - Enable", "category": "Remote Access", "panel": "2", "Type": "Button", "ButtonWidth": "300", "function": "Invoke-WPFSSHServer", "link": "https://winutil.christitus.com/dev/features/remote-access/sshserver" } } '@ | ConvertFrom-Json $sync.configs.preset = @' { "Standard": [ "WPFTweaksActivity", "WPFTweaksConsumerFeatures", "WPFTweaksDisableExplorerAutoDiscovery", "WPFTweaksWPBT", "WPFTweaksLocation", "WPFTweaksServices", "WPFTweaksTelemetry", "WPFTweaksDeliveryOptimization", "WPFTweaksDiskCleanup", "WPFTweaksDeleteTempFiles", "WPFTweaksEndTaskOnTaskbar", "WPFTweaksRestorePoint" ], "Minimal": [ "WPFTweaksConsumerFeatures", "WPFTweaksWPBT", "WPFTweaksServices", "WPFTweaksTelemetry" ], "Advanced": [ "WPFTweaksRestorePoint", "WPFTweaksActivity", "WPFTweaksConsumerFeatures", "WPFTweaksDisableExplorerAutoDiscovery", "WPFTweaksWPBT", "WPFTweaksLocation", "WPFTweaksServices", "WPFTweaksTelemetry", "WPFTweaksDeliveryOptimization", "WPFTweaksDeleteTempFiles", "WPFTweaksEndTaskOnTaskbar", "WPFTweaksDisableStoreSearch", "WPFTweaksRevertStartMenu", "WPFTweaksWidget", "WPFTweaksRemoveOneDrive", "WPFTweaksWindowsAI", "WPFTweaksRightClickMenu" ], "AppxDefault": [ "WPFAppxMicrosoft_WindowsFeedbackHub", "WPFAppxMicrosoft_GetHelp", "WPFAppxMicrosoft_MicrosoftOfficeHub", "WPFAppxMicrosoft_WindowsCalculator", "WPFAppxClipchamp_Clipchamp", "WPFAppxMicrosoft_WindowsAlarms", "WPFAppxMicrosoftCorporationII_QuickAssist", "WPFAppxMicrosoft_WindowsSoundRecorder", "WPFAppxMicrosoft_MicrosoftStickyNotes", "WPFAppxMicrosoft_Todos", "WPFAppxMicrosoft_MicrosoftSolitaireCollection", "WPFAppxMicrosoft_PowerAutomateDesktop", "WPFAppxMicrosoft_WindowsDevHome", "WPFAppxMicrosoft_BingWeather", "WPFAppxMicrosoft_StartExperiencesApp", "WPFAppxMicrosoft_BingNews", "WPFAppxMicrosoft_Copilot", "WPFAppxMicrosoft_BingSearch" ] } '@ | ConvertFrom-Json $sync.configs.themes = @' { "shared": { "AppEntryWidth": "200", "AppEntryFontSize": "11", "AppEntryMargin": "1,0,1,0", "AppEntryBorderThickness": "0", "CustomDialogFontSize": "12", "CustomDialogFontSizeHeader": "14", "CustomDialogLogoSize": "25", "CustomDialogWidth": "400", "CustomDialogHeight": "200", "FontSize": "12", "FontFamily": "Arial", "HeaderFontSize": "16", "HeaderFontFamily": "Consolas, Monaco", "CheckBoxBulletDecoratorSize": "14", "CheckBoxMargin": "15,0,0,2", "TabContentMargin": "5", "TabButtonFontSize": "14", "TabButtonWidth": "110", "TabButtonHeight": "26", "TabRowHeightInPixels": "50", "ToolTipWidth": "300", "IconFontSize": "14", "IconButtonSize": "35", "SettingsIconFontSize": "18", "CloseIconFontSize": "18", "GroupBorderBackgroundColor": "#0F172A", "ButtonFontSize": "12", "ButtonFontFamily": "Arial", "ButtonWidth": "200", "ButtonHeight": "25", "ConfigTabButtonFontSize": "14", "ConfigUpdateButtonFontSize": "14", "SearchBarWidth": "200", "SearchBarHeight": "26", "SearchBarTextBoxFontSize": "12", "SearchBarClearButtonFontSize": "14", "CheckboxMouseOverColor": "#999999", "ButtonBorderThickness": "1", "ButtonMargin": "1", "ButtonCornerRadius": "2" }, "Light": { "AppInstallUnselectedColor": "#F7F7F7", "AppInstallHighlightedColor": "#CFCFCF", "AppInstallSelectedColor": "#C2C2C2", "AppInstallOverlayBackgroundColor": "#6A6D72", "ComboBoxForegroundColor": "#232629", "ComboBoxBackgroundColor": "#F7F7F7", "LabelboxForegroundColor": "#232629", "MainForegroundColor": "#232629", "MainBackgroundColor": "#F7F7F7", "LabelBackgroundColor": "#F7F7F7", "LinkForegroundColor": "#484848", "LinkHoverForegroundColor": "#232629", "ScrollBarBackgroundColor": "#4A4D52", "ScrollBarHoverColor": "#5A5D62", "ScrollBarDraggingColor": "#6A6D72", "ProgressBarForegroundColor": "#06B6D4", "ProgressBarBackgroundColor": "Transparent", "ProgressBarTextColor": "#232629", "ButtonInstallBackgroundColor": "#F7F7F7", "ButtonTweaksBackgroundColor": "#F7F7F7", "ButtonConfigBackgroundColor": "#F7F7F7", "ButtonUpdatesBackgroundColor": "#F7F7F7", "ButtonWin11ISOBackgroundColor": "#F7F7F7", "ButtonAppxBackgroundColor": "#F7F7F7", "ButtonInstallForegroundColor": "#232629", "ButtonTweaksForegroundColor": "#232629", "ButtonConfigForegroundColor": "#232629", "ButtonUpdatesForegroundColor": "#232629", "ButtonWin11ISOForegroundColor": "#232629", "ButtonAppxForegroundColor": "#232629", "ButtonBackgroundColor": "#F5F5F5", "ButtonBackgroundPressedColor": "#1A1A1A", "ButtonBackgroundMouseoverColor": "#C2C2C2", "ButtonBackgroundSelectedColor": "#F0F0F0", "ButtonForegroundColor": "#232629", "ToggleButtonOnColor": "#10B981", "ToggleButtonOffColor": "#707070", "ToolTipBackgroundColor": "#F7F7F7", "BorderColor": "#232629", "BorderOpacity": "0.2" }, "Dark": { "AppInstallUnselectedColor": "#232629", "AppInstallHighlightedColor": "#3C3C3C", "AppInstallSelectedColor": "#4C4C4C", "AppInstallOverlayBackgroundColor": "#2E3135", "ComboBoxForegroundColor": "#F7F7F7", "ComboBoxBackgroundColor": "#1E293B", "LabelboxForegroundColor": "#06B6D4", "MainForegroundColor": "#F7F7F7", "MainBackgroundColor": "#0F172A", "LabelBackgroundColor": "#232629", "LinkForegroundColor": "#ADD8E6", "LinkHoverForegroundColor": "#F7F7F7", "ScrollBarBackgroundColor": "#2E3135", "ScrollBarHoverColor": "#3B4252", "ScrollBarDraggingColor": "#5E81AC", "ProgressBarForegroundColor": "#222222", "ProgressBarBackgroundColor": "Transparent", "ProgressBarTextColor": "#232629", "ButtonInstallBackgroundColor": "#222222", "ButtonTweaksBackgroundColor": "#333333", "ButtonConfigBackgroundColor": "#444444", "ButtonUpdatesBackgroundColor": "#555555", "ButtonWin11ISOBackgroundColor": "#666666", "ButtonAppxBackgroundColor": "#777777", "ButtonInstallForegroundColor": "#F7F7F7", "ButtonTweaksForegroundColor": "#F7F7F7", "ButtonConfigForegroundColor": "#F7F7F7", "ButtonUpdatesForegroundColor": "#F7F7F7", "ButtonWin11ISOForegroundColor": "#F7F7F7", "ButtonAppxForegroundColor": "#F7F7F7", "ButtonBackgroundColor": "#1E293B", "ButtonBackgroundPressedColor": "#F7F7F7", "ButtonBackgroundMouseoverColor": "#3B4252", "ButtonBackgroundSelectedColor": "#06B6D4", "ButtonForegroundColor": "#F7F7F7", "ToggleButtonOnColor": "#10B981", "ToggleButtonOffColor": "#707070", "ToolTipBackgroundColor": "#2F373D", "BorderColor": "#2F373D", "BorderOpacity": "0.2" } } '@ | ConvertFrom-Json $sync.configs.tweaks = @' { "WPFTweaksActivity": { "Content": "Activity History - Disable", "Description": "Erases recent docs, clipboard, and run history.", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Name": "EnableActivityFeed", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Name": "PublishUserActivities", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Name": "UploadUserActivities", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/activity" }, "WPFTweaksHiber": { "Content": "Hibernation - Disable", "Description": "Hibernation is really meant for laptops as it saves what\u0027s in memory before turning the PC off. It really should never be used.", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\System\\CurrentControlSet\\Control\\Session Manager\\Power", "Name": "HibernateEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FlyoutMenuSettings", "Name": "ShowHibernateOption", "Value": "0", "Type": "DWord", "OriginalValue": "1" } ], "InvokeScript": [ "powercfg.exe /hibernate off" ], "UndoScript": [ "powercfg.exe /hibernate on" ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/hiber" }, "WPFTweaksWidget": { "Content": "Widgets - Remove", "Description": "Removes the annoying widgets in the bottom left of the Taskbar.", "category": "Essential Tweaks", "panel": "1", "InvokeScript": [ "\r\n # Sometimes if you dont stop the Widgets process the removal may fail\r\n\r\n Get-Process *Widget* | Stop-Process\r\n Get-AppxPackage Microsoft.WidgetsPlatformRuntime -AllUsers | Remove-AppxPackage -AllUsers\r\n Get-AppxPackage MicrosoftWindows.Client.WebExperience -AllUsers | Remove-AppxPackage -AllUsers\r\n\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n Write-Host \"Removed widgets\"\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/widget" }, "WPFTweaksRevertStartMenu": { "Content": "Start Menu Previous Layout - Enable", "Description": "Bring back the old Start Menu layout from before the gradual rollout of the new one in 25H2. On newer versions of Windows !!THIS TWEAK WILL NOT WORK!!", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\SYSTEM\\ControlSet001\\Control\\FeatureManagement\\Overrides\\8\\3036241548", "Name": "EnabledState", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/revertstartmenu" }, "WPFTweaksDisableStoreSearch": { "Content": "Microsoft Store Recommended Search Results - Disable", "Description": "Will not display recommended Microsoft Store apps when searching for apps in the Start menu.", "category": "Essential Tweaks", "panel": "1", "InvokeScript": [ "icacls \"$Env:LocalAppData\\Packages\\Microsoft.WindowsStore_8wekyb3d8bbwe\\LocalState\\store.db\" /deny Everyone:F" ], "UndoScript": [ "icacls \"$Env:LocalAppData\\Packages\\Microsoft.WindowsStore_8wekyb3d8bbwe\\LocalState\\store.db\" /grant Everyone:F" ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/disablestoresearch" }, "WPFTweaksLocation": { "Content": "Location Tracking - Disable", "Description": "Disables Location Tracking.", "category": "Essential Tweaks", "panel": "1", "service": [ { "Name": "lfsvc", "StartupType": "Disable", "OriginalType": "Manual" } ], "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\CapabilityAccessManager\\ConsentStore\\location", "Name": "Value", "Value": "Deny", "Type": "String", "OriginalValue": "Allow" }, { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Sensor\\Overrides\\{BFA794E4-F964-4FDB-90F6-51056BFE4B44}", "Name": "SensorPermissionState", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKLM:\\SYSTEM\\Maps", "Name": "AutoUpdateEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "1" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/location" }, "WPFTweaksServices": { "Content": "Services - Set to Manual", "Description": "Sets some services to Manual startup and adjusts the SvcHostSplitThresholdInKB registry value to better match system memory, which can significantly reduce the number of svchost.exe processes.", "category": "Essential Tweaks", "panel": "1", "service": [ { "Name": "CscService", "StartupType": "Disabled", "OriginalType": "Manual" }, { "Name": "DiagTrack", "StartupType": "Disabled", "OriginalType": "Automatic" }, { "Name": "MapsBroker", "StartupType": "Manual", "OriginalType": "Automatic" }, { "Name": "StorSvc", "StartupType": "Manual", "OriginalType": "Automatic" }, { "Name": "SharedAccess", "StartupType": "Disabled", "OriginalType": "Automatic" } ], "InvokeScript": [ "\r\n $Memory = (Get-CimInstance Win32_PhysicalMemory | Measure-Object Capacity -Sum).Sum / 1KB\r\n Set-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Control\" -Name SvcHostSplitThresholdInKB -Value $Memory\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/services" }, "WPFTweaksBraveDebloat": { "Content": "Brave Browser - Debloat", "Description": "Disables various annoyances like Brave Rewards, Leo AI, Crypto Wallet and VPN.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveRewardsDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveWalletDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveVPNDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveAIChatEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveStatsPingEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveNewsDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveTalkDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "TorDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "BraveP3AEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "UrlKeyedAnonymizedDataCollectionEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "SafeBrowsingExtendedReportingEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\BraveSoftware\\Brave", "Name": "MetricsReportingEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/bravedebloat" }, "WPFTweaksDisableWarningForUnsignedRdp": { "Content": "RDP Unsigned File Warnings - Disable", "Description": "Disables warnings shown when launching unsigned RDP files introduced with the latest Windows 10 and 11 updates.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows NT\\Terminal Services\\Client", "Name": "RedirectionWarningDialogVersion", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\SOFTWARE\\Microsoft\\Terminal Server Client", "Name": "RdpLaunchConsentAccepted", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablewarningforunsignedrdp" }, "WPFTweaksEdgeDebloat": { "Content": "Microsoft Edge - Debloat", "Description": "Disables various telemetry options, popups, and other annoyances in Edge.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\EdgeUpdate", "Name": "CreateDesktopShortcutDefault", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "PersonalizationReportingEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge\\ExtensionInstallBlocklist", "Name": "1", "Value": "ofefcgjbeghpigppfmkologfjadafddi", "Type": "String", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "ShowRecommendationsEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "HideFirstRunExperience", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "UserFeedbackAllowed", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "ConfigureDoNotTrack", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "AlternateErrorPagesEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "EdgeCollectionsEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "EdgeShoppingAssistantEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "MicrosoftEdgeInsiderPromotionEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "ShowMicrosoftRewards", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "WebWidgetAllowed", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "DiagnosticData", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "EdgeAssetDeliveryServiceEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "WalletDonationEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Edge", "Name": "DefaultBrowserSettingsCampaignEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/edgedebloat" }, "WPFTweaksConsumerFeatures": { "Content": "ConsumerFeatures - Disable", "Description": "Windows will not automatically install any games, third-party apps, or application links from the Windows Store for the signed-in user. Some default Apps will be inaccessible (e.g. Phone Link).", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CloudContent", "Name": "DisableWindowsConsumerFeatures", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/consumerfeatures" }, "WPFTweaksTelemetry": { "Content": "Telemetry - Disable", "Description": "Disables Microsoft Telemetry.", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\AdvertisingInfo", "Name": "Enabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Privacy", "Name": "TailoredExperiencesWithDiagnosticDataEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Speech_OneCore\\Settings\\OnlineSpeechPrivacy", "Name": "HasAccepted", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Input\\TIPC", "Name": "Enabled", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\InputPersonalization", "Name": "RestrictImplicitInkCollection", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\InputPersonalization", "Name": "RestrictImplicitTextCollection", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\InputPersonalization\\TrainedDataStore", "Name": "HarvestContacts", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Personalization\\Settings", "Name": "AcceptedPrivacyPolicy", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\DataCollection", "Name": "AllowTelemetry", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "Start_TrackProgs", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Name": "PublishUserActivities", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Siuf\\Rules", "Name": "NumberOfSIUFInPeriod", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "InvokeScript": [ "\r\n # Disable Defender Auto Sample Submission\r\n Set-MpPreference -SubmitSamplesConsent 2\r\n\r\n # Disable (Connected User Experiences and Telemetry) Service\r\n Set-Service -Name diagtrack -StartupType Disabled\r\n\r\n # Disable (Windows Error Reporting Manager) Service\r\n Set-Service -Name wermgr -StartupType Disabled\r\n\r\n # Disable PowerShell 7 telemetry\r\n [Environment]::SetEnvironmentVariable(\u0027POWERSHELL_TELEMETRY_OPTOUT\u0027, \u00271\u0027, \u0027Machine\u0027)\r\n\r\n Remove-ItemProperty -Path \"HKCU:\\Software\\Microsoft\\Siuf\\Rules\" -Name PeriodInNanoSeconds\r\n " ], "UndoScript": [ "\r\n # Enable Defender Auto Sample Submission\r\n Set-MpPreference -SubmitSamplesConsent 1\r\n\r\n # Enable (Connected User Experiences and Telemetry) Service\r\n Set-Service -Name diagtrack -StartupType Automatic\r\n\r\n # Enable (Windows Error Reporting Manager) Service\r\n Set-Service -Name wermgr -StartupType Automatic\r\n\r\n # Enable PowerShell 7 telemetry\r\n [Environment]::SetEnvironmentVariable(\u0027POWERSHELL_TELEMETRY_OPTOUT\u0027, \u0027\u0027, \u0027Machine\u0027)\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/telemetry" }, "WPFTweaksDeliveryOptimization": { "Content": "Delivery Optimization - Disable", "Description": "Stops Windows from using your bandwidth to upload updates to other PCs on the internet or local network.", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\DeliveryOptimization", "Name": "DODownloadMode", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/deliveryoptimization" }, "WPFTweaksRemoveEdge": { "Content": "Microsoft Edge - Remove", "Description": "Uninstalls Microsoft Edge by creating dummy MicrosoftEdge.exe file in the legacy Edge folder. This tricks Windows into unlocking the official Edge uninstaller allowing for a system-level removal.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "InvokeScript": [ "\r\n $Path = Resolve-Path -Path \"$Env:ProgramFiles (x86)\\Microsoft\\Edge\\Application\\*\\Installer\\setup.exe\" | Select-Object -Last 1\r\n\r\n if (Test-Path $Path) {\r\n New-Item -Path \"$Env:SystemRoot\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdge.exe\" -Force\r\n Start-Process -FilePath $Path -ArgumentList \"--uninstall --system-level --force-uninstall --delete-profile\" -Wait\r\n Write-Host \"Microsoft Edge was removed\"\r\n } else {\r\n Write-Host \"Microsoft Edge is not installed\"\r\n }\r\n " ], "UndoScript": [ "\r\n Write-Host \"Installing Microsoft Edge...\"\r\n winget install Microsoft.Edge --source winget\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removeedge" }, "WPFTweaksDisableBitLocker": { "Content": "BitLocker - Disable", "Description": "Disables BitLocker.", "category": "Essential Tweaks", "panel": "1", "InvokeScript": [ "Disable-BitLocker -MountPoint $Env:SystemDrive" ], "UndoScript": [ "Enable-BitLocker -MountPoint $Env:SystemDrive" ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/disablebitlocker" }, "WPFTweaksUTC": { "Content": "Date \u0026 Time - Set Time to UTC", "Description": "Essential for computers that are dual booting. Fixes the time sync with Linux systems.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", "Name": "RealTimeIsUniversal", "Value": "1", "Type": "QWord", "OriginalValue": "0" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/utc" }, "WPFTweaksRemoveOneDrive": { "Content": "Microsoft OneDrive - Remove", "Description": "Denies permission to remove OneDrive user files, then uses its own uninstaller to remove it and restores the original permission afterward.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "InvokeScript": [ "\r\n # Deny permission to remove OneDrive folder\r\n icacls $Env:OneDrive /deny \"Administrators:(D,DC)\"\r\n\r\n Write-Host \"Uninstalling OneDrive...\"\r\n Start-Process \u0027$Env:SystemRoot\\System32\\OneDriveSetup.exe\u0027 -ArgumentList \u0027/uninstall\u0027 -Wait\r\n\r\n # Some of OneDrive files use explorer, and OneDrive uses FileCoAuth\r\n Write-Host \"Removing leftover OneDrive Files...\"\r\n\r\n Stop-Process -Name FileCoAuth,Explorer\r\n\r\n Remove-Item \"$Env:LocalAppData\\Microsoft\\OneDrive\" -Recurse -Force\r\n Remove-Item \"$Env:ProgramData\\Microsoft OneDrive\" -Recurse -Force\r\n\r\n # Grant back permission to access OneDrive folder\r\n icacls $Env:OneDrive /grant \"Administrators:(D,DC)\"\r\n\r\n if (-not (Get-ChildItem -Path $Env:OneDrive)) {\r\n Remove-Item -Path $Env:OneDrive -Recurse\r\n [Environment]::SetEnvironmentVariable(\u0027OneDrive\u0027, $null, \u0027User\u0027)\r\n }\r\n\r\n # Disable OneSyncSvc\r\n Set-Service -Name OneSyncSvc -StartupType Disabled\r\n " ], "UndoScript": [ "\r\n Write-Host \"Installing OneDrive\"\r\n winget install Microsoft.Onedrive --source winget\r\n\r\n # Enabled OneSyncSvc\r\n Set-Service -Name OneSyncSvc -StartupType Automatic\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removeonedrive" }, "WPFTweaksRemoveHomeAndGallery": { "Content": "File Explorer Home and Gallery - Disable", "Description": "Removes the Home and Gallery from Explorer and sets This PC as default.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKCU:\\Software\\Classes\\CLSID\\{f874310e-b6b7-47dc-bc84-b9e6b38f5903}", "Name": "System.IsPinnedToNameSpaceTree", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Classes\\CLSID\\{e88865ea-0e1c-4e20-9aa6-edcd0212c87c}", "Name": "System.IsPinnedToNameSpaceTree", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "LaunchTo", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/removehomeandgallery" }, "WPFTweaksDisplay": { "Content": "Visual Effects - Set to Best Performance", "Description": "Sets the system preferences to performance. You can do this manually with sysdm.cpl as well.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKCU:\\Control Panel\\Desktop", "Name": "DragFullWindows", "Value": "0", "Type": "String", "OriginalValue": "1" }, { "Path": "HKCU:\\Control Panel\\Desktop", "Name": "MenuShowDelay", "Value": "200", "Type": "String", "OriginalValue": "400" }, { "Path": "HKCU:\\Control Panel\\Desktop\\WindowMetrics", "Name": "MinAnimate", "Value": "0", "Type": "String", "OriginalValue": "1" }, { "Path": "HKCU:\\Control Panel\\Keyboard", "Name": "KeyboardDelay", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "ListviewAlphaSelect", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "ListviewShadow", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "TaskbarAnimations", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VisualEffects", "Name": "VisualFXSetting", "Value": "3", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\DWM", "Name": "EnableAeroPeek", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "TaskbarMn", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "ShowTaskViewButton", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Search", "Name": "SearchboxTaskbarMode", "Value": "0", "Type": "DWord", "OriginalValue": "1" } ], "InvokeScript": [ "Set-ItemProperty -Path \"HKCU:\\Control Panel\\Desktop\" -Name \"UserPreferencesMask\" -Type Binary -Value ([byte[]](144,18,3,128,16,0,0,0))" ], "UndoScript": [ "Remove-ItemProperty -Path \"HKCU:\\Control Panel\\Desktop\" -Name \"UserPreferencesMask\"" ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/display" }, "WPFTweaksReservedStorage": { "Content": "Disable Reserved Storage", "Description": "Disables Windows Reserved Storage (7-10 GB held for updates/temp files). Recommended only on small drives. Re-enable before major Windows feature updates to avoid installation failures.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "InvokeScript": [ "DISM /Online /Set-ReservedStorageState /State:Disabled" ], "UndoScript": [ "DISM /Online /Set-ReservedStorageState /State:Enabled" ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/reservedstorage" }, "WPFTweaksRestorePoint": { "Content": "Restore Point - Create", "Description": "Creates a restore point at runtime in case a revert is needed from WinUtil modifications.", "category": "Essential Tweaks", "panel": "1", "Checked": "False", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SystemRestore", "Name": "SystemRestorePointCreationFrequency", "Value": "0", "Type": "DWord", "OriginalValue": "1440" } ], "InvokeScript": [ "\r\n if (-not (Get-ComputerRestorePoint)) {\r\n Enable-ComputerRestore -Drive $Env:SystemDrive\r\n }\r\n\r\n Checkpoint-Computer -Description \"System Restore Point created by WinUtil\" -RestorePointType MODIFY_SETTINGS\r\n Write-Host \"System Restore Point Created Successfully\" -ForegroundColor Green\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/restorepoint" }, "WPFTweaksEndTaskOnTaskbar": { "Content": "End Task With Right Click - Enable", "Description": "Enables option to end task when right clicking a program in the taskbar.", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\TaskbarDeveloperSettings", "Name": "TaskbarEndTask", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/endtaskontaskbar" }, "WPFTweaksStorage": { "Content": "Storage Sense - Disable", "Description": "Storage Sense deletes temp files automatically.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\StorageSense\\Parameters\\StoragePolicy", "Name": "01", "Value": "0", "Type": "DWord", "OriginalValue": "1" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/storage" }, "WPFTweaksWindowsAI": { "Content": "Windows AI - Disable And Remove", "Description": "Removes and disables all AI features/packages", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "Name": "SettingsPageVisibility", "Value": "hide:aicomponents", "Type": "String", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\WindowsNotepad", "Name": "DisableAIFeatures", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "InvokeScript": [ "\r\n $Appx = (Get-AppxPackage MicrosoftWindows.Client.CoreAI).PackageFullName\r\n $Sid = (Get-LocalUser $Env:UserName).Sid.Value\r\n\r\n New-Item \"HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Appx\\AppxAllUserStore\\EndOfLife\\$Sid\\$Appx\" -Force\r\n\r\n Get-AppxPackage -AllUsers \"*Copilot*\" | Remove-AppxPackage -AllUsers\r\n winget uninstall -e --name \"Copilot\" --silent --force --accept-source-agreements 2\u003e$null\r\n Get-AppxPackage -AllUsers Microsoft.MicrosoftOfficeHub | Remove-AppxPackage -AllUsers\r\n\r\n if ($Appx) {\r\n Remove-AppxPackage $Appx\r\n }\r\n\r\n Set-Service -Name WSAIFabricSvc -StartupType Disabled\r\n Disable-WindowsOptionalFeature -FeatureName Recall -Online -NoRestart\r\n\r\n Write-Host \"Windows AI Disabled\"\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/windowsai" }, "WPFTweaksWPBT": { "Content": "Windows Platform Binary Table (WPBT) - Disable", "Description": "If enabled, WPBT allows your computer vendor to execute programs at boot time, such as anti-theft software, software drivers, as well as force install software without user consent. Poses potential security risk.", "category": "Essential Tweaks", "panel": "1", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager", "Name": "DisableWpbtExecution", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/wpbt" }, "WPFTweaksRazerBlock": { "Content": "Razer Software Auto-Install - Disable", "Description": "Blocks ALL Razer Software installations. The hardware works fine without any software.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DriverSearching", "Name": "SearchOrderConfig", "Value": "0", "Type": "DWord", "OriginalValue": "1" }, { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Device Installer", "Name": "DisableCoInstallers", "Value": "1", "Type": "DWord", "OriginalValue": "0" } ], "InvokeScript": [ "\r\n $RazerPath = \"$Env:SystemRoot\\Installer\\Razer\"\r\n\r\n if (Test-Path $RazerPath) {\r\n Remove-Item $RazerPath\\* -Recurse -Force\r\n } else {\r\n New-Item -Path $RazerPath -ItemType Directory\r\n }\r\n\r\n icacls $RazerPath /deny \"Everyone:(W)\"\r\n " ], "UndoScript": [ "\r\n icacls \"$Env:SystemRoot\\Installer\\Razer\" /remove:d Everyone\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/razerblock" }, "WPFTweaksDisableNotifications": { "Content": "System Tray Notifications \u0026 Calendar - Disable", "Description": "Disables all Notifications INCLUDING Calendar.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKCU:\\Software\\Policies\\Microsoft\\Windows\\Explorer", "Name": "DisableNotificationCenter", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" }, { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\PushNotifications", "Name": "ToastEnabled", "Value": "0", "Type": "DWord", "OriginalValue": "1" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablenotifications" }, "WPFTweaksBlockAdobeNet": { "Content": "Adobe URL Block List - Enable", "Description": "Reduces user interruptions by selectively blocking connections to Adobe\u0027s activation and telemetry servers. Credit: Ruddernation-Designs", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "InvokeScript": [ "\r\n $hostsUrl = Invoke-RestMethod -Uri https://github.com/Ruddernation-Designs/Adobe-URL-Block-List/raw/refs/heads/master/hosts\r\n Add-Content -Path \"$Env:SystemRoot\\System32\\drivers\\etc\\hosts\" -Value $hostsUrl\r\n\r\n ipconfig /flushdns\r\n Write-Host \u0027Added Adobe url block list from host file\u0027\r\n " ], "UndoScript": [ "\r\n Set-Content \"$Env:SystemRoot\\System32\\drivers\\etc\\hosts\" (\r\n (Get-Content \"$Env:SystemRoot\\System32\\drivers\\etc\\hosts\") -join \"`n\" -replace \u0027(?s)#New Ver.*\u0027, \u0027\u0027\r\n )\r\n\r\n ipconfig /flushdns\r\n Write-Host \u0027Removed Adobe url block list from host file\u0027\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/blockadobenet" }, "WPFTweaksRightClickMenu": { "Content": "Right-Click Menu Previous Layout - Enable", "Description": "Restores the classic context menu when right-clicking in File Explorer, replacing the simplified Windows 11 version.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "InvokeScript": [ "\r\n New-Item -Path \"HKCU:\\Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\" -Name InprocServer32 -Value \"\" -Force\r\n Stop-Process -Name explorer\r\n " ], "UndoScript": [ "Remove-Item -Path \"HKCU:\\Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\" -Recurse" ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/rightclickmenu" }, "WPFTweaksDiskCleanup": { "Content": "Disk Cleanup - Run", "Description": "Runs Disk Cleanup on Drive C: and removes old Windows Updates.", "category": "Essential Tweaks", "panel": "1", "InvokeScript": [ "\r\n cleanmgr.exe /d C: /VERYLOWDISK\r\n Dism.exe /online /Cleanup-Image /StartComponentCleanup /ResetBase\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/diskcleanup" }, "WPFTweaksDeleteTempFiles": { "Content": "Temporary Files - Remove", "Description": "Erases TEMP Folders.", "category": "Essential Tweaks", "panel": "1", "InvokeScript": [ "\r\n Remove-Item -Path \"$Env:Temp\\*\" -Recurse -Force\r\n Remove-Item -Path \"$Env:SystemRoot\\Temp\\*\" -Recurse -Force\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/deletetempfiles" }, "WPFTweaksIPv46": { "Content": "IPv6 - Set IPv4 as Preferred", "Description": "Setting the IPv4 preference can have latency and security benefits on private networks where IPv6 is not configured.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters", "Name": "DisabledComponents", "Value": "32", "Type": "DWord", "OriginalValue": "0" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/ipv46" }, "WPFTweaksTeredo": { "Content": "Teredo - Disable", "Description": "Teredo network tunneling is an IPv6 feature that can cause additional latency, but may cause problems with some games.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters", "Name": "DisabledComponents", "Value": "1", "Type": "DWord", "OriginalValue": "0" } ], "InvokeScript": [ "netsh interface teredo set state disabled" ], "UndoScript": [ "netsh interface teredo set state default" ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/teredo" }, "WPFTweaksDisableIPv6": { "Content": "IPv6 - Disable", "Description": "Disables IPv6.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip6\\Parameters", "Name": "DisabledComponents", "Value": "255", "Type": "DWord", "OriginalValue": "0" } ], "InvokeScript": [ "Disable-NetAdapterBinding -Name * -ComponentID ms_tcpip6" ], "UndoScript": [ "Enable-NetAdapterBinding -Name * -ComponentID ms_tcpip6" ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disableipv6" }, "WPFTweaksDisableBGapps": { "Content": "Background Apps - Disable", "Description": "Disables all Microsoft Store apps from running in the background, which has to be done individually since Windows 11.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\BackgroundAccessApplications", "Name": "GlobalUserDisabled", "Value": "1", "Type": "DWord", "OriginalValue": "0" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablebgapps" }, "WPFTweaksDisableFSO": { "Content": "Fullscreen Optimizations - Disable", "Description": "Disables FSO in all applications. NOTE: This will disable Color Management in Exclusive Fullscreen.", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "registry": [ { "Path": "HKCU:\\System\\GameConfigStore", "Name": "GameDVR_DXGIHonorFSEWindowsCompatible", "Value": "1", "Type": "DWord", "OriginalValue": "0" } ], "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/disablefso" }, "WPFTweaksDisableExplorerAutoDiscovery": { "Content": "File Explorer Automatic Folder Discovery - Disable", "Description": "Windows Explorer automatically tries to guess the type of the folder based on its contents, slowing down the browsing experience. WARNING! Will disable File Explorer grouping.", "category": "Essential Tweaks", "panel": "1", "InvokeScript": [ "\r\n # Previously detected folders\r\n $bags = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\"\r\n\r\n # Folder types lookup table\r\n $bagMRU = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\"\r\n\r\n # Flush Explorer view database\r\n Remove-Item -Path $bags -Recurse -Force\r\n Write-Host \"Removed $bags\"\r\n\r\n Remove-Item -Path $bagMRU -Recurse -Force\r\n Write-Host \"Removed $bagMRU\"\r\n\r\n # Every folder\r\n $allFolders = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\\AllFolders\\Shell\"\r\n\r\n if (!(Test-Path $allFolders)) {\r\n New-Item -Path $allFolders -Force\r\n Write-Host \"Created $allFolders\"\r\n }\r\n\r\n # Generic view\r\n New-ItemProperty -Path $allFolders -Name \"FolderType\" -Value \"NotSpecified\" -PropertyType String -Force\r\n Write-Host \"Set FolderType to NotSpecified\"\r\n\r\n Write-Host Please sign out and back in, or restart your computer to apply the changes!\r\n " ], "UndoScript": [ "\r\n # Previously detected folders\r\n $bags = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\Bags\"\r\n\r\n # Folder types lookup table\r\n $bagMRU = \"HKCU:\\Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU\"\r\n\r\n # Flush Explorer view database\r\n Remove-Item -Path $bags -Recurse -Force\r\n Write-Host \"Removed $bags\"\r\n\r\n Remove-Item -Path $bagMRU -Recurse -Force\r\n Write-Host \"Removed $bagMRU\"\r\n\r\n Write-Host Please sign out and back in, or restart your computer to apply the changes!\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/essential-tweaks/disableexplorerautodiscovery" }, "WPFToggleDetailedBSoD": { "Content": "BSoD Verbose Mode", "Description": "Gives more information when you blue screen.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\CrashControl", "Name": "DisplayParameters", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "false" }, { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\CrashControl", "Name": "DisableEmoticon", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "false" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/detailedbsod" }, "WPFToggleBatteryPercentage": { "Content": "System Tray Battery Percentage", "Description": "Shows numeric battery percentage next to the battery icon in the system tray.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "IsBatteryPercentageEnabled", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e", "DefaultState": "false" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/batterypercentage" }, "WPFToggleDarkMode": { "Content": "Dark Theme for Windows", "Description": "Dark Mode for the system and applications.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "Name": "AppsUseLightTheme", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "false" }, { "Path": "HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", "Name": "SystemUsesLightTheme", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "false" } ], "InvokeScript": [ "\r\n Invoke-WinUtilExplorerUpdate\r\n if ($sync.ThemeButton.Content -eq [char]0xF08C) {\r\n Invoke-WinutilThemeChange -theme \"Auto\"\r\n }\r\n " ], "UndoScript": [ "\r\n Invoke-WinUtilExplorerUpdate\r\n if ($sync.ThemeButton.Content -eq [char]0xF08C) {\r\n Invoke-WinutilThemeChange -theme \"Auto\"\r\n }\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/darkmode" }, "WPFToggleShowExt": { "Content": "File Explorer File Extensions", "Description": "Shows .file extensions in Explorer (.exe, .png, etc.)", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "HideFileExt", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "false" } ], "InvokeScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "UndoScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/showext" }, "WPFToggleHiddenFiles": { "Content": "File Explorer Hidden Files", "Description": "Reveals hidden files in Explorer.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "Hidden", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "false" } ], "InvokeScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "UndoScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/hiddenfiles" }, "WPFToggleVerboseLogon": { "Content": "Logon Verbose Mode", "Description": "Show detailed messages during startup/shutdown.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "Name": "VerboseStatus", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "false" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/verboselogon" }, "WPFToggleNewOutlook": { "Content": "Microsoft Outlook New Version", "Description": "This will ensures the classic Outlook application is used.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\SOFTWARE\\Microsoft\\Office\\16.0\\Outlook\\Preferences", "Name": "UseNewOutlook", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" }, { "Path": "HKCU:\\Software\\Microsoft\\Office\\16.0\\Outlook\\Options\\General", "Name": "HideNewOutlookToggle", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "true" }, { "Path": "HKCU:\\Software\\Policies\\Microsoft\\Office\\16.0\\Outlook\\Options\\General", "Name": "DoNewOutlookAutoMigration", "Value": "0", "Type": "DWord", "OriginalValue": "0", "DefaultState": "false" }, { "Path": "HKCU:\\Software\\Policies\\Microsoft\\Office\\16.0\\Outlook\\Preferences", "Name": "NewOutlookMigrationUserSetting", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/newoutlook" }, "WPFToggleScrollbars": { "Content": "Scrollbars Always Visible", "Description": "If enabled, scrollbars will always be visible. If disabled, Windows will automatically hide scrollbars when not in use.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Control Panel\\Accessibility", "Name": "DynamicScrollbars", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "false", "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/scrollbars" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/scrollbars" }, "WPFToggleMultiplaneOverlay": { "Content": "Multiplane Overlay", "Description": "Multiplane Overlay compose multiple image layers, which can sometimes cause issues with graphics cards.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\Windows\\Dwm", "Name": "OverlayTestMode", "Value": "0", "Type": "DWord", "OriginalValue": "5", "DefaultState": "true" }, { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers", "Name": "DisableOverlays", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/multiplaneoverlay" }, "WPFToggleMouseAcceleration": { "Content": "Mouse Acceleration", "Description": "Makes it so Cursor movement is affected by the speed of your physical mouse movements.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Control Panel\\Mouse", "Name": "MouseSpeed", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" }, { "Path": "HKCU:\\Control Panel\\Mouse", "Name": "MouseThreshold1", "Value": "6", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" }, { "Path": "HKCU:\\Control Panel\\Mouse", "Name": "MouseThreshold2", "Value": "10", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/mouseacceleration" }, "WPFToggleNumLock": { "Content": "Num Lock on Startup", "Description": "Toggle the Num Lock key state when your computer starts.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKU:\\.Default\\Control Panel\\Keyboard", "Name": "InitialKeyboardIndicators", "Value": "2", "Type": "String", "OriginalValue": "0", "DefaultState": "false" }, { "Path": "HKCU:\\Control Panel\\Keyboard", "Name": "InitialKeyboardIndicators", "Value": "2", "Type": "String", "OriginalValue": "0", "DefaultState": "false" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/numlock" }, "WPFToggleWindowSnapping": { "Content": "Window Snapping", "Description": "Toggles the window snapping feature when dragging windows.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Control Panel\\Desktop", "Name": "WindowArrangementActive", "Value": "1", "Type": "String", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/windowsnapping" }, "WPFToggleStandbyFix": { "Content": "S0 Sleep Network Connectivity", "Description": "Toggles network connectivity during S0 Sleep which is low power idle in modern laptops.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\SOFTWARE\\Policies\\Microsoft\\Power\\PowerSettings\\f15576e8-98b7-4186-b944-eafa664402d9", "Name": "ACSettingIndex", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/standbyfix" }, "WPFToggleS3Sleep": { "Content": "S3 Sleep", "Description": "Toggles between Modern Standby and S3 Sleep, which cuts off power to the CPU while continuing to refresh the memory.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Power", "Name": "PlatformAoAcOverride", "Value": "0", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e", "DefaultState": "false" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/s3sleep" }, "WPFToggleHideSettingsHome": { "Content": "Settings Home Page", "Description": "Toggles the Home Page in the Windows Settings app.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "Name": "SettingsPageVisibility", "Value": "show:home", "Type": "String", "OriginalValue": "hide:home", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/hidesettingshome" }, "WPFToggleBingSearch": { "Content": "Start Menu Bing Search", "Description": "Toggles Bing web search results in Windows Search.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Search", "Name": "BingSearchEnabled", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/bingsearch" }, "WPFToggleLoginBlur": { "Content": "Logon Screen Acrylic Blur", "Description": "Toggles the acrylic blur effect on login screen background.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\System", "Name": "DisableAcrylicBackgroundOnLogon", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/loginblur" }, "WPFTweaksDisableLockscreen": { "Content": "Lock Screen - Disable", "Description": "Skips the lock screen entirely and goes directly to the sign-in screen on boot and wake.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Personalization", "Name": "NoLockScreen", "Value": "1", "Type": "DWord", "OriginalValue": "\u003cRemoveEntry\u003e" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/disablelockscreen" }, "WPFToggleStartMenuRecommendations": { "Content": "Start Menu Recommendations", "Description": "Toggles the recommendations section in the Start Menu. WARNING: This will also disable Windows Spotlight on your Lock Screen as a side effect.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SOFTWARE\\Microsoft\\PolicyManager\\current\\device\\Start", "Name": "HideRecommendedSection", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "true" }, { "Path": "HKLM:\\SOFTWARE\\Microsoft\\PolicyManager\\current\\device\\Education", "Name": "IsEducationEnvironment", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "true" }, { "Path": "HKLM:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer", "Name": "HideRecommendedSection", "Value": "0", "Type": "DWord", "OriginalValue": "1", "DefaultState": "true" } ], "InvokeScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "UndoScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/startmenurecommendations" }, "WPFToggleStickyKeys": { "Content": "Sticky Keys", "Description": "Toggles the Sticky Keys, which activate when clicking shift rapidly.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Control Panel\\Accessibility\\StickyKeys", "Name": "Flags", "Value": "506", "Type": "DWord", "OriginalValue": "58", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/stickykeys" }, "WPFToggleTaskbarAlignment": { "Content": "Taskbar Centered Icons", "Description": "Toggles the Taskbar alignment either to the left or center.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "TaskbarAl", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "InvokeScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "UndoScript": [ "\r\n Invoke-WinUtilExplorerUpdate -action \"restart\"\r\n " ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskbaralignment" }, "WPFToggleTaskbarSearch": { "Content": "Taskbar Search Icon", "Description": "Toggles the Search Button on the Taskbar.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Search", "Name": "SearchboxTaskbarMode", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskbarsearch" }, "WPFToggleTaskView": { "Content": "Taskbar Task View Icon", "Description": "Toggles the Task View Button in the Taskbar.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", "Name": "ShowTaskViewButton", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/taskview" }, "WPFToggleGameMode": { "Content": "Game Mode", "Description": "Toggles Windows prioritizes gaming performance by allocating system resources to games.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKCU:\\Software\\Microsoft\\GameBar", "Name": "AllowAutoGameMode", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" }, { "Path": "HKCU:\\Software\\Microsoft\\GameBar", "Name": "AutoGameModeEnabled", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "true" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/gamemode" }, "WPFToggleLongPaths": { "Content": "Enable Long Paths", "Description": "Toggles support for file paths longer than 260 characters in Explorer.", "category": "Customize Preferences", "panel": "2", "Type": "Toggle", "registry": [ { "Path": "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\FileSystem", "Name": "LongPathsEnabled", "Value": "1", "Type": "DWord", "OriginalValue": "0", "DefaultState": "false" } ], "link": "https://winutil.christitus.com/dev/tweaks/customize-preferences/longpaths" }, "WPFOOSUbutton": { "Content": "O\u0026O ShutUp10++ - Run", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "Type": "Button", "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/oosubutton" }, "WPFchangedns": { "Content": "DNS - Set to:", "category": "z__Advanced Tweaks - CAUTION", "panel": "1", "Type": "Combobox", "ComboItems": "Default DHCP Google Cloudflare Cloudflare_Malware Cloudflare_Malware_Adult Open_DNS Quad9 AdGuard_Ads_Trackers AdGuard_Ads_Trackers_Malware_Adult", "link": "https://winutil.christitus.com/dev/tweaks/z--advanced-tweaks---caution/changedns" }, "WPFAddUltPerf": { "Content": "Ultimate Performance Profile - Enable", "category": "Performance Plans - NOT FOR LAPTOPS", "panel": "2", "Type": "Button", "ButtonWidth": "300", "link": "https://winutil.christitus.com/dev/tweaks/performance-plans---not-for-laptops/addultperf" }, "WPFRemoveUltPerf": { "Content": "Ultimate Performance Profile - Disable", "category": "Performance Plans - NOT FOR LAPTOPS", "panel": "2", "Type": "Button", "ButtonWidth": "300", "link": "https://winutil.christitus.com/dev/tweaks/performance-plans---not-for-laptops/removeultperf" } } '@ | ConvertFrom-Json $inputXML = @' Install Tweaks Config Updates Win11 Creator AppX Removal