229 lines
9.5 KiB
PowerShell
229 lines
9.5 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Diagnose Windows Updates
|
|
.DESCRIPTION
|
|
Shows detailed information about available updates and why they might be hidden
|
|
.NOTES
|
|
Author: oxmc
|
|
#>
|
|
|
|
#Requires -RunAsAdministrator
|
|
|
|
Write-Host "=== Windows Update Diagnostic Tool ===" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
# Search for updates
|
|
Write-Host "Searching for all available updates..." -ForegroundColor Yellow
|
|
$session = New-Object -ComObject "Microsoft.Update.Session"
|
|
$searcher = $session.CreateUpdateSearcher()
|
|
|
|
try {
|
|
$searchResult = $searcher.Search("IsInstalled=0")
|
|
|
|
Write-Host "Found $($searchResult.Updates.Count) total updates" -ForegroundColor Green
|
|
Write-Host ""
|
|
|
|
if ($searchResult.Updates.Count -eq 0) {
|
|
Write-Host "No updates available. Your system is up to date!" -ForegroundColor Green
|
|
exit 0
|
|
}
|
|
|
|
# Categorize updates
|
|
$criticalUpdates = @()
|
|
$securityUpdates = @()
|
|
$importantUpdates = @()
|
|
$driverUpdates = @()
|
|
$optionalUpdates = @()
|
|
$definitionUpdates = @()
|
|
|
|
foreach ($update in $searchResult.Updates) {
|
|
$isCritical = $false
|
|
$isSecurity = $false
|
|
$isImportant = $false
|
|
$isDefinition = $false
|
|
|
|
foreach ($category in $update.Categories) {
|
|
if ($category.Name -match "Critical") { $isCritical = $true }
|
|
if ($category.Name -match "Security") { $isSecurity = $true }
|
|
if ($category.Name -match "Important") { $isImportant = $true }
|
|
if ($category.Name -match "Definition") { $isDefinition = $true }
|
|
}
|
|
|
|
if ($update.Type -eq 2) {
|
|
$driverUpdates += $update
|
|
}
|
|
elseif ($isDefinition) {
|
|
$definitionUpdates += $update
|
|
}
|
|
elseif ($isCritical) {
|
|
$criticalUpdates += $update
|
|
}
|
|
elseif ($isSecurity) {
|
|
$securityUpdates += $update
|
|
}
|
|
elseif ($isImportant) {
|
|
$importantUpdates += $update
|
|
}
|
|
else {
|
|
$optionalUpdates += $update
|
|
}
|
|
}
|
|
|
|
# Display categorized results
|
|
Write-Host "=== UPDATE BREAKDOWN ===" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
if ($criticalUpdates.Count -gt 0) {
|
|
Write-Host "CRITICAL UPDATES ($($criticalUpdates.Count)):" -ForegroundColor Red
|
|
Write-Host "These SHOULD appear in Windows Update" -ForegroundColor Yellow
|
|
foreach ($update in $criticalUpdates) {
|
|
Write-Host " - $($update.Title)" -ForegroundColor White
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($securityUpdates.Count -gt 0) {
|
|
Write-Host "SECURITY UPDATES ($($securityUpdates.Count)):" -ForegroundColor Red
|
|
Write-Host "These SHOULD appear in Windows Update" -ForegroundColor Yellow
|
|
foreach ($update in $securityUpdates) {
|
|
Write-Host " - $($update.Title)" -ForegroundColor White
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($importantUpdates.Count -gt 0) {
|
|
Write-Host "IMPORTANT UPDATES ($($importantUpdates.Count)):" -ForegroundColor Yellow
|
|
Write-Host "These SHOULD appear in Windows Update" -ForegroundColor Yellow
|
|
foreach ($update in $importantUpdates) {
|
|
Write-Host " - $($update.Title)" -ForegroundColor White
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($driverUpdates.Count -gt 0) {
|
|
Write-Host "DRIVER UPDATES ($($driverUpdates.Count)):" -ForegroundColor Magenta
|
|
Write-Host "These are HIDDEN by default in Windows Update!" -ForegroundColor Yellow
|
|
Write-Host "Check: Settings > Windows Update > Advanced options > Optional updates" -ForegroundColor Cyan
|
|
foreach ($update in $driverUpdates) {
|
|
Write-Host " - $($update.Title)" -ForegroundColor White
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
|
|
# Check if AutoSelectOnWebSites is set
|
|
if ($update.AutoSelectOnWebSites) {
|
|
Write-Host " Status: Recommended by manufacturer" -ForegroundColor Green
|
|
}
|
|
else {
|
|
Write-Host " Status: Optional driver" -ForegroundColor Gray
|
|
}
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($definitionUpdates.Count -gt 0) {
|
|
Write-Host "DEFINITION UPDATES ($($definitionUpdates.Count)):" -ForegroundColor Green
|
|
Write-Host "These usually install automatically in the background" -ForegroundColor Yellow
|
|
foreach ($update in $definitionUpdates) {
|
|
Write-Host " - $($update.Title)" -ForegroundColor White
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($optionalUpdates.Count -gt 0) {
|
|
Write-Host "OPTIONAL UPDATES ($($optionalUpdates.Count)):" -ForegroundColor Blue
|
|
Write-Host "These may be HIDDEN in Windows Update" -ForegroundColor Yellow
|
|
Write-Host "Check: Settings > Windows Update > Advanced options > Optional updates" -ForegroundColor Cyan
|
|
foreach ($update in $optionalUpdates) {
|
|
Write-Host " - $($update.Title)" -ForegroundColor White
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
}
|
|
Write-Host ""
|
|
}
|
|
|
|
# Detailed information for each update
|
|
Write-Host "=== DETAILED UPDATE INFORMATION ===" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
$index = 1
|
|
foreach ($update in $searchResult.Updates) {
|
|
Write-Host "[$index] $($update.Title)" -ForegroundColor White
|
|
Write-Host " Type: " -NoNewline -ForegroundColor Gray
|
|
switch ($update.Type) {
|
|
1 { Write-Host "Software Update" -ForegroundColor Green }
|
|
2 { Write-Host "Driver Update" -ForegroundColor Magenta }
|
|
default { Write-Host "Unknown" -ForegroundColor Gray }
|
|
}
|
|
|
|
Write-Host " Size: $([math]::Round($update.MaxDownloadSize / 1MB, 2)) MB" -ForegroundColor Gray
|
|
|
|
Write-Host " Categories: " -NoNewline -ForegroundColor Gray
|
|
$categories = @()
|
|
foreach ($category in $update.Categories) {
|
|
$categories += $category.Name
|
|
}
|
|
Write-Host ($categories -join ", ") -ForegroundColor Gray
|
|
|
|
Write-Host " Mandatory: $(if ($update.IsMandatory) { 'Yes' } else { 'No' })" -ForegroundColor Gray
|
|
Write-Host " Auto-select: $(if ($update.AutoSelectOnWebSites) { 'Yes' } else { 'No' })" -ForegroundColor Gray
|
|
Write-Host " Hidden: $(if ($update.IsHidden) { 'Yes' } else { 'No' })" -ForegroundColor Gray
|
|
|
|
if ($update.KBArticleIDs.Count -gt 0) {
|
|
Write-Host " KB Article: KB$($update.KBArticleIDs[0])" -ForegroundColor Gray
|
|
}
|
|
|
|
Write-Host " Description: " -ForegroundColor Gray
|
|
Write-Host " $($update.Description.Substring(0, [Math]::Min(150, $update.Description.Length)))..." -ForegroundColor DarkGray
|
|
Write-Host ""
|
|
|
|
$index++
|
|
}
|
|
|
|
# Summary and recommendations
|
|
Write-Host "=== SUMMARY & RECOMMENDATIONS ===" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
if ($driverUpdates.Count -gt 0) {
|
|
Write-Host "WHY WINDOWS UPDATE SAYS 'UP TO DATE':" -ForegroundColor Yellow
|
|
Write-Host " You have $($driverUpdates.Count) DRIVER update(s) available." -ForegroundColor White
|
|
Write-Host " These are hidden by default and listed as 'Optional'." -ForegroundColor White
|
|
Write-Host ""
|
|
Write-Host "TO VIEW THESE IN WINDOWS UPDATE:" -ForegroundColor Yellow
|
|
Write-Host " 1. Open Settings" -ForegroundColor White
|
|
Write-Host " 2. Go to Windows Update" -ForegroundColor White
|
|
Write-Host " 3. Click 'Advanced options'" -ForegroundColor White
|
|
Write-Host " 4. Click 'Optional updates'" -ForegroundColor White
|
|
Write-Host " 5. Expand 'Driver updates' section" -ForegroundColor White
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($optionalUpdates.Count -gt 0) {
|
|
Write-Host "OPTIONAL UPDATES FOUND:" -ForegroundColor Yellow
|
|
Write-Host " You have $($optionalUpdates.Count) optional update(s)." -ForegroundColor White
|
|
Write-Host " These don't appear in the main Windows Update screen." -ForegroundColor White
|
|
Write-Host ""
|
|
}
|
|
|
|
if ($criticalUpdates.Count -eq 0 -and $securityUpdates.Count -eq 0 -and $importantUpdates.Count -eq 0) {
|
|
Write-Host "VERDICT:" -ForegroundColor Green
|
|
Write-Host " Windows Update is technically correct!" -ForegroundColor White
|
|
Write-Host " No critical/security/important updates are missing." -ForegroundColor White
|
|
Write-Host " The available updates are drivers/optional updates." -ForegroundColor White
|
|
Write-Host ""
|
|
}
|
|
|
|
Write-Host "SHOULD YOU INSTALL THESE?" -ForegroundColor Yellow
|
|
Write-Host " Drivers: Only if you're having issues with those devices" -ForegroundColor White
|
|
Write-Host " Optional: Review the description to decide" -ForegroundColor White
|
|
Write-Host ""
|
|
}
|
|
catch {
|
|
Write-Host "Error searching for updates: $($_.Exception.Message)" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Press any key to exit..." -ForegroundColor Gray
|
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|