Skip to content

Instantly share code, notes, and snippets.

@realchrisolin
Created April 21, 2025 13:05
Show Gist options
  • Select an option

  • Save realchrisolin/e65047cd453148e852065ef110b32af3 to your computer and use it in GitHub Desktop.

Select an option

Save realchrisolin/e65047cd453148e852065ef110b32af3 to your computer and use it in GitHub Desktop.

Revisions

  1. realchrisolin created this gist Apr 21, 2025.
    114 changes: 114 additions & 0 deletions script.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,114 @@
    # 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!"
    }