Fix progress, update profiles, and documentation links (#4845)

* Improve O&O ShutUp10++ download flow

* Refine Windows Update profile behavior and docs

* Fix documentation link regressions

* Restore updates when applying recommended profile
This commit is contained in:
Chris Titus
2026-07-15 23:36:46 -05:00
committed by GitHub
parent 9ed06e793a
commit 29595f90e2
14 changed files with 669 additions and 205 deletions
@@ -0,0 +1,8 @@
---
title: "Xbox and Gaming Components - Removal"
description: "Xbox package management has moved to AppX Removal."
---
The former Xbox Removal tweak has been replaced by the AppX Removal tool.
Open **Tweaks**, select **AppX Removal**, and choose the Xbox or gaming packages you want to remove or reinstall. See the [AppX Packages guide](/userguide/tweaks/#appx-packages) for details.
+14 -12
View File
@@ -9,28 +9,30 @@ WinUtil provides three update modes so you can choose how aggressively Windows U
Changing modes adjusts system-wide Windows Update behavior. After switching modes, give Windows a moment to apply the policy and plan for a restart if the new state does not appear immediately.
{{< image src="images/updates-tab-new" alt="Updates tab in WinUtil" >}}
- **Recommended**: Prioritizes stability while still receiving security updates
- **Windows Default**: Restores standard Windows Update behavior
- **Disable Updates**: Blocks Windows Update and should only be used with extreme caution
- **Default (Out of the Box) Settings**: Restores standard Windows Update behavior
- **Security (Recommended) Settings**: Prioritizes stability while still receiving security updates
- **Disable ALL Updates**: Turns off Windows Update entirely and should only be used with extreme caution
### Windows Default
### Default (Out of Box) Settings
- **What it does**: Restores the default Windows Update configuration.
- **What it does**: Removes Windows Update policies managed by WinUtil, restores update service startup settings, and re-enables update scheduled tasks.
- **Best for**: Systems where you want Windows to manage updates normally.
- **Notes**: This removes custom update settings previously applied by WinUtil. If update errors continue, use the reset option in the **Config** tab to restore Microsoft Update services to their default state.
- **Notes**: Only values managed by WinUtil are removed; other Windows Update policies are left in place. If update errors continue, use the reset option in the **Config** tab to repair Microsoft Update components.
### Security (Recommended) Settings
### Recommended
- **What it does**: Applies a more conservative update strategy designed for most users.
- **Feature updates**: Delayed by **365 days** to reduce the chance of disruption from major Windows changes.
- **Security updates**: Delayed by **4 days** to allow time for early issues to surface while still keeping the system protected.
- **Quality updates**: Delayed by **4 days** to allow time for early issues to surface while still keeping the system protected.
- **Drivers**: Excluded from Windows quality updates.
- **Restarts**: Scheduled updates do not automatically restart Windows while a user is signed in. A restart explicitly scheduled by a user still takes precedence.
- **Availability**: Update deferral policies apply to Windows Pro, Enterprise, and Education editions.
- **Why use it**: This mode offers the best balance between security and stability, which is why it is the recommended option for most PCs.
### Disable ALL Updates (NOT RECOMMENDED!)
### Disable Updates (NOT RECOMMENDED!)
- **What it does**: Disables all Windows updates.
- **What it does**: Disables automatic update policy, stops and disables update services, disables update scheduled tasks, and clears downloaded update files.
- **Best for**: Highly controlled or special-purpose systems where updates must remain off temporarily.
- **Warning**: This leaves the system without security patches and significantly increases security risk.
- **Notes**: Windows servicing can restore update components in some circumstances. Use **Restore Defaults** when you are ready to receive updates again.
- **Recommendation**: Avoid this mode unless you fully understand the tradeoffs and have a specific reason to use it.
+59
View File
@@ -0,0 +1,59 @@
function Save-WinUtilFile {
<#
.SYNOPSIS
Downloads a file and reports transfer progress.
#>
param(
[Parameter(Mandatory)]
[uri]$Uri,
[Parameter(Mandatory)]
[string]$DestinationPath,
[Parameter(Mandatory)]
[scriptblock]$ProgressCallback
)
$response = $null
$responseStream = $null
$outputStream = $null
try {
$request = [System.Net.WebRequest]::Create($Uri)
$response = $request.GetResponse()
$totalBytes = $response.ContentLength
$responseStream = $response.GetResponseStream()
$outputStream = [System.IO.File]::Create($DestinationPath)
$buffer = New-Object byte[] 81920
$downloadedBytes = 0L
$lastPercent = -1
while (($bytesRead = $responseStream.Read($buffer, 0, $buffer.Length)) -gt 0) {
$outputStream.Write($buffer, 0, $bytesRead)
$downloadedBytes += $bytesRead
if ($totalBytes -gt 0) {
$percent = [Math]::Min(100, [int](($downloadedBytes / $totalBytes) * 100))
if ($percent -ne $lastPercent) {
& $ProgressCallback $percent
$lastPercent = $percent
}
}
}
if ($lastPercent -ne 100) {
& $ProgressCallback 100
}
}
finally {
if ($null -ne $outputStream) {
$outputStream.Dispose()
}
if ($null -ne $responseStream) {
$responseStream.Dispose()
}
if ($null -ne $response) {
$response.Dispose()
}
}
}
+45 -7
View File
@@ -1,12 +1,50 @@
function Invoke-WPFOOSU {
try {
$ProgressPreference = 'SilentlyContinue'
if ($sync.ProcessRunning) {
Show-WinUtilMessage -Message "Another process is currently running." -Title "WinUtil" -Button "OK" -Icon "Warning"
return
}
Invoke-WebRequest -Uri https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe -OutFile "$winutildir\ooshutup10.exe"
Start-Process -FilePath "$winutildir\ooshutup10.exe"
$downloadPath = Join-Path $sync.winutildir "ooshutup10.exe"
$sync.ProcessRunning = $true
$ProgressPreference = 'Continue'
} catch {
Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection."
Invoke-WPFRunspace -ParameterList @(,("downloadPath", $downloadPath)) -ScriptBlock {
param($downloadPath)
$hasUI = $null -ne $sync.Form -and $null -ne $sync.Form.Dispatcher
try {
Write-WinUtilLog -Component "OOSU" -Message "Downloading O&O ShutUp10++."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Downloading O&O ShutUp10++ (0%)" -Percent 0
}
Save-WinUtilFile -Uri "https://dl5.oo-software.com/files/ooshutup10/OOSU10.exe" -DestinationPath $downloadPath -ProgressCallback {
param($percent)
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Downloading O&O ShutUp10++ ($percent%)" -Percent $percent
}
}
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "Launching O&O ShutUp10++" -Percent 100
}
Start-Process -FilePath $downloadPath
Write-WinUtilLog -Component "OOSU" -Message "O&O ShutUp10++ launched."
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "O&O ShutUp10++ launched" -Percent 100
}
}
catch {
Write-WinUtilLog -Level "ERROR" -Component "OOSU" -Message "O&O ShutUp10++ download failed: $($_.Exception.Message)"
if ($hasUI) {
Set-WinUtilTweaksProgressIndicator -Visible $true -Label "O&O ShutUp10++ download failed" -Percent 100
}
Write-Error "Couldn't download O&O ShutUp10. Please make sure you have an active Internet connection."
}
finally {
$sync.ProcessRunning = $false
}
}
}
+6 -1
View File
@@ -404,11 +404,16 @@ function Invoke-WPFUIElements {
$textBlock.ToolTip = $entryInfo.Link
$textBlock.Style = $HoverTextBlockStyle
$textBlock.UseLayoutRounding = $true
$textBlock.VerticalAlignment = "Center"
$textBlock.SetResourceReference([Windows.Controls.Control]::FontSizeProperty, "FontSize")
$textBlock.Tag = $checkBox
$textBlock.Add_MouseUp({
[System.Object]$Sender = $args[0]
Start-Process $Sender.ToolTip -ErrorAction Stop
})
$updateLinkMargin = {
[System.Object]$Sender = $args[0]
$linkedCheckBox = $Sender.Tag
+43 -22
View File
@@ -5,22 +5,51 @@ function Invoke-WPFUpdatesdefault {
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."
Write-Host "Removing Windows Update settings managed by WinUtil..." -ForegroundColor Green
Write-WinUtilLog -Component "Updates" -Message "Removing Windows Update registry values managed by WinUtil."
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
$registryValues = @(
@{
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
Names = @("NoAutoUpdate", "AUOptions", "NoAutoRebootWithLoggedOnUsers", "AUPowerManagement")
},
@{
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
Names = @("ExcludeWUDriversInQualityUpdate", "DeferFeatureUpdates", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdates", "DeferQualityUpdatesPeriodInDays")
},
@{
Path = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"
Names = @("BranchReadinessLevel", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdatesPeriodInDays")
},
@{
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata"
Names = @("PreventDeviceMetadataFromNetwork")
},
@{
Path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching"
Names = @("DontPromptForWindowsUpdate", "DontSearchWindowsUpdate", "DriverUpdateWizardWuSearchEnabled")
},
@{
Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config"
Names = @("DODownloadMode")
}
)
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
foreach ($registryEntry in $registryValues) {
foreach ($valueName in $registryEntry.Names) {
Remove-ItemProperty -Path $registryEntry.Path -Name $valueName -ErrorAction SilentlyContinue
}
}
$explorerPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
$settingsPageVisibility = (Get-ItemProperty -Path $explorerPolicyPath -Name "SettingsPageVisibility" -ErrorAction SilentlyContinue).SettingsPageVisibility
if ($settingsPageVisibility -eq "hide:windowsupdate") {
Write-Host "Removing WinUtil's legacy Windows Update page restriction..."
Write-WinUtilLog -Component "Updates" -Message "Removing the legacy Windows Update settings page restriction."
Remove-ItemProperty -Path $explorerPolicyPath -Name "SettingsPageVisibility" -ErrorAction SilentlyContinue
}
Write-Host "Reenabling Windows Update Services..." -ForegroundColor Green
Write-WinUtilLog -Component "Updates" -Message "Restoring Windows Update service startup types."
@@ -35,12 +64,8 @@ function Invoke-WPFUpdatesdefault {
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
Start-Service -Name UsoSvc
Write-Host "Enabling update related scheduled tasks..." -ForegroundColor Green
Write-WinUtilLog -Component "Updates" -Message "Enabling update related scheduled tasks."
@@ -54,13 +79,9 @@ function Invoke-WPFUpdatesdefault {
'\Microsoft\WindowsUpdate\*'
foreach ($Task in $Tasks) {
Get-ScheduledTask -TaskPath $Task | Enable-ScheduledTask -ErrorAction SilentlyContinue
Get-ScheduledTask -TaskPath $Task -ErrorAction SilentlyContinue | 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
+20 -20
View File
@@ -8,7 +8,17 @@ function Invoke-WPFUpdatesdisable {
Disabling Windows Update is not recommended. This is only for advanced users who know what they are doing.
#>
$ErrorActionPreference = 'SilentlyContinue'
$confirmation = Show-WinUtilMessage `
-Message "Disabling Windows Update stops update services, disables scheduled tasks, and clears downloaded update files. Security updates will not be installed until defaults are restored. Continue?" `
-Title "Disable Windows Update?" `
-Button "YesNo" `
-Icon "Warning"
if ($confirmation -ne "Yes") {
Write-WinUtilLog -Component "Updates" -Message "Windows Update disable workflow cancelled."
return
}
Write-WinUtilLog -Component "Updates" -Message "Disabling Windows Update settings."
Write-Host "Configuring registry settings..." -ForegroundColor Yellow
@@ -21,24 +31,14 @@ function Invoke-WPFUpdatesdisable {
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
foreach ($serviceName in @("BITS", "wuauserv", "UsoSvc")) {
Write-Host "Stopping and disabling $serviceName service."
Write-WinUtilLog -Component "Updates" -Message "Stopping and disabling $serviceName service."
Stop-Service -Name $serviceName -Force -ErrorAction SilentlyContinue
Set-Service -Name $serviceName -StartupType Disabled
}
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
Remove-Item -Path "C:\Windows\SoftwareDistribution\*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Cleared SoftwareDistribution folder."
Write-WinUtilLog -Component "Updates" -Message "Cleared SoftwareDistribution folder."
@@ -54,11 +54,11 @@ function Invoke-WPFUpdatesdisable {
'\Microsoft\WindowsUpdate\*'
foreach ($Task in $Tasks) {
Get-ScheduledTask -TaskPath $Task | Disable-ScheduledTask -ErrorAction SilentlyContinue
Get-ScheduledTask -TaskPath $Task -ErrorAction SilentlyContinue | Disable-ScheduledTask -ErrorAction SilentlyContinue
}
Write-Host "=================================" -ForegroundColor Green
Write-Host "--- Updates Are Disabled ---" -ForegroundColor Green
Write-Host "--- Windows Update Is 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
+47 -16
View File
@@ -6,10 +6,9 @@ function Invoke-WPFUpdatessecurity {
.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
2. Defers feature updates for 365 days
3. Defers quality updates for 4 days
4. Prevents automatic restarts while a user is signed in
#>
@@ -17,6 +16,32 @@ function Invoke-WPFUpdatessecurity {
Write-WinUtilLog -Component "Updates" -Message "Applying recommended Windows Update settings."
Write-WinUtilLog -Component "Updates" -Message "Disabling driver offering through Windows Update."
$windowsUpdatePolicyPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$automaticUpdatePolicyPath = Join-Path $windowsUpdatePolicyPath "AU"
Write-Host "Restoring Windows Update availability..."
Write-WinUtilLog -Component "Updates" -Message "Restoring Windows Update services and scheduled tasks before applying recommended settings."
Remove-ItemProperty -Path $automaticUpdatePolicyPath -Name "NoAutoUpdate" -ErrorAction SilentlyContinue
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -Name "DODownloadMode" -ErrorAction SilentlyContinue
Set-Service -Name BITS -StartupType Manual
Set-Service -Name wuauserv -StartupType Manual
Set-Service -Name UsoSvc -StartupType Automatic
Start-Service -Name UsoSvc
$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 -ErrorAction SilentlyContinue | Enable-ScheduledTask -ErrorAction SilentlyContinue
}
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
@@ -26,24 +51,30 @@ function Invoke-WPFUpdatessecurity {
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
New-Item -Path $windowsUpdatePolicyPath -Force
Set-ItemProperty -Path $windowsUpdatePolicyPath -Name "ExcludeWUDriversInQualityUpdate" -Type DWord -Value 1
Write-Host "Setting cumulative updates back by 1 year and security updates by 4 days..."
Write-Host "Deferring feature updates by 365 days and quality 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 $windowsUpdatePolicyPath -Name "DeferFeatureUpdates" -Type DWord -Value 1
Set-ItemProperty -Path $windowsUpdatePolicyPath -Name "DeferFeatureUpdatesPeriodInDays" -Type DWord -Value 365
Set-ItemProperty -Path $windowsUpdatePolicyPath -Name "DeferQualityUpdates" -Type DWord -Value 1
Set-ItemProperty -Path $windowsUpdatePolicyPath -Name "DeferQualityUpdatesPeriodInDays" -Type DWord -Value 4
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
$legacySettingsPath = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"
foreach ($legacyValue in @("BranchReadinessLevel", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdatesPeriodInDays")) {
Remove-ItemProperty -Path $legacySettingsPath -Name $legacyValue -ErrorAction SilentlyContinue
}
Write-Host "Disabling Windows Update automatic restart..."
Write-WinUtilLog -Component "Updates" -Message "Disabling Windows Update automatic restart while users are logged in."
Write-Host "Preventing automatic restarts while users are signed in..."
Write-WinUtilLog -Component "Updates" -Message "Configuring scheduled automatic updates without restarting while users are signed 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
New-Item -Path $automaticUpdatePolicyPath -Force
# NoAutoRebootWithLoggedOnUsers only applies when automatic updates use option 4.
Set-ItemProperty -Path $automaticUpdatePolicyPath -Name "AUOptions" -Type DWord -Value 4
Set-ItemProperty -Path $automaticUpdatePolicyPath -Name "NoAutoRebootWithLoggedOnUsers" -Type DWord -Value 1
Set-ItemProperty -Path $automaticUpdatePolicyPath -Name "AUPowerManagement" -Type DWord -Value 0
Write-Host "================================="
Write-Host "-- Updates Set to Recommended ---"
+8
View File
@@ -113,4 +113,12 @@ Describe "Startup lazy tab wiring" {
$rendererScript | Should -Match '\$sync\.Buttons\.Add\(\$button\.Name\)'
$mainScript | Should -Match '\$sync\.Buttons -notcontains \$psitem'
}
It "binds generated documentation links when lazy panels are rendered" {
$rendererScript = Get-Content -Path (Join-Path $script:repoRoot "functions\public\Invoke-WPFUIElements.ps1") -Raw
$mainScript = Get-Content -Path (Join-Path $script:repoRoot "scripts\main.ps1") -Raw
$rendererScript | Should -Match '(?s)if \(\$entryInfo\.Link\).*\$textBlock\.Add_MouseUp\(\{.*Start-Process \$Sender\.ToolTip -ErrorAction Stop'
$mainScript | Should -Not -Match '\.Name\.EndsWith\("Link"\)'
}
}
+139
View File
@@ -0,0 +1,139 @@
#===========================================================================
# Tests - O&O ShutUp10++ Download Workflow
#===========================================================================
BeforeAll {
$script:repoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
. (Join-Path $script:repoRoot "functions\private\Save-WinUtilFile.ps1")
. (Join-Path $script:repoRoot "functions\public\Invoke-WPFOOSU.ps1")
function Invoke-WPFRunspace {
param($ArgumentList, $ParameterList, [scriptblock]$ScriptBlock)
}
function Set-WinUtilTweaksProgressIndicator {
param($Visible, $Label, $Percent)
}
function Show-WinUtilMessage {
param($Message, $Title, $Button, $Icon)
}
function Write-WinUtilLog {
param($Message, $Level, $Component)
}
function script:New-WinUtilOOSUTestContext {
param([bool]$ProcessRunning = $false)
$script:sync = [Hashtable]::Synchronized(@{
ProcessRunning = $ProcessRunning
winutildir = $TestDrive
Form = [pscustomobject]@{
Dispatcher = [pscustomobject]@{}
}
})
}
}
Describe "Save-WinUtilFile" {
It "copies a download and reports its percentage" {
$sourcePath = Join-Path $TestDrive "source.bin"
$destinationPath = Join-Path $TestDrive "destination.bin"
$sourceBytes = [byte[]](0..255)
[System.IO.File]::WriteAllBytes($sourcePath, $sourceBytes)
$reportedProgress = [System.Collections.Generic.List[int]]::new()
Save-WinUtilFile -Uri ([uri]$sourcePath) -DestinationPath $destinationPath -ProgressCallback {
param($percent)
$reportedProgress.Add($percent)
}
[System.IO.File]::ReadAllBytes($destinationPath) | Should -Be $sourceBytes
$reportedProgress[-1] | Should -Be 100
}
}
Describe "Invoke-WPFOOSU" {
BeforeEach {
New-WinUtilOOSUTestContext
$script:capturedScriptBlock = $null
$script:capturedParameterList = $null
Mock Invoke-WPFRunspace {
$script:capturedScriptBlock = $ScriptBlock
$script:capturedParameterList = $ParameterList
[pscustomobject]@{ MockHandle = $true }
}
Mock Set-WinUtilTweaksProgressIndicator { }
Mock Show-WinUtilMessage { }
Mock Write-WinUtilLog { }
Mock Start-Process { }
Mock Write-Error { }
}
AfterEach {
Remove-Variable -Name sync -Scope Script -ErrorAction SilentlyContinue
Remove-Variable -Name capturedScriptBlock -Scope Script -ErrorAction SilentlyContinue
Remove-Variable -Name capturedParameterList -Scope Script -ErrorAction SilentlyContinue
}
It "queues the download in a background runspace" {
Invoke-WPFOOSU
$script:sync.ProcessRunning | Should -BeTrue
Should -Invoke Invoke-WPFRunspace -Times 1 -Exactly
$script:capturedParameterList[0][0] | Should -Be "downloadPath"
$script:capturedParameterList[0][1] | Should -Be (Join-Path $TestDrive "ooshutup10.exe")
}
It "does not start while another process is running" {
New-WinUtilOOSUTestContext -ProcessRunning $true
Invoke-WPFOOSU
Should -Invoke Show-WinUtilMessage -Times 1 -Exactly -ParameterFilter {
$Message -eq "Another process is currently running." -and
$Title -eq "WinUtil" -and
$Button -eq "OK" -and
$Icon -eq "Warning"
}
Should -Not -Invoke Invoke-WPFRunspace
}
It "maps download progress to the window indicator and launches O&O ShutUp10++" {
Mock Save-WinUtilFile {
& $ProgressCallback 35
& $ProgressCallback 100
}
Invoke-WPFOOSU
& $script:capturedScriptBlock -downloadPath $script:capturedParameterList[0][1]
Should -Invoke Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
$Visible -eq $true -and $Label -eq "Downloading O&O ShutUp10++ (0%)" -and $Percent -eq 0
}
Should -Invoke Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
$Visible -eq $true -and $Label -eq "Downloading O&O ShutUp10++ (35%)" -and $Percent -eq 35
}
Should -Invoke Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
$Visible -eq $true -and $Label -eq "O&O ShutUp10++ launched" -and $Percent -eq 100
}
Should -Invoke Start-Process -Times 1 -Exactly -ParameterFilter {
$FilePath -eq (Join-Path $TestDrive "ooshutup10.exe")
}
$script:sync.ProcessRunning | Should -BeFalse
}
It "shows failure progress and clears the running state when the download fails" {
Mock Save-WinUtilFile { throw "download failed" }
Invoke-WPFOOSU
& $script:capturedScriptBlock -downloadPath $script:capturedParameterList[0][1]
Should -Invoke Set-WinUtilTweaksProgressIndicator -Times 1 -Exactly -ParameterFilter {
$Visible -eq $true -and $Label -eq "O&O ShutUp10++ download failed" -and $Percent -eq 100
}
Should -Not -Invoke Start-Process
Should -Invoke Write-Error -Times 1 -Exactly
$script:sync.ProcessRunning | Should -BeFalse
}
}
+136 -36
View File
@@ -11,8 +11,11 @@ BeforeAll {
function Write-WinUtilLog {
param($Message, $Level, $Component)
}
function Show-WinUtilMessage {
param($Message, $Title, $Button, $Icon)
}
function Get-ScheduledTask {
param($TaskPath)
param($TaskPath, $ErrorAction)
}
function Disable-ScheduledTask {
param(
@@ -51,6 +54,7 @@ Describe "Invoke-WPFUpdatesdisable" {
BeforeEach {
Mock Write-Host { }
Mock Write-WinUtilLog { }
Mock Show-WinUtilMessage { "Yes" }
Mock New-Item { }
Mock Set-ItemProperty { }
Mock Set-Service { }
@@ -88,25 +92,23 @@ Describe "Invoke-WPFUpdatesdisable" {
$Type -eq "DWord" -and
$Value -eq 0
}
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -and
$Name -eq "SettingsPageVisibility" -and
$Value -eq "hide:windowsupdate"
}
}
It "disables update services and clears the SoftwareDistribution folder" {
Invoke-WPFUpdatesdisable
foreach ($expectedServiceName in @("BITS", "wuauserv", "UsoSvc")) {
$expected = $expectedServiceName
Should -Invoke -CommandName Stop-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq $expected -and $Force -eq $true
}
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "BITS" -and $StartupType -eq "Disabled"
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "wuauserv" -and $StartupType -eq "Disabled"
}
Should -Invoke -CommandName Stop-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "UsoSvc" -and $Force -eq $true
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "UsoSvc" -and $StartupType -eq "Disabled"
}
@@ -128,6 +130,21 @@ Describe "Invoke-WPFUpdatesdisable" {
}
Should -Invoke -CommandName Disable-ScheduledTask -Times $script:updateTaskPaths.Count -Exactly
}
It "requires confirmation before disabling updates" {
Mock Show-WinUtilMessage { "No" }
Invoke-WPFUpdatesdisable
Should -Invoke Show-WinUtilMessage -Times 1 -Exactly -ParameterFilter {
$Title -eq "Disable Windows Update?" -and
$Button -eq "YesNo" -and
$Icon -eq "Warning"
}
Should -Not -Invoke Set-ItemProperty
Should -Not -Invoke Set-Service
Should -Not -Invoke Remove-Item
}
}
Describe "Invoke-WPFUpdatesdefault" {
@@ -136,6 +153,11 @@ Describe "Invoke-WPFUpdatesdefault" {
Mock Write-WinUtilLog { }
Mock Remove-Item { }
Mock Remove-ItemProperty { }
Mock Get-ItemProperty {
[pscustomobject]@{
SettingsPageVisibility = "hide:windowsupdate"
}
}
Mock Set-Service { }
Mock Start-Service { }
Mock Get-ScheduledTask {
@@ -147,30 +169,49 @@ Describe "Invoke-WPFUpdatesdefault" {
Mock secedit { }
}
It "removes update policy registry paths and shows the Windows Update settings page" {
It "removes only registry values managed by WinUtil" {
Invoke-WPFUpdatesdefault
$expectedPaths = @(
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization",
"HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings",
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata",
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching",
"HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$expectedRegistryValues = @(
@("HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU", "NoAutoUpdate", "AUOptions", "NoAutoRebootWithLoggedOnUsers", "AUPowerManagement"),
@("HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate", "ExcludeWUDriversInQualityUpdate", "DeferFeatureUpdates", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdates", "DeferQualityUpdatesPeriodInDays"),
@("HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings", "BranchReadinessLevel", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdatesPeriodInDays"),
@("HKLM:\SOFTWARE\Policies\Microsoft\Windows\Device Metadata", "PreventDeviceMetadataFromNetwork"),
@("HKLM:\SOFTWARE\Policies\Microsoft\Windows\DriverSearching", "DontPromptForWindowsUpdate", "DontSearchWindowsUpdate", "DriverUpdateWizardWuSearchEnabled"),
@("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config", "DODownloadMode")
)
foreach ($expectedRegistryPath in $expectedPaths) {
$expected = $expectedRegistryPath
Should -Invoke -CommandName Remove-Item -Times 1 -Exactly -ParameterFilter {
$Path -eq $expected -and $Recurse -eq $true -and $Force -eq $true
foreach ($expectedEntry in $expectedRegistryValues) {
$expectedPath = $expectedEntry[0]
foreach ($expectedName in $expectedEntry[1..($expectedEntry.Count - 1)]) {
$valueName = $expectedName
Should -Invoke -CommandName Remove-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq $expectedPath -and $Name -eq $valueName
}
}
}
Should -Not -Invoke Remove-Item
Should -Invoke -CommandName Remove-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -and
$Name -eq "SettingsPageVisibility"
}
}
It "preserves unrelated Settings page visibility policy" {
Mock Get-ItemProperty {
[pscustomobject]@{
SettingsPageVisibility = "hide:privacy"
}
}
Invoke-WPFUpdatesdefault
Should -Not -Invoke Remove-ItemProperty -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer" -and
$Name -eq "SettingsPageVisibility"
}
}
It "restores update service startup types" {
Invoke-WPFUpdatesdefault
@@ -186,12 +227,12 @@ Describe "Invoke-WPFUpdatesdefault" {
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "UsoSvc" -and $StartupType -eq "Automatic"
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "WaaSMedicSvc" -and $StartupType -eq "Manual"
Should -Not -Invoke Set-Service -ParameterFilter {
$Name -eq "WaaSMedicSvc"
}
}
It "enables update scheduled task paths and resets local policy defaults" {
It "enables update scheduled task paths without resetting unrelated local security policy" {
Invoke-WPFUpdatesdefault
foreach ($expectedTaskPath in $script:updateTaskPaths) {
@@ -201,13 +242,7 @@ Describe "Invoke-WPFUpdatesdefault" {
}
}
Should -Invoke -CommandName Enable-ScheduledTask -Times $script:updateTaskPaths.Count -Exactly
Should -Invoke -CommandName secedit -Times 1 -Exactly -ParameterFilter {
$Arguments[0] -eq "/configure" -and
$Arguments[1] -eq "/cfg" -and
$Arguments[2] -like "*\inf\defltbase.inf" -and
$Arguments[3] -eq "/db" -and
$Arguments[4] -eq "defltbase.sdb"
}
Should -Not -Invoke secedit
}
}
@@ -217,6 +252,47 @@ Describe "Invoke-WPFUpdatessecurity" {
Mock Write-WinUtilLog { }
Mock New-Item { }
Mock Set-ItemProperty { }
Mock Remove-ItemProperty { }
Mock Set-Service { }
Mock Start-Service { }
Mock Get-ScheduledTask {
[pscustomobject]@{
TaskPath = $TaskPath
}
}
Mock Enable-ScheduledTask { }
}
It "restores update availability before applying recommended settings" {
Invoke-WPFUpdatessecurity
Should -Invoke -CommandName Remove-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -and
$Name -eq "NoAutoUpdate"
}
Should -Invoke -CommandName Remove-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\DeliveryOptimization\Config" -and
$Name -eq "DODownloadMode"
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "BITS" -and $StartupType -eq "Manual"
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "wuauserv" -and $StartupType -eq "Manual"
}
Should -Invoke -CommandName Set-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "UsoSvc" -and $StartupType -eq "Automatic"
}
Should -Invoke -CommandName Start-Service -Times 1 -Exactly -ParameterFilter {
$Name -eq "UsoSvc"
}
foreach ($expectedTaskPath in $script:updateTaskPaths) {
$expected = $expectedTaskPath
Should -Invoke -CommandName Get-ScheduledTask -Times 1 -Exactly -ParameterFilter {
$TaskPath -eq $expected
}
}
Should -Invoke -CommandName Enable-ScheduledTask -Times $script:updateTaskPaths.Count -Exactly
}
It "disables driver metadata and Windows Update driver search" {
@@ -261,23 +337,35 @@ Describe "Invoke-WPFUpdatessecurity" {
Invoke-WPFUpdatessecurity
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -and
$Name -eq "BranchReadinessLevel" -and
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -and
$Name -eq "DeferFeatureUpdates" -and
$Type -eq "DWord" -and
$Value -eq 20
$Value -eq 1
}
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -and
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -and
$Name -eq "DeferFeatureUpdatesPeriodInDays" -and
$Type -eq "DWord" -and
$Value -eq 365
}
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -and
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -and
$Name -eq "DeferQualityUpdates" -and
$Type -eq "DWord" -and
$Value -eq 1
}
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" -and
$Name -eq "DeferQualityUpdatesPeriodInDays" -and
$Type -eq "DWord" -and
$Value -eq 4
}
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -and
$Name -eq "AUOptions" -and
$Type -eq "DWord" -and
$Value -eq 4
}
Should -Invoke -CommandName Set-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -and
$Name -eq "NoAutoRebootWithLoggedOnUsers" -and
@@ -291,4 +379,16 @@ Describe "Invoke-WPFUpdatessecurity" {
$Value -eq 0
}
}
It "removes legacy WinUtil deferral values from the unsupported UX settings path" {
Invoke-WPFUpdatessecurity
foreach ($expectedValueName in @("BranchReadinessLevel", "DeferFeatureUpdatesPeriodInDays", "DeferQualityUpdatesPeriodInDays")) {
$expected = $expectedValueName
Should -Invoke Remove-ItemProperty -Times 1 -Exactly -ParameterFilter {
$Path -eq "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings" -and
$Name -eq $expected
}
}
}
}
+17 -1
View File
@@ -152,7 +152,6 @@ Describe "XAML document" {
"appspanel",
"tweakspanel",
"featurespanel",
"updatespanel",
"appxpanel",
"WPFstandard",
"WPFminimal",
@@ -180,6 +179,23 @@ Describe "XAML document" {
}
}
It "presents the three Updates profiles with accurate action labels" {
$updatesTab = $script:xaml.SelectSingleNode('//*[local-name()="TabItem"][@Name="WPFTab4"]')
$profileGrid = $updatesTab.SelectSingleNode('.//*[local-name()="UniformGrid"]')
$expectedButtons = @{
WPFUpdatessecurity = "Apply Recommended"
WPFUpdatesdefault = "Restore Defaults"
WPFUpdatesdisable = "Disable Updates"
}
$profileGrid.GetAttribute("Columns") | Should -Be "3"
foreach ($buttonName in $expectedButtons.Keys) {
$button = $updatesTab.SelectSingleNode(".//*[local-name()='Button'][@Name='$buttonName']")
$button.GetAttribute("Content") | Should -Be $expectedButtons[$buttonName]
}
$updatesTab.SelectSingleNode('.//*[@Name="updatespanel"]') | Should -BeNullOrEmpty
}
It "contains Win11 Creator controls used by the ISO workflow" {
$xamlNames = @(Get-WinUtilXamlRuntimeNamedControls | ForEach-Object { $_.Name })
$requiredControls = @(
-12
View File
@@ -128,9 +128,6 @@ Invoke-WinutilThemeChange -theme $sync.preferences.theme
$sync.InitializedTabs = @{}
Initialize-WinUtilTabContent -TabName "Install"
# Future implementation: Add Windows Version to updates panel
#Invoke-WPFUIElements -configVariable $sync.configs.updates -targetGridName "updatespanel" -columncount 1
#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================
@@ -171,15 +168,6 @@ $sync.keys | ForEach-Object {
}
}
if ($($sync["$psitem"].GetType() | Select-Object -ExpandProperty Name) -eq "TextBlock") {
if ($sync["$psitem"].Name.EndsWith("Link")) {
$sync["$psitem"].Add_MouseUp({
[System.Object]$Sender = $args[0]
Start-Process $Sender.ToolTip -ErrorAction Stop
})
}
}
}
}
+127 -78
View File
@@ -1366,99 +1366,148 @@
</TabItem>
<TabItem Header="Updates" Visibility="Collapsed" Name="WPFTab4">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="{DynamicResource TabContentMargin}">
<Grid Background="Transparent" MaxWidth="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ScrollViewer}}">
<Grid Background="Transparent" MaxWidth="1250" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <!-- Row for the 3 columns -->
<RowDefinition Height="Auto"/> <!-- Row for Windows Version -->
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Three columns container -->
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Margin="10,10,10,14">
<TextBlock Text="Windows Update Profiles"
FontSize="24"
FontWeight="Bold"
Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="Choose how Windows receives updates. Each profile replaces the Windows Update settings managed by WinUtil."
Margin="0,6,0,0"
FontSize="13"
TextWrapping="Wrap"
Foreground="{DynamicResource MainForegroundColor}"/>
</StackPanel>
<!-- Default Settings -->
<Border Grid.Column="0" Style="{StaticResource BorderStyle}">
<StackPanel>
<Button Name="WPFUpdatesdefault"
FontSize="{DynamicResource ConfigTabButtonFontSize}"
Content="Default Settings"
Margin="10,5"
Padding="10"/>
<TextBlock Margin="10"
TextWrapping="Wrap"
Foreground="{DynamicResource MainForegroundColor}">
<Run FontWeight="Bold">Default Windows Update Configuration</Run>
<LineBreak/>
- No modifications to Windows defaults
<LineBreak/>
- Removes any custom update settings
<LineBreak/><LineBreak/>
<Run FontStyle="Italic" FontSize="11">Note: This resets your Windows Update settings to default out of the box settings. It removes ANY policy or customization that has been done to Windows Update.</Run>
</TextBlock>
</StackPanel>
</Border>
<!-- Security Settings -->
<Border Grid.Column="1" Style="{StaticResource BorderStyle}">
<StackPanel>
<UniformGrid Grid.Row="1" Columns="3">
<Border Style="{StaticResource BorderStyle}"
BorderBrush="{DynamicResource ProgressBarForegroundColor}"
BorderThickness="2"
Padding="16"
MinHeight="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,14">
<TextBlock Text="Recommended"
FontSize="20"
FontWeight="Bold"
Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="Balanced security and stability"
Margin="0,4,0,0"
FontSize="13"
Foreground="{DynamicResource MainForegroundColor}"/>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock Text="- Defers feature updates for 365 days" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Defers quality updates for 4 days" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Excludes drivers from quality updates" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Prevents automatic restarts while a user is signed in" TextWrapping="Wrap" Margin="0,0,0,12" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="Available on Windows Pro, Enterprise, and Education editions."
FontSize="11"
FontStyle="Italic"
TextWrapping="Wrap"
Foreground="{DynamicResource MainForegroundColor}"/>
</StackPanel>
<Button Name="WPFUpdatessecurity"
Grid.Row="2"
Content="Apply Recommended"
FontSize="{DynamicResource ConfigTabButtonFontSize}"
Content="Security Settings"
Margin="10,5"
Margin="0,16,0,0"
Padding="10"/>
<TextBlock Margin="10"
TextWrapping="Wrap"
Foreground="{DynamicResource MainForegroundColor}">
<Run FontWeight="Bold">Balanced Security Configuration</Run>
<LineBreak/>
- Feature updates delayed by 365 days
<LineBreak/>
- Security updates installed after 4 days
<LineBreak/>
- Prevents Windows Update from installing drivers
<LineBreak/><LineBreak/>
<Run FontWeight="SemiBold">Feature Updates:</Run> New features and potential bugs
<LineBreak/>
<Run FontWeight="SemiBold">Security Updates:</Run> Critical security patches
<LineBreak/><LineBreak/>
<Run FontStyle="Italic" FontSize="11">Note: This only applies to Pro systems that can use group policy.</Run>
</TextBlock>
</StackPanel>
</Grid>
</Border>
<!-- Disable Updates -->
<Border Grid.Column="2" Style="{StaticResource BorderStyle}">
<StackPanel>
<Border Style="{StaticResource BorderStyle}" Padding="16" MinHeight="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,14">
<TextBlock Text="Windows Default"
FontSize="20"
FontWeight="Bold"
Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="Return control to Windows"
Margin="0,4,0,0"
FontSize="13"
Foreground="{DynamicResource MainForegroundColor}"/>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock Text="- Removes Windows Update policies applied by WinUtil" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Restores update service startup settings" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Re-enables update scheduled tasks" TextWrapping="Wrap" Margin="0,0,0,12" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="Use this to undo the Recommended or Disable profile."
FontSize="11"
FontStyle="Italic"
TextWrapping="Wrap"
Foreground="{DynamicResource MainForegroundColor}"/>
</StackPanel>
<Button Name="WPFUpdatesdefault"
Grid.Row="2"
Content="Restore Defaults"
FontSize="{DynamicResource ConfigTabButtonFontSize}"
Margin="0,16,0,0"
Padding="10"/>
</Grid>
</Border>
<Border Style="{StaticResource BorderStyle}" Padding="16" MinHeight="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,14">
<TextBlock Text="Disable Updates"
FontSize="20"
FontWeight="Bold"
Foreground="Red"/>
<TextBlock Text="Advanced use only"
Margin="0,4,0,0"
FontSize="13"
FontWeight="SemiBold"
Foreground="Red"/>
</StackPanel>
<StackPanel Grid.Row="1">
<TextBlock Text="- Disables automatic update policy" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Stops update services and scheduled tasks" TextWrapping="Wrap" Margin="0,0,0,7" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="- Clears downloaded update files" TextWrapping="Wrap" Margin="0,0,0,12" Foreground="{DynamicResource MainForegroundColor}"/>
<TextBlock Text="Security updates will not be installed while this profile is active."
FontSize="11"
FontStyle="Italic"
TextWrapping="Wrap"
Foreground="Red"/>
</StackPanel>
<Button Name="WPFUpdatesdisable"
Grid.Row="2"
Content="Disable Updates"
FontSize="{DynamicResource ConfigTabButtonFontSize}"
Content="Disable All Updates"
Foreground="Red"
Margin="10,5"
Margin="0,16,0,0"
Padding="10"/>
<TextBlock Margin="10"
TextWrapping="Wrap"
Foreground="{DynamicResource MainForegroundColor}">
<Run FontWeight="Bold" Foreground="Red">!! Not Recommended !!</Run>
<LineBreak/>
- Disables ALL Windows Updates
<LineBreak/>
- Increases security risks
<LineBreak/>
- Only use for isolated systems
<LineBreak/><LineBreak/>
<Run FontStyle="Italic" FontSize="11">Warning: Your system will be vulnerable without security updates.</Run>
</TextBlock>
</StackPanel>
</Grid>
</Border>
</Grid>
</UniformGrid>
<!-- Future Implementation: Add Windows Version to updates panel -->
<Grid Name="updatespanel" Grid.Row="1" Background="Transparent">
</Grid>
<Border Grid.Row="2" Style="{StaticResource BorderStyle}" Margin="8,14,8,8" Padding="12">
<TextBlock Text="Changes apply system-wide. Restart Windows after switching profiles. Use Restore Defaults to undo WinUtil update policies."
TextWrapping="Wrap"
HorizontalAlignment="Center"
Foreground="{DynamicResource MainForegroundColor}"/>
</Border>
</Grid>
</ScrollViewer>
</TabItem>