Um DefenderUpdatesOnly ergänzt
This commit is contained in:
@@ -9,12 +9,18 @@ Author: Patrick Asmus
|
||||
Web: https://www.cleveradmin.de
|
||||
Repository: https://git.techniverse.net/scriptos/windows-updater.git
|
||||
License: MIT
|
||||
Version: 2.7.2
|
||||
Date: 06.07.2026
|
||||
Modifications: Guard TLS 1.3 with enum check and try/catch fallback to TLS 1.2
|
||||
Version: 2.8.0
|
||||
Date: 07.07.2026
|
||||
Modifications: Add -DefenderOnly, -DryRun, -ConfigFile parameters and UpdateType config option
|
||||
#####################################################
|
||||
#>
|
||||
|
||||
param(
|
||||
[switch]$DefenderOnly,
|
||||
[switch]$DryRun,
|
||||
[string]$ConfigFile
|
||||
)
|
||||
|
||||
# ===================================================
|
||||
#region Administrator Check
|
||||
# ===================================================
|
||||
@@ -53,6 +59,9 @@ $script:UseXlsx = $false
|
||||
$script:UpdateResults = [System.Collections.ArrayList]::new()
|
||||
$script:WingetResults = [System.Collections.ArrayList]::new()
|
||||
$script:ScriptStartTime = Get-Date
|
||||
$script:DefenderOnlyMode = $DefenderOnly.IsPresent
|
||||
$script:DryRunParam = $DryRun.IsPresent
|
||||
$script:ConfigFilePath = $ConfigFile
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -765,6 +774,11 @@ function Get-AvailableUpdates {
|
||||
$params["MicrosoftUpdate"] = $true
|
||||
}
|
||||
|
||||
if ($script:DefenderOnlyMode) {
|
||||
$params["Category"] = @("Definition Updates")
|
||||
Write-Log "Filtering for Defender definition updates only"
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($excludeKBs)) {
|
||||
$kbList = $excludeKBs -split ',' | ForEach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
|
||||
if ($kbList.Count -gt 0) {
|
||||
@@ -773,7 +787,7 @@ function Get-AvailableUpdates {
|
||||
}
|
||||
}
|
||||
|
||||
if ($excludeDrivers) {
|
||||
if ($excludeDrivers -and -not $script:DefenderOnlyMode) {
|
||||
$params["NotCategory"] = "Drivers"
|
||||
Write-Log "Excluding driver updates"
|
||||
}
|
||||
@@ -804,6 +818,10 @@ function Install-PendingUpdates {
|
||||
$params["MicrosoftUpdate"] = $true
|
||||
}
|
||||
|
||||
if ($script:DefenderOnlyMode) {
|
||||
$params["Category"] = @("Definition Updates")
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($excludeKBs)) {
|
||||
$kbList = $excludeKBs -split ',' | ForEach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
|
||||
if ($kbList.Count -gt 0) {
|
||||
@@ -811,7 +829,7 @@ function Install-PendingUpdates {
|
||||
}
|
||||
}
|
||||
|
||||
if ($excludeDrivers) {
|
||||
if ($excludeDrivers -and -not $script:DefenderOnlyMode) {
|
||||
$params["NotCategory"] = "Drivers"
|
||||
}
|
||||
|
||||
@@ -1158,16 +1176,30 @@ function Invoke-ServiceWatchdog {
|
||||
|
||||
function Start-WindowsUpdater {
|
||||
# --- Load Config ---
|
||||
$configPath = Join-Path -Path $PSScriptRoot -ChildPath "config.ini"
|
||||
if (-not [string]::IsNullOrWhiteSpace($script:ConfigFilePath)) {
|
||||
$configPath = $script:ConfigFilePath
|
||||
}
|
||||
else {
|
||||
$configPath = Join-Path -Path $PSScriptRoot -ChildPath "config.ini"
|
||||
}
|
||||
$script:Config = Read-IniFile -Path $configPath
|
||||
|
||||
# --- Resolve DefenderOnly mode (parameter overrides config) ---
|
||||
if (-not $script:DefenderOnlyMode) {
|
||||
$configUpdateType = Get-ConfigValue -Config $script:Config -Section "General" -Key "UpdateType" -Default "All"
|
||||
if ($configUpdateType -eq "DefenderOnly") {
|
||||
$script:DefenderOnlyMode = $true
|
||||
}
|
||||
}
|
||||
|
||||
# --- Initialize Logging ---
|
||||
$logPath = Get-ConfigValue -Config $script:Config -Section "General" -Key "LogPath" -Default "C:\logs\windows-updater"
|
||||
$logRetention = Get-ConfigValue -Config $script:Config -Section "General" -Key "LogRetentionDays" -Default 365 -Type int
|
||||
Initialize-Logging -LogPath $logPath -RetentionDays $logRetention
|
||||
|
||||
$modeLabel = if ($script:DefenderOnlyMode) { "Defender Only" } else { "Full Update" }
|
||||
Write-Log "=========================================="
|
||||
Write-Log "Windows Updater started"
|
||||
Write-Log "Windows Updater started (Mode: $modeLabel)"
|
||||
Write-Log "=========================================="
|
||||
|
||||
# --- OS Detection ---
|
||||
@@ -1208,6 +1240,7 @@ function Start-WindowsUpdater {
|
||||
|
||||
# --- Scan for Updates ---
|
||||
$dryRun = Get-ConfigValue -Config $script:Config -Section "General" -Key "DryRun" -Default $false -Type bool
|
||||
if ($script:DryRunParam) { $dryRun = $true }
|
||||
$availableUpdates = Get-AvailableUpdates
|
||||
|
||||
if ($null -eq $availableUpdates) {
|
||||
@@ -1220,13 +1253,15 @@ function Start-WindowsUpdater {
|
||||
exit 1
|
||||
}
|
||||
|
||||
$updateLabel = if ($script:DefenderOnlyMode) { "Defender" } else { "Windows" }
|
||||
|
||||
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." `
|
||||
Send-Notification -Subject "No $updateLabel Updates - $env:COMPUTERNAME" `
|
||||
-Body "No $updateLabel updates are currently available for $env:COMPUTERNAME." `
|
||||
-EventName "NoUpdates"
|
||||
if (-not $dryRun) {
|
||||
Invoke-WingetUpgrade
|
||||
if (-not $script:DefenderOnlyMode) { Invoke-WingetUpgrade }
|
||||
Export-UpdateHistory
|
||||
}
|
||||
Invoke-UpdateHook -Phase Post | Out-Null
|
||||
@@ -1250,7 +1285,7 @@ function Start-WindowsUpdater {
|
||||
if ($dryRun) {
|
||||
Write-Log "DRY-RUN mode active - no updates will be installed"
|
||||
|
||||
$reportLines = @("Available Updates for $env:COMPUTERNAME ($updateCount):`n")
|
||||
$reportLines = @("Available $updateLabel Updates for $env:COMPUTERNAME ($updateCount):`n")
|
||||
foreach ($u in $availableUpdates) {
|
||||
$sizeStr = if ($u.Size) { "{0:N2} MB" -f ($u.Size / 1MB) } else { "N/A" }
|
||||
$kbStr = if ($u.KB) { $u.KB } else { "N/A" }
|
||||
@@ -1258,7 +1293,7 @@ function Start-WindowsUpdater {
|
||||
}
|
||||
$reportBody = $reportLines -join "`n"
|
||||
|
||||
Send-Notification -Subject "Dry-Run Report - $env:COMPUTERNAME" -Body $reportBody -EventName "DryRun"
|
||||
Send-Notification -Subject "$updateLabel Dry-Run Report - $env:COMPUTERNAME" -Body $reportBody -EventName "DryRun"
|
||||
|
||||
Invoke-UpdateHook -Phase Post | Out-Null
|
||||
Write-Log "Windows Updater finished (dry-run)"
|
||||
@@ -1268,8 +1303,10 @@ function Start-WindowsUpdater {
|
||||
# --- Install Updates ---
|
||||
Install-PendingUpdates
|
||||
|
||||
# --- Winget ---
|
||||
Invoke-WingetUpgrade
|
||||
# --- Winget (skip in DefenderOnly mode) ---
|
||||
if (-not $script:DefenderOnlyMode) {
|
||||
Invoke-WingetUpgrade
|
||||
}
|
||||
|
||||
# --- Export History ---
|
||||
Export-UpdateHistory
|
||||
@@ -1279,7 +1316,7 @@ function Start-WindowsUpdater {
|
||||
$failCount = ($script:UpdateResults | Where-Object { $_.Result -notmatch "^Installed|^Succeeded|^Success" } | Measure-Object).Count
|
||||
|
||||
$summaryBody = @(
|
||||
"Windows Update Summary for $env:COMPUTERNAME"
|
||||
"$updateLabel Update Summary for $env:COMPUTERNAME"
|
||||
"OS: $($script:OSInfo.Caption)"
|
||||
"Date: $(Get-Date -Format 'dd.MM.yyyy HH:mm:ss')"
|
||||
""
|
||||
@@ -1295,7 +1332,7 @@ function Start-WindowsUpdater {
|
||||
$summaryText = $summaryBody -join "`n"
|
||||
$hasFailures = $failCount -gt 0 -or $script:HasErrors
|
||||
$priority = if ($hasFailures) { "high" } else { "default" }
|
||||
$subjectPrefix = if ($hasFailures) { "Updates (with errors)" } else { "Updates OK" }
|
||||
$subjectPrefix = if ($hasFailures) { "$updateLabel Updates (with errors)" } else { "$updateLabel Updates OK" }
|
||||
|
||||
Send-Notification -Subject "$subjectPrefix - $env:COMPUTERNAME" `
|
||||
-Body $summaryText -Priority $priority `
|
||||
@@ -1304,22 +1341,24 @@ function Start-WindowsUpdater {
|
||||
# --- Post-Update Hook ---
|
||||
Invoke-UpdateHook -Phase Post | Out-Null
|
||||
|
||||
# --- Reboot Handling ---
|
||||
$script:RebootPending = Test-PendingReboot
|
||||
if ($script:RebootPending) {
|
||||
Write-Log "System reboot is pending"
|
||||
$rebootHandled = Invoke-ScheduledReboot
|
||||
if (-not $rebootHandled) {
|
||||
Write-Log "Auto-reboot is disabled, manual reboot required" -Level WARN
|
||||
Send-Notification -Subject "Reboot Required - $env:COMPUTERNAME" `
|
||||
-Body "Windows updates have been installed on $env:COMPUTERNAME but a reboot is required. Auto-reboot is disabled." `
|
||||
-Priority "high" -EventName "RebootRequired"
|
||||
# --- Reboot Handling (skip in DefenderOnly mode) ---
|
||||
if (-not $script:DefenderOnlyMode) {
|
||||
$script:RebootPending = Test-PendingReboot
|
||||
if ($script:RebootPending) {
|
||||
Write-Log "System reboot is pending"
|
||||
$rebootHandled = Invoke-ScheduledReboot
|
||||
if (-not $rebootHandled) {
|
||||
Write-Log "Auto-reboot is disabled, manual reboot required" -Level WARN
|
||||
Send-Notification -Subject "Reboot Required - $env:COMPUTERNAME" `
|
||||
-Body "Windows updates have been installed on $env:COMPUTERNAME but a reboot is required. Auto-reboot is disabled." `
|
||||
-Priority "high" -EventName "RebootRequired"
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Log "No reboot required"
|
||||
# --- Service Watchdog (only when no reboot is pending) ---
|
||||
Invoke-ServiceWatchdog
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Log "No reboot required"
|
||||
# --- Service Watchdog (only when no reboot is pending) ---
|
||||
Invoke-ServiceWatchdog
|
||||
}
|
||||
|
||||
# --- Finish ---
|
||||
@@ -1328,7 +1367,7 @@ function Start-WindowsUpdater {
|
||||
Write-Log "=========================================="
|
||||
|
||||
if ($script:HasErrors) { exit 1 }
|
||||
if ($script:RebootPending -and -not (Get-ConfigValue -Config $script:Config -Section "Reboot" -Key "Enabled" -Default $false -Type bool)) { exit 2 }
|
||||
if (-not $script:DefenderOnlyMode -and $script:RebootPending -and -not (Get-ConfigValue -Config $script:Config -Section "Reboot" -Key "Enabled" -Default $false -Type bool)) { exit 2 }
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user