Created
April 21, 2025 13:05
-
-
Save realchrisolin/e65047cd453148e852065ef110b32af3 to your computer and use it in GitHub Desktop.
fetch and install Windows Updates using COM API objects in powershell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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!" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment