Skip to content

Instantly share code, notes, and snippets.

@realchrisolin
Created April 21, 2025 13:05
Show Gist options
  • Save realchrisolin/e65047cd453148e852065ef110b32af3 to your computer and use it in GitHub Desktop.
Save realchrisolin/e65047cd453148e852065ef110b32af3 to your computer and use it in GitHub Desktop.
fetch and install Windows Updates using COM API objects in powershell
# 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