<# .SYNOPSIS Automates the process of checking for, installing, and reporting on Windows Updates using the PSWindowsUpdate module. .DESCRIPTION This script ensures the NuGet package provider and the PSWindowsUpdate PowerShell module are installed and imported. It supports installing either only Definition Updates or all available Windows Updates based on the parameters provided. The script previews available updates, installs them with optional automatic reboot, and reports on updates installed within the last 24 hours. It also checks if a reboot is required after installation and notifies the user if a manual reboot is needed. .PARAMETER DefinitionOnly When specified, the script will only check for and install Windows Definition Updates. .PARAMETER AllUpdates When specified, the script will check for and install all available Windows Updates. .PARAMETER Reboot When specified, the script will automatically reboot the system after installing updates if a reboot is required. .EXAMPLE .\PerformWindowsUpdate.ps1 -DefinitionOnly Checks for and installs only Definition Updates without rebooting. .EXAMPLE .\PerformWindowsUpdate.ps1 -AllUpdates -Reboot Installs all available updates and automatically reboots the system if needed. .NOTES Requires administrative privileges to install updates. Exits with code 1 if no updates are found or if an error occurs during installation. Exits with code 2 if a reboot is required but the -Reboot switch is not specified. #> param( [switch]$DefinitionOnly, [switch]$AllUpdates, [switch]$Reboot ) # Enable TLS 1.2 needed for older windows server version [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; # Ensure NuGet provider is available (with -Force to avoid prompts) $nugetProvider = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue if (-not $nugetProvider) { Write-Host "Installing NuGet provider..." Install-PackageProvider -Name NuGet -Force -Confirm:$false } # Ensure PSWindowsUpdate module is available (with -Force to avoid prompts) $installedModule = Get-InstalledModule -Name PSWindowsUpdate -ErrorAction SilentlyContinue if (-not $installedModule) { Write-Host "Installing PSWindowsUpdate module..." Install-Module -Name PSWindowsUpdate -Force -AllowClobber -Confirm:$false } # Import latest module Import-Module PSWindowsUpdate -Force # Validate parameters if (-not ($DefinitionOnly -or $AllUpdates)) { Write-Host "Please specify either -DefinitionOnly or -AllUpdates." exit 1 } # Preview updates if ($DefinitionOnly) { $updates = Get-WindowsUpdate -AcceptAll -IgnoreReboot -RootCategories 'Definition Updates' } elseif ($AllUpdates) { $updates = Get-WindowsUpdate -AcceptAll -IgnoreReboot } if ($updates) { Write-Host "Updates found:`n" foreach ($update in $updates) { $kb = ($update.KBArticleIDs -join ', ') Write-Host "Title: $($update.Title)" Write-Host "KB: $kb" Write-Host "----------------------------------" } Write-Host "`nInstalling updates..." try { if ($DefinitionOnly) { if ($Reboot) { Install-WindowsUpdate -AcceptAll -AutoReboot -RootCategories 'Definition Updates' } else { Install-WindowsUpdate -AcceptAll -IgnoreReboot -RootCategories 'Definition Updates' } } elseif ($AllUpdates) { if ($Reboot) { Install-WindowsUpdate -AcceptAll -AutoReboot } else { Install-WindowsUpdate -AcceptAll -IgnoreReboot } } } catch { Write-Host "`nError during update installation: $($_.Exception.Message)" exit 1 # Exit with code 1 if an error occurs during installation } # Get the current time (to compare for last 24 hours) $currentTime = Get-Date $twentyFourHoursAgo = $currentTime.AddHours(-24) # Query the update history and filter for updates installed in the last 24 hours $history = Get-WUHistory | Where-Object { $_.Date -gt $twentyFourHoursAgo } if ($history) { Write-Host "`nConfirmed installed updates in the last 24 hours:`n" foreach ($item in $history) { $kb = ($item.KB -join ', ') Write-Host "Title: $($item.Title)" Write-Host "KB: $kb" Write-Host "Result: $($item.ResultCode)" Write-Host "Date: $($item.Date)" Write-Host "----------------------------------" } } else { Write-Host "`nNo updates were confirmed in the update history in the last 24 hours." exit 1 # Exit with code 1 if no updates are confirmed in the last 24 hours } if ($DefinitionOnly) { Write-Host "`nOnly definition updates were installed. No reboot needed." exit 0 } elseif ($AllUpdates) { if (-not $Reboot -and (Get-WURebootStatus)) { Write-Host "`nReboot required, but -Reboot not specified. Please reboot manually." exit 2 } } } else { Write-Host "No updates available for the selected category." exit 0 # Exit with code 0 if no updates were found }