Reviews and improvements
This commit is contained in:
@@ -9,9 +9,9 @@ Author: Patrick Asmus
|
||||
Web: https://www.cleveradmin.de
|
||||
Repository: https://git.techniverse.net/scriptos/windows-updater.git
|
||||
License: MIT
|
||||
Version: 2.2.0
|
||||
Version: 2.3.0
|
||||
Datum: 06.07.2026
|
||||
Modifiaktione: Service-Watchdog: Dienste nach Updates ohne Reboot neu starten und überwachen.
|
||||
Modifiaktione: Reviews and improvements
|
||||
#####################################################
|
||||
#>
|
||||
|
||||
@@ -355,21 +355,29 @@ function New-HtmlUpdateReport {
|
||||
|
||||
$rows = ""
|
||||
foreach ($r in $Results) {
|
||||
$color = if ($r.Result -match "Install|Success") { "#2d7d2d" } else { "#c0392b" }
|
||||
$bgColor = if ($r.Result -match "Install|Success") { "#e8f5e9" } else { "#fde8e8" }
|
||||
$color = if ($r.Result -match "^Installed|^Succeeded|^Success") { "#2d7d2d" } else { "#c0392b" }
|
||||
$bgColor = if ($r.Result -match "^Installed|^Succeeded|^Success") { "#e8f5e9" } else { "#fde8e8" }
|
||||
$eDate = [System.Net.WebUtility]::HtmlEncode($r.Date)
|
||||
$eKB = [System.Net.WebUtility]::HtmlEncode($r.KB)
|
||||
$eTitle = [System.Net.WebUtility]::HtmlEncode($r.Title)
|
||||
$eSize = [System.Net.WebUtility]::HtmlEncode($r.Size)
|
||||
$eResult = [System.Net.WebUtility]::HtmlEncode($r.Result)
|
||||
$rows += @"
|
||||
<tr style="background-color: $bgColor;">
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$($r.Date)</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$($r.KB)</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$($r.Title)</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$($r.Size)</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd; color: $color; font-weight: bold;">$($r.Result)</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$eDate</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$eKB</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$eTitle</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd;">$eSize</td>
|
||||
<td style="padding: 8px; border: 1px solid #ddd; color: $color; font-weight: bold;">$eResult</td>
|
||||
</tr>
|
||||
"@
|
||||
}
|
||||
|
||||
$successCount = ($Results | Where-Object { $_.Result -match "Install|Success" } | Measure-Object).Count
|
||||
$failCount = ($Results | Where-Object { $_.Result -notmatch "Install|Success" } | Measure-Object).Count
|
||||
$successCount = ($Results | Where-Object { $_.Result -match "^Installed|^Succeeded|^Success" } | Measure-Object).Count
|
||||
$failCount = ($Results | Where-Object { $_.Result -notmatch "^Installed|^Succeeded|^Success" } | Measure-Object).Count
|
||||
|
||||
$eHostname = [System.Net.WebUtility]::HtmlEncode($Hostname)
|
||||
$eOSCaption = [System.Net.WebUtility]::HtmlEncode($OSCaption)
|
||||
|
||||
$html = @"
|
||||
<!DOCTYPE html>
|
||||
@@ -377,8 +385,8 @@ function New-HtmlUpdateReport {
|
||||
<head><meta charset="utf-8"></head>
|
||||
<body style="font-family: Segoe UI, Arial, sans-serif; color: #333; max-width: 900px; margin: 0 auto; padding: 20px;">
|
||||
<h2 style="color: #1a5276;">Windows Update Report</h2>
|
||||
<p><strong>Host:</strong> $Hostname<br>
|
||||
<strong>OS:</strong> $OSCaption<br>
|
||||
<p><strong>Host:</strong> $eHostname<br>
|
||||
<strong>OS:</strong> $eOSCaption<br>
|
||||
<strong>Date:</strong> $(Get-Date -Format "dd.MM.yyyy HH:mm:ss")<br>
|
||||
<strong>Successful:</strong> $successCount | <strong>Failed:</strong> $failCount</p>
|
||||
<table style="border-collapse: collapse; width: 100%; font-size: 14px;">
|
||||
@@ -510,7 +518,7 @@ function Send-TeamsNotification {
|
||||
}
|
||||
|
||||
foreach ($r in $UpdateResults) {
|
||||
$icon = if ($r.Result -match "Install|Success") { "✅" } else { "❌" }
|
||||
$icon = if ($r.Result -match "^Installed|^Succeeded|^Success") { "✅" } else { "❌" }
|
||||
$bodyItems += @{
|
||||
type = "TextBlock"
|
||||
text = "$icon **$($r.KB)** — $($r.Title) ($($r.Size)) — $($r.Result)"
|
||||
@@ -761,7 +769,8 @@ function Get-AvailableUpdates {
|
||||
}
|
||||
catch {
|
||||
Write-Log "Error scanning for updates: $($_.Exception.Message)" -Level ERROR
|
||||
return @()
|
||||
$script:HasErrors = $true
|
||||
return $null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,7 +842,7 @@ function Install-PendingUpdates {
|
||||
Add-UpdateHistoryEntry -KB $kbStr -Title $r.Title -Size $sizeStr -Result $resultStr
|
||||
}
|
||||
|
||||
$failed = $deduplicated | Where-Object { $_.Result -and $_.Result.ToString() -notmatch "Install|Success" }
|
||||
$failed = $deduplicated | Where-Object { $_.Result -and $_.Result.ToString() -notmatch "^Installed|^Succeeded|^Success" }
|
||||
if ($failed -and $retryCount -gt 0) {
|
||||
Write-Log "Retrying $(@($failed).Count) failed update(s)..." -Level WARN
|
||||
foreach ($f in $failed) {
|
||||
@@ -844,7 +853,7 @@ function Install-PendingUpdates {
|
||||
Write-Log " Retry $i/$retryCount for $kbId - $($f.Title)" -Level WARN
|
||||
try {
|
||||
$retryResult = Install-WindowsUpdate -KBArticleID $kbId -AcceptAll -ErrorAction Stop
|
||||
if ($retryResult -and $retryResult.Result -and $retryResult.Result.ToString() -match "Install|Success") {
|
||||
if ($retryResult -and $retryResult.Result -and $retryResult.Result.ToString() -match "^Installed|^Succeeded|^Success") {
|
||||
Write-Log " Retry successful for $kbId" -Level INFO
|
||||
$retrySuccess = $true
|
||||
|
||||
@@ -925,12 +934,14 @@ function Invoke-WingetUpgrade {
|
||||
}
|
||||
else {
|
||||
Write-Log "Winget upgrade finished with exit code: $exitCode" -Level WARN
|
||||
$script:HasErrors = $true
|
||||
}
|
||||
|
||||
Add-UpdateHistoryEntry -KB "winget" -Title "Winget Upgrade --all" -Size "N/A" -Result "ExitCode: $exitCode" -UpdateType "Winget"
|
||||
}
|
||||
catch {
|
||||
Write-Log "Winget upgrade error: $($_.Exception.Message)" -Level WARN
|
||||
Write-Log "Winget upgrade error: $($_.Exception.Message)" -Level ERROR
|
||||
$script:HasErrors = $true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1165,12 +1176,25 @@ function Start-WindowsUpdater {
|
||||
$dryRun = Get-ConfigValue -Config $script:Config -Section "General" -Key "DryRun" -Default $false -Type bool
|
||||
$availableUpdates = Get-AvailableUpdates
|
||||
|
||||
if (-not $availableUpdates -or @($availableUpdates).Count -eq 0) {
|
||||
if ($null -eq $availableUpdates) {
|
||||
Write-Log "Update scan failed, aborting" -Level ERROR
|
||||
Send-Notification -Subject "Scan Error - $env:COMPUTERNAME" `
|
||||
-Body "Windows update scan failed on $env:COMPUTERNAME. Check logs for details." `
|
||||
-Priority "high" -EventName "UpdateComplete"
|
||||
Invoke-UpdateHook -Phase Post | Out-Null
|
||||
Write-Log "Windows Updater finished (scan error)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if (@($availableUpdates).Count -eq 0) {
|
||||
Write-Log "No updates available"
|
||||
Send-Notification -Subject "No Updates - $env:COMPUTERNAME" `
|
||||
-Body "No Windows updates are currently available for $env:COMPUTERNAME." `
|
||||
-EventName "NoUpdates"
|
||||
Invoke-WingetUpgrade
|
||||
if (-not $dryRun) {
|
||||
Invoke-WingetUpgrade
|
||||
Export-UpdateHistory
|
||||
}
|
||||
Invoke-UpdateHook -Phase Post | Out-Null
|
||||
Write-Log "Windows Updater finished (no updates)"
|
||||
exit 0
|
||||
@@ -1198,7 +1222,6 @@ function Start-WindowsUpdater {
|
||||
|
||||
Send-Notification -Subject "Dry-Run Report - $env:COMPUTERNAME" -Body $reportBody -EventName "DryRun"
|
||||
|
||||
Invoke-WingetUpgrade
|
||||
Invoke-UpdateHook -Phase Post | Out-Null
|
||||
Write-Log "Windows Updater finished (dry-run)"
|
||||
exit 0
|
||||
@@ -1214,8 +1237,8 @@ function Start-WindowsUpdater {
|
||||
Export-UpdateHistory
|
||||
|
||||
# --- Send Summary Notification ---
|
||||
$successCount = ($script:UpdateResults | Where-Object { $_.Result -match "Install|Success" } | Measure-Object).Count
|
||||
$failCount = ($script:UpdateResults | Where-Object { $_.Result -notmatch "Install|Success" } | Measure-Object).Count
|
||||
$successCount = ($script:UpdateResults | Where-Object { $_.Result -match "^Installed|^Succeeded|^Success" } | Measure-Object).Count
|
||||
$failCount = ($script:UpdateResults | Where-Object { $_.Result -notmatch "^Installed|^Succeeded|^Success" } | Measure-Object).Count
|
||||
|
||||
$summaryBody = @(
|
||||
"Windows Update Summary for $env:COMPUTERNAME"
|
||||
@@ -1232,8 +1255,9 @@ function Start-WindowsUpdater {
|
||||
}
|
||||
|
||||
$summaryText = $summaryBody -join "`n"
|
||||
$priority = if ($failCount -gt 0) { "high" } else { "default" }
|
||||
$subjectPrefix = if ($failCount -gt 0) { "Updates (with errors)" } else { "Updates OK" }
|
||||
$hasFailures = $failCount -gt 0 -or $script:HasErrors
|
||||
$priority = if ($hasFailures) { "high" } else { "default" }
|
||||
$subjectPrefix = if ($hasFailures) { "Updates (with errors)" } else { "Updates OK" }
|
||||
|
||||
Send-Notification -Subject "$subjectPrefix - $env:COMPUTERNAME" `
|
||||
-Body $summaryText -Priority $priority `
|
||||
|
||||
Reference in New Issue
Block a user