# Copy and paste this script into an admin powershell window # or download it and call it with powershell.exe -ExecutionPolicy Bypass -File /path/to/script.ps1 # API documentation can be found at https://learn.microsoft.com/en-us/windows/win32/wua_sdk/portal-client # Create a Windows Update session and searcher $Session = New-Object -ComObject Microsoft.Update.Session $Searcher = $Session.CreateUpdateSearcher() # Search for updates with progress Write-Progress -Activity "šŸ” Checking for updates..." -Status "Initializing search" $SearchResult = $Searcher.Search("IsInstalled=0 and Type='Software'") Write-Progress -Activity "šŸ” Checking for updates..." -Completed if ($SearchResult.Updates.Count -gt 0) { # Prepare the update collection for later reference $UpdatesToInstall = $SearchResult.Updates # Display update list Write-Host "āœ… Found $($UpdatesToInstall.Count) updates:" for ($i = 0; $i -lt $UpdatesToInstall.Count; $i++) { $update = $UpdatesToInstall.Item($i) $kb = if ($update.KBArticleIDs.Count -gt 0) { $update.KBArticleIDs -join ", " } else { "N/A" } Write-Host " - [KB$kb] $($update.Title)" } # Download updates with progress $Downloader = $Session.CreateUpdateDownloader() $Downloader.Updates = $UpdatesToInstall Write-Progress -Activity "ā¬‡ļø Downloading updates..." -PercentComplete 0 -Status "Preparing" try { $DownloadResult = $Downloader.Download() Write-Progress -Activity "ā¬‡ļø Downloading updates..." -Completed # Map ResultCode to a friendly message $downloadStatus = switch ($DownloadResult.ResultCode) { 2 { "āœ… Succeeded" } 3 { "āš ļø Succeeded with errors" } 4 { "āŒ Failed" } 5 { "ā¹ļø Aborted" } default { "ā“ Unknown result ($($DownloadResult.ResultCode))" } } Write-Host "`nšŸ’¾ Download status: $downloadStatus" # Optional: Show per-update download status (if supported) if ($DownloadResult.PSObject.Methods.Name -contains "GetUpdateResult") { Write-Host "`nšŸ“„ Per-update download results:" for ($i = 0; $i -lt $UpdatesToInstall.Count; $i++) { $update = $UpdatesToInstall.Item($i) $result = $DownloadResult.GetUpdateResult($i) $status = switch ($result.ResultCode) { 2 { "āœ… Succeeded" } 3 { "āš ļø Succeeded with errors" } 4 { "āŒ Failed" } 5 { "ā¹ļø Aborted" } default { "ā“ Unknown" } } $kb = if ($update.KBArticleIDs.Count -gt 0) { $update.KBArticleIDs -join ", " } else { "N/A" } Write-Host " - $status [KB$kb] $($update.Title)" } } } catch { Write-Host "āŒ Download failed: $($_.Exception.Message)" exit } # Install updates with per-update tracking $Installer = $Session.CreateUpdateInstaller() $Installer.Updates = $UpdatesToInstall $totalUpdates = $UpdatesToInstall.Count Write-Host "`nšŸ”§ Installing updates:" for ($i = 0; $i -lt $totalUpdates; $i++) { $update = $UpdatesToInstall.Item($i) $kb = if ($update.KBArticleIDs.Count -gt 0) { $update.KBArticleIDs -join ", " } else { "N/A" } $percent = [math]::Round((($i+1) / $totalUpdates) * 100) Write-Progress -Activity "āš™ļø Installing updates..." -Status "$($i+1)/$totalUpdates" ` -PercentComplete $percent -CurrentOperation "Installing: $($update.Title)" } $InstallResult = $Installer.Install() Write-Progress -Activity "āš™ļø Installing updates..." -Completed # Display installation results Write-Host "`nšŸ“Š Installation results:" for ($i = 0; $i -lt $UpdatesToInstall.Count; $i++) { $result = $InstallResult.GetUpdateResult($i) $update = $UpdatesToInstall.Item($i) $status = switch ($result.ResultCode) { 2 { "āœ… Succeeded" } 3 { "āš ļø Succeeded with errors" } 4 { # Convert HResult to hexadecimal format (e.g., 0x80050007) $hexError = "0x{0:X8}" -f $result.HResult "āŒ Failed (Error: $hexError)" } 5 { "ā¹ļø Aborted" } default { "ā“ Unknown" } } $kb = if ($update.KBArticleIDs.Count -gt 0) { $update.KBArticleIDs -join ", " } else { "N/A" } Write-Host " - $status [KB$kb] $($update.Title)" } # Reboot handling if ($InstallResult.RebootRequired) { Write-Host "`nšŸ”„ System reboot required!" $choice = Read-Host "Restart now? (Y/N)" if ($choice -eq 'Y') { Restart-Computer -Force } } } else { Write-Host "šŸŽ‰ No updates available!" }