PowerShell module for Windows Update infrastructure remediation. Achieves approximately 80-90% of what enterprise patch prerequisite handlers accomplish without native binaries or external dependencies.

Requirements

  • PowerShell 5.1 or later
  • Administrator privileges (typically runs as SYSTEM)
  • Windows 10/11 or Windows Server 2016+
  • InvokeSystems.Common module (auto-imported from sibling path)

Installation

Import-Module .\InvokeSystems.UpdateRepair.psd1

Usage

Basic Usage

Invoke-InvUpdateRepair

Verbose Output

Invoke-InvUpdateRepair -Verbose

Enable Event Logging

Invoke-InvUpdateRepair -EnableEventLog

Skip Long-Running Checks

Invoke-InvUpdateRepair -SkipDism -SkipSfc

Custom Log Path

Invoke-InvUpdateRepair -LogPath 'D:\Logs\UpdateRepair'

Dry Run

Invoke-InvUpdateRepair -WhatIf

Full Verbose with Event Log

Invoke-InvUpdateRepair -Verbose -EnableEventLog

What It Does

Phase 1: Stop Update Services

Stops services in dependency order:

  1. wuauserv (Windows Update)
  2. bits (Background Intelligent Transfer Service)
  3. cryptsvc (Cryptographic Services)
  4. msiserver (Windows Installer)

Phase 2: Clear Update Caches

Removes contents from:

  • $env:SystemRoot\SoftwareDistribution
  • $env:SystemRoot\System32\catroot2

Phase 3: Reset BITS Jobs

Cancels all BITS transfer jobs for all users.

Phase 4: DISM RestoreHealth

Runs DISM /Online /Cleanup-Image /RestoreHealth to repair the Windows component store.

Phase 5: SFC VerifyOnly

Runs SFC /VerifyOnly to check system file integrity without making changes.

Phase 6: Restart Services

Restarts services in reverse order:

  1. msiserver
  2. cryptsvc
  3. bits
  4. wuauserv

Phase 7: Trigger Update Scan

Runs UsoClient StartScan to initiate update detection. If UsoClient is unavailable or fails, the module falls back to wuauclt /resetauthorization /detectnow.

Exit Codes

CodeMeaning
0Success - all steps completed
1Partial remediation - some steps failed
2Fatal failure - critical step failed

Log Files

All operations are logged to $env:ProgramData\InvokeSystems\UpdateRepair\ by default:

  • UpdateRepair.log - Main operation log with timestamps
  • dism_stdout.log - DISM output
  • dism_stderr.log - DISM errors
  • sfc_stdout.log - SFC output
  • sfc_stderr.log - SFC errors

Event Log

When -EnableEventLog is specified, entries are written to the Application event log:

  • Source: InvokeSystems-UpdateRepair
  • Event IDs:
    • 1000 - Informational messages
    • 1001 - Success messages
    • 2000 - Warning messages
    • 3000 - Error messages

View recent events:

Get-EventLog -LogName Application -Source 'InvokeSystems-UpdateRepair' -Newest 20

Output Object

[PSCustomObject]@{
    Success        = [bool]    # Overall success status
    ExitCode       = [int]     # 0, 1, or 2
    Steps          = [array]   # Array of step results
    TotalElapsedMs = [long]    # Total execution time
    LogPath        = [string]  # Path to log directory
    StartTime      = [datetime]
    EndTime        = [datetime]
}

Scheduled Task Deployment

For enterprise deployment via scheduled task:

$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath 'Modules\InvokeSystems.UpdateRepair'
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument @"
-NoProfile -ExecutionPolicy Bypass -Command "Import-Module '$modulePath'; `$result = Invoke-InvUpdateRepair; exit `$result.ExitCode"
"@

$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At '02:00'
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries

Register-ScheduledTask -TaskName 'Windows Update Remediation' -Action $action -Trigger $trigger -Principal $principal -Settings $settings

Idempotency

This module is designed to be safe for repeated execution:

  • Services already stopped are skipped
  • Empty cache directories are handled gracefully
  • BITS jobs that do not exist are skipped
  • Services already running are skipped

Module Structure

InvokeSystems.UpdateRepair/
├── Private/
│   ├── Clear-UpdateCache.ps1
│   ├── Initialize-RepairLogDirectory.ps1
│   ├── Invoke-DismRestoreHealth.ps1
│   ├── Invoke-SfcVerify.ps1
│   ├── Invoke-UpdateScan.ps1
│   ├── Reset-BitsJob.ps1
│   ├── Start-UpdateService.ps1
│   ├── Stop-UpdateService.ps1
│   ├── Write-RepairEventLog.ps1
│   └── Write-RepairLog.ps1
├── Public/
│   └── Invoke-InvUpdateRepair.ps1
├── tests/
│   └── InvokeSystems.UpdateRepair.Tests.ps1
├── CHANGELOG.md
├── README.md
├── InvokeSystems.UpdateRepair.psd1
└── InvokeSystems.UpdateRepair.psm1