diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index a17a517e16..09baddc695 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -7,10 +7,10 @@ body:
attributes:
value: |
# 🐞 **Issue Report**
- Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
+ Thank you for taking the time to report an issue! Please provide as much detail as possible to help us address the problem efficiently.
- ## ⚠️ **IMPORTANT**
- - 🛠️ **Supported environments only:** We only support Windows 11. Custom ISOs that are not made using Microwin are not supported.
+ ## ⚠️ **IMPORTANT**
+ - 🛠️ **Supported environments only:** We only support Windows 11. Custom ISOs that are not made using Microwin are not supported.
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
- type: checkboxes
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
index d32fae1ed6..65e24338fc 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yaml
@@ -9,7 +9,7 @@ body:
# ✨ **Feature request**
Thank you for taking the time to suggest a feature! Please provide as much detail as possible to help us understand and evaluate your request.
- ## ⚠️ **IMPORTANT**
+ ## ⚠️ **IMPORTANT**
- 🛠️ **Supported environments only:** We only support Windows 11.
- 💡 For general questions, use the [Discussions section](https://github.com/Christitustech/winutil/discussions) or join our Community-driven [Discord Server](https://discord.gg/RUbZUZyByQ).
@@ -54,4 +54,4 @@ body:
label: 🖼️ Additional context
placeholder: "Include screenshots, code blocks (use triple backticks ```), or any other relevant information."
validations:
- required: false
\ No newline at end of file
+ required: false
diff --git a/functions/public/Invoke-WPFButton.ps1 b/functions/public/Invoke-WPFButton.ps1
index 0b79e553dc..ae9b753ed7 100644
--- a/functions/public/Invoke-WPFButton.ps1
+++ b/functions/public/Invoke-WPFButton.ps1
@@ -61,5 +61,10 @@ function Invoke-WPFButton {
"WPFWinUtilInstallPSProfile" {Invoke-WinUtilInstallPSProfile}
"WPFWinUtilUninstallPSProfile" {Invoke-WinUtilUninstallPSProfile}
"WPFWinUtilSSHServer" {Invoke-WPFSSHServer}
+ "WPFScanUpdates" {Invoke-WPFUpdatesScan}
+ "WPFShowUpdateHistory" { Invoke-WPFUpdateHistoryToggle }
+ "WPFUpdateSelectedInstall" {Invoke-WPFUpdateMGMT -Selected}
+ "WPFUpdateAllInstall" {Invoke-WPFUpdateMGMT -All}
+ "WPFUpdateScanHistory" {Invoke-WPFUpdateScanHistory}
}
}
diff --git a/functions/public/Invoke-WPFUpdateHistoryToggle.ps1 b/functions/public/Invoke-WPFUpdateHistoryToggle.ps1
new file mode 100644
index 0000000000..030b6be13d
--- /dev/null
+++ b/functions/public/Invoke-WPFUpdateHistoryToggle.ps1
@@ -0,0 +1,11 @@
+function Invoke-WPFUpdateHistoryToggle {
+ if ($sync["WPFShowUpdateHistory"].Content -eq "Show History") {
+ $sync["WPFShowUpdateHistory"].Content = "Show available Updates"
+ $sync["HistoryGrid"].Visibility = "Visible"
+ $sync["UpdatesGrid"].Visibility = "Collapsed"
+ } else {
+ $sync["WPFShowUpdateHistory"].Content = "Show History"
+ $sync["HistoryGrid"].Visibility = "Collapsed"
+ $sync["UpdatesGrid"].Visibility = "Visible"
+ }
+}
diff --git a/functions/public/Invoke-WPFUpdateMGMGT.ps1 b/functions/public/Invoke-WPFUpdateMGMGT.ps1
new file mode 100644
index 0000000000..d6cec270f7
--- /dev/null
+++ b/functions/public/Invoke-WPFUpdateMGMGT.ps1
@@ -0,0 +1,45 @@
+function Invoke-WPFUpdateMGMT {
+ param (
+ [switch]$Selected,
+ [switch]$All
+ )
+
+ if ($All) {
+ Write-Host "Installing all available updates ..."
+ Invoke-WPFRunspace -ArgumentList $sync["WPFUpdateVerbose"].IsChecked -DebugPreference $DebugPreference -ScriptBlock {
+ param ($WPFUpdateVerbose)
+ if ($WPFUpdateVerbose) {
+ Install-WindowsUpdate -Verbose -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
+ } else {
+ Install-WindowsUpdate -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
+ }
+ Write-Host "All Update Processes Completed"
+ }
+ } elseif (($Selected) -and ($sync["WPFUpdatesList"].SelectedItems.Count -gt 0)) {
+ write-host "Installing selected updates..."
+ $selectedUpdates = $sync["WPFUpdatesList"].SelectedItems | ForEach-Object {
+ [PSCustomObject]@{
+ ComputerName = $_.ComputerName
+ Title = $_.LongTitle
+ KB = $_.KB
+ Size = $_.Size
+ }
+ }
+ Invoke-WPFRunspace -ParameterList @(("selectedUpdates", $selectedUpdates), ("WPFUpdateVerbose", $sync["WPFUpdateVerbose"].IsChecked)) -DebugPreference $DebugPreference -ScriptBlock {
+ param ($selectedUpdates, $WPFUpdateVerbose)
+ foreach ($update in $selectedUpdates) {
+ Write-Host "Installing update $($update.Title) on $($update.ComputerName)"
+ if ($WPFUpdateVerbose) {
+ Get-WindowsUpdate -ComputerName $update.ComputerName -Title $update.Title -Install -Confirm:$false -Verbose -IgnoreReboot:$true -IgnoreRebootRequired:$true
+ } else {
+ Get-WindowsUpdate -ComputerName $update.ComputerName -Title $update.Title -Install -Confirm:$false -IgnoreReboot:$true -IgnoreRebootRequired:$true
+ }
+ }
+ Write-Host "Selected Update Processes Completed"
+ }
+ } else {
+ Write-Host "No updates selected"
+ return
+ }
+
+}
diff --git a/functions/public/Invoke-WPFUpdateScanHistory.ps1 b/functions/public/Invoke-WPFUpdateScanHistory.ps1
new file mode 100644
index 0000000000..4138e746a5
--- /dev/null
+++ b/functions/public/Invoke-WPFUpdateScanHistory.ps1
@@ -0,0 +1,46 @@
+function Invoke-WPFUpdateScanHistory {
+ $sync["WPFUpdateHistory"].Items.Clear()
+ Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
+ write-host "Scanning for Windows update history..."
+ $UpdateHistory = Get-WUHistory -Last 50 -ErrorAction SilentlyContinue
+ if ($UpdateHistory) {
+ foreach ($update in $UpdateHistory) {
+ $item = New-Object PSObject -Property @{
+ ComputerName = $update.ComputerName
+ Result = $update.Result
+ Title = $update.Title -replace '\s*\(KB\d+\)', '' -replace '\s*KB\d+\b', '' # Remove KB number from title, first in parentheses, then standalone
+ KB = $update.KB
+ Date = $update.Date
+ }
+ $Computers = $item | Select-Object -ExpandProperty ComputerName -Unique
+ $sync.form.Dispatcher.Invoke([action] {
+ $sync["WPFUpdateHistory"].Items.Add($item)
+ if ($item.Result -eq "Succeeded") {
+ # does not work : $sync["WPFUpdateHistory"].Items[$sync["WPFUpdateHistory"].Items.Count - 1].Foreground = "Green"
+ #write-host "$($item.Title) was successful"
+ }
+ elseif ($item.Result -eq "Failed") {
+ # does not work : $sync["WPFUpdateHistory"].Items[$sync["WPFUpdateHistory"].Items.Count - 1].Foreground = "Red"
+ #write-host "$($item.Title) failed"
+ }
+ })
+ }
+ write-host "Found $($UpdateHistory.Count) updates."
+ $sync.form.Dispatcher.Invoke([action] {
+ if ($Computers.Count -gt 1) {
+ $sync["WPFUpdateHistory"].Columns[0].Visibility = "Visible"
+ }
+ else {
+ Write-Debug "Hiding ComputerName column, only $item.ComputerName"
+ $sync["WPFUpdateHistory"].Columns[0].Visibility = "Collapsed"
+ }
+ })
+ }
+ else {
+ $sync.form.Dispatcher.Invoke([action] {
+ $sync["WPFUpdateHistory"].Items.Clear()
+ })
+ Write-Host "No update history available."
+ }
+ }
+}
diff --git a/functions/public/Invoke-WPFUpdatesScan.ps1 b/functions/public/Invoke-WPFUpdatesScan.ps1
new file mode 100644
index 0000000000..4805b022f3
--- /dev/null
+++ b/functions/public/Invoke-WPFUpdatesScan.ps1
@@ -0,0 +1,58 @@
+function Invoke-WPFUpdatesScan {
+
+
+ Invoke-WPFRunspace -DebugPreference $DebugPreference -ScriptBlock {
+ # Check if the PSWindowsUpdate module is installed
+ if (-not (Get-Module -ListAvailable -Name PSWindowsUpdate)) {
+ try {
+ Write-Host "PSWindowsUpdate module not found. Attempting to install..."
+ Install-Module -Name PSWindowsUpdate -Force -Scope CurrentUser
+ Write-Host "PSWindowsUpdate module installed successfully."
+ }
+ catch {
+ Write-Error "Failed to install PSWindowsUpdate module: $_"
+ return
+ }
+ }
+
+ # Import the module
+ try {
+ Import-Module PSWindowsUpdate -ErrorAction Stop
+ Write-Host "PSWindowsUpdate module imported successfully."
+ }
+ catch {
+ Write-Error "Failed to import PSWindowsUpdate module: $_"
+ return
+ }
+
+ try {
+ $sync.form.Dispatcher.Invoke([action] { $sync["WPFUpdatesList"].Items.Clear() })
+ Write-Host "Scanning for Windows updates..."
+ $updates = Get-WindowsUpdate -ErrorAction Stop
+ Write-Host "Found $($updates.Count) updates."
+
+ $sync.form.Dispatcher.Invoke([action] {
+ foreach ($update in $updates) {
+ $item = New-Object PSObject -Property @{
+ LongTitle = $update.Title
+ ComputerName = $update.ComputerName
+ KB = $update.KB
+ Size = $update.Size
+ Title = $update.Title -replace '\s*\(KB\d+\)', '' -replace '\s*KB\d+\b', '' # Remove KB number from title, first in parentheses, then standalone
+ Status = "Not Installed"
+ }
+ $Computers = $item | Select-Object -ExpandProperty ComputerName -Unique
+ $sync["WPFUpdatesList"].Items.Add($item)
+ }
+ if ($Computers.Count -gt 1) {
+ $sync["WPFUpdatesList"].Columns[0].Visibility = "Visible"
+ } else {
+ Write-Debug "Hiding ComputerName column, only $item.ComputerName"
+ $sync["WPFUpdatesList"].Columns[0].Visibility = "Collapsed"
+ }
+ })
+ } catch {
+ Write-Error "Error scanning for updates: $_"
+ }
+ }
+}
diff --git a/xaml/inputXML.xaml b/xaml/inputXML.xaml
index 63a41af54e..18e60fd32b 100644
--- a/xaml/inputXML.xaml
+++ b/xaml/inputXML.xaml
@@ -842,6 +842,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1132,100 +1308,232 @@
-
+
-
-
+
+
-
-
-
+
-
-
-
+
+
+
+
-
- Default Windows Update Configuration
-
- - No modifications to Windows defaults
-
- - Removes any custom update settings
-
- 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.
-
-
-
+ Content="Default"
+ Width="Auto"
+ Margin="0,2"
+ ToolTip="Default Windows Update Configuration
- No modifications to Windows defaults
- Removes any custom update settings
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."/>
-
-
-
-
- Balanced Security Configuration
-
- - Feature updates delayed by 2 years
-
- - Security updates installed after 4 days
-
- Feature Updates: New features and potential bugs
-
- Security Updates: Critical security patches
-
- Note: This only applies to Pro systems that can use group policy.
-
-
-
+ Content="Security"
+ Width="Auto"
+ Margin="0,2"
+ ToolTip="Balanced Security Configuration
- Feature updates delayed by 2 years
- Security updates installed after 4 days
Feature Updates: New features and potential bugs
Security Updates: Critical security patches
Note: This only applies to Pro systems that can use group policy."/>
-
-
-
-
- !! Not Recommended !!
-
- - Disables ALL Windows Updates
-
- - Increases security risks
-
- - Only use for isolated systems
-
- Warning: Your system will be vulnerable without security updates.
-
+ Margin="0,2"
+ ToolTip="!! Not Recommended !!
- Disables ALL Windows Updates
- Increases security risks
- Only use for isolated systems
Warning: Your system will be vulnerable without security updates."/>
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Note: Updates may require a system restart to complete installation. Make sure to save any work before proceeding.
+
+
+
-
+