Pages

Wednesday, June 25, 2025

Supercharging Patch Compliance Checks with PowerShell 7 Parallelism

When you're managing thousands of systems, checking for patch compliance across all of them can become a real slog, especially if you’re still looping through them sequentially or juggling a pile of background jobs. That used to be me.

Recently, I rewrote one of my older patch check scripts using PowerShell 7’s ForEach-Object -Parallel feature, and the results were night and day. Here’s a look at how I did it and why you might want to make the leap, too.

The Legacy Job-Based Approach (Worked... but Clunky)

$servers = Get-Content .\serverlist.txt
$jobs = foreach ($server in $servers) {
    Start-Job -ScriptBlock {
        $s = $using:server
        Invoke-Command -ComputerName $s -ScriptBlock {
            Get-HotFix -Id KB5008380
        }
    }
}

# Wait and collect
$results = $jobs | Wait-Job | ForEach-Object {
    Receive-Job -Job $_
}

It got the job done, but there was too much scaffolding: tracking, collecting, cleaning up jobs, and dealing with throttling manually.

Enter PowerShell 7: A One-Liner Game Changer

$servers = Get-Content .\serverlist.txt

$results = $servers | ForEach-Object -Parallel {
    try {
        Invoke-Command -ComputerName $_ -ScriptBlock {
            Get-HotFix -Id KB5008380
        }
        [PSCustomObject]@{ Server = $_; Patched = $true }
    }
    catch {
        [PSCustomObject]@{ Server = $_; Patched = $false }
    }
} -ThrottleLimit 10
  • ✔️ Built-in throttling
  • ✔️ Fewer moving parts
  • ✔️ Much easier to maintain and explain to others

And yes—runtime improved significantly when scaled out.

Bonus: Reporting

You can easily integrate this with your preferred reporting pipeline—CSV, HTML, or even Power BI. Here's a quick CSV export:

$results | Export-Csv .\PatchResults.csv -NoTypeInformation

Final Thoughts

The job-based model served us well, but with PowerShell 7's baked-in parallelism, most of my automation scripts just got faster and cleaner. This is one of those “glad I made the switch” moments—especially when time-to-resolution matters.

Have you tried this approach yet? I’d love to hear how you're using -Parallel in your environment.

No comments:

Post a Comment