Freedom from Patch Management!

warrior holds up stick. freedom from patch management.

How long have you stayed up late night catching computers up on updates? How many times have you implored users to leave their computers on, only to be ignored? Dying in your beds, many years from now, would you be willing to trade all the days, from this day to that, for one chance – just one chance – to be free from chasing unpatched computers?

Solutions for Patch Management: No more chasing unpatched computers

Let me tell you about the biggest pain in patch management: Getting users to leave their computers on overnight. No matter how many times you ask, when it turns 5 o’clock, it’s lights out and they’re outta there! 

But what if there was a way to make it hurt a little if they don’t update their computers? What if through Conditional Access, they were blocked from accessing Office until they update? Wouldn’t that make everyone patch like their job depended on it? (Because, it kind of would!)

No more patch reports. No more begging. No more late nights. Oh, how the tables have turned!

A Boy Can Dream: Windows Compliance Policy

Windows 10/11 compliance policy in Microsoft Endpoint Manager offers a Minimum OS version setting that can enforce update compliance, but the version number has to be manually updated each month. If you’re an MSP with multiple clients, you’ll want a way to automate this.

windows 10/11 compliance policy screenshot showing where to find minimum OS version

You can also require Microsoft Defender for Endpoint’s risk score to be above a certain threshold, but there, again, Microsoft swings and misses. The risk score measures whether there were recent infections, not whether a device has unpatched vulnerabilities – that would be the exposure level in the next column of device inventory. Until Microsoft adds a check for exposure level, the only option left is to create a custom compliance policy.

Windows 10/11 Compliance Policy screenshot showing where to find Microsoft Defender for Endpoint Risk Score
Windows 10/11 Compliance Policy screenshot showing where to find Microsoft Defender for Endpoint Exposure Level

Custom Compliance Policy: Automating Patch Management

Custom compliance policy is a feature in preview, so let’s get the disclaimer out of the way that this is an unproven concept. If you’re the adventurous type, I invite you to come along with me on this journey. If not, check back in a few months to see if I still have my job.

Having said that…

The promise of custom compliance policy is that you can test for any condition you want, if you know your way around PowerShell. 

You can find a great post explaining how to set up a custom compliance policy here:

Below is my script for testing whether a computer has a pending cumulative update:

  1. Script returns a count of pending updates with “cumulative” in the title. The computer fails compliance if the number is greater than 0.
  2. I added an IF statement to bypass the test one week following Patch Tuesday. This is to give users enough time to update their computers after a new update is released.
# Set $StrtMonth to 1st day of the month
# Keep adding 1 day until you reach 1st Tuesday
while ($StrtMonth.DayofWeek -ne 'Tuesday') {$StrtMonth=$StrtMonth.AddDays(1)}
# Calculate Second and Third Tuesday of the month
$SecondTuesday = $StrtMonth.AddDays(7)
$ThirdTuesday = $StrtMonth.AddDays(14)

if ([datetime]::NOW -lt $SecondTuesday -or [datetime]::NOW -ge $ThirdTuesday) {
    # Get count of pending cumulative updates
    $UpdateSession = New-Object -ComObject Microsoft.Update.Session
    $UpdateSearcher = $UpdateSession.CreateupdateSearcher()
    $Updates = @($UpdateSearcher.Search("IsHidden=0 and IsInstalled=0").Updates)
    $CumulativeUpdateCount = @{"CumulativeUpdateCount" = ($Updates | Where-Object {$_.title -like "*cumulative*"}).count}
    # Return result as JSON for custom conditional access processing
    return $CumulativeUpdateCount | ConvertTo-Json -Compress
} else {
    #Bypass test 1 week following Patch Tuesday
    $CumulativeUpdateCount = @{"CumulativeUpdateCount" = 0}
    return $CumulativeUpdateCount | ConvertTo-Json -Compress

Here’s the JSON for custom setting:

             "Title":"Please run Windows Update.",
             "Description": "Please make sure that Windows is up-to-date. Outdated computers will lose access to emails in 3 days.  If you need assistance, please contact support."

Don’t Forget: Conditional Access

Marking a computer not compliant doesn’t prevent access until you pair it with Conditional Access. It’s a good idea to test your Conditional Access policy in “Report-only” mode before deploying in production.

GRANT compliant desktop access, Conditional Access, screenshot

In Conclusion

I must admit, the idea of blocking access to unpatched computers to force users to update has been a bit of a personal crusade. Either this is a really good idea, or I’ll be run down by an angry mob. Time will tell.

warriors get ready to fight against unpatched computers and users who refuse to update them

In the meantime, read my last post, “