Using update status as part of the compliance of Windows devices

This week is focused on the update status of Windows devices. More specifically, this week is focused on making sure that Windows devices can only be compliant when running the latest cumulative update. Within a device compliance policy, it was already possible to specify a specific Windows version. That, however, is a manual action. Over and over again. That can be achieved easier nowadays. A few months ago I wrote about working with custom compliance settings. That enables the ability to add custom scripting to device compliance policies. Custom scripting basically means that anything is possible. Including the check on the update status. This post will show how to leverage that functionality with a small custom script to check for the update status of the latest cumulative update. For a check like that, a daily verification is often enough.

Important: At the moment of writing custom settings for compliance is still in preview. Once it becomes generally available, it will be additional cost to the licensing options that include Microsoft Endpoint Manager or Intune.

Creating a PowerShell script to check for the update status

When looking at the configuration, the first action is to create a PowerShell script that will be used to check for the update status of the latest cumulative update for Windows. The idea, however, is not that the user will have no time to install the latest cumulative update. With that in mind, the idea is to give the user a period of time to install that latest update. The PowerShell script example below checks for the latest patch Tuesday and adds an offset of days that is used to provide the user with the install window. Based on the installation status of the latest cumulative update, the Windows device will return if it’s Up-to-date or Not up-to-date. That information is returned in a compressed single line JSON-format.

[datetime]$dtToday = [datetime]::NOW
$strCurrentMonth = $dtToday.Month.ToString()
$strCurrentYear = $dtToday.Year.ToString()
[datetime]$dtMonth = $strCurrentMonth + '/1/' + $strCurrentYear

while ($dtMonth.DayofWeek -ne 'Tuesday') { 
      $dtMonth = $dtMonth.AddDays(1) 
}

$strPatchTuesday = $dtMonth.AddDays(7)
$intOffSet = 7

if ([datetime]::NOW -lt $strPatchTuesday -or [datetime]::NOW -ge $strPatchTuesday.AddDays($intOffSet)) {
    $objUpdateSession = New-Object -ComObject Microsoft.Update.Session
    $objUpdateSearcher = $objUpdateSession.CreateupdateSearcher()
    $arrAvailableUpdates = @($objUpdateSearcher.Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0").Updates)
    $strAvailableCumulativeUpdates = $arrAvailableUpdates | Where-Object {$_.title -like "*cumulative*"}

    if ($strAvailableCumulativeUpdates -eq $null) {
        $strUpdateStatus = @{"Update status" = "Up-to-date"}
    } 
    else {
        $strUpdateStatus = @{"Update status" = "Not up-to-date"}
    }
} 
else {
    $strUpdateStatus = @{"Update status" = "Up-to-date"}
}

return $strUpdateStatus | ConvertTo-Json -Compress

Note: The PowerShell script logics for determining the second Tuesday of the month are based on this example provided by Travis Roberts on his GitHub.

Once the PowerShell script is written, it can be added to Microsoft Intune. That action should be performed before the update status can be used in the device compliance policy. The following five steps walk through the process of adding that script.

  1. Open the Microsoft Endpoint Manager admin center portal and navigate to Endpoint security > Device compliance > Scripts
  2. On the Compliance policies | Scripts page,  click Add > Windows 10 and later
  3. On the Basics page, specify a Name and optionaly a Description and Publisher and click Next
  4. On the Settings page (as shown in Figure 1), specify the following information and click Next
  • Detection script: Copy the just written PowerShell script
  • Run this script using the logged on credentials: Select No to run the PowerShell script in SYSTEM context
  • Enforce script signature check: Select No to not perform a signature check on the PowerShell script
  • Run script in 64 bit PowerShell Host: Select Yes to run the PowerShell script in 64-bit
  1. On the Review + create page, verify the configuration of the PowerShell script and click Create

Note: Once the PowerShell script is added, it can be editted via Microsoft Endpoint Manager admin center portal.

Creating JSON to verify the update status

Once the PowerShell script is written and added to Microsoft Intune, the second action is construct a JSON-file. That JSON-file can be used to define the update status information that the device compliance policy should verify. Including the acceptable values for that status information. It even contains the options to configure a message that will tell the user what to do when the device is not compliant with the specified update status. In this case, the JSON-file must verify the Update status that is returned via the PowerShell script. Besides that, the operand can be used to verify for Up-to-date or Not up-to-date status.

{
"Rules":[ 
    { 
       "SettingName":"Update status",
       "Operator":"IsEquals",
       "DataType":"String",
       "Operand":"Up-to-date",
       "MoreInfoUrl":"https://petervanderwoude.nl",
       "RemediationStrings":[ 
          { 
             "Language":"en_US",
             "Title":"Device must be running the latest cumulative update for Windows.",
             "Description": "Please make sure that the latest cumulative update for Windows is installed."
          }
       ]
    }
 ]
}

Creating a device compliance policy with update status check

Once the JSON-file is constructed, the third and last action is to create and configure a device compliance policy. That policy can be used to verify if the Windows devices are running the latest cumulative update and if those devices comply with the company policies. That compliance information can be used for reporting purposes, but also for usage with Conditional Access to determine access to data and resources. The following nine steps walk through the process of creating a device compliance policy that includes (and focusses on) the custom compliance setting for the update status.

  1. Open the Microsoft Endpoint Manager admin center portal navigate to Endpoint security Device compliance
  2. On the Compliance policies | Policies blade, click Create Policy to open the Create a policy page
  3. On the Create a policy page, select Windows 10 and later with Platform and click Create
  4. On the Basics page, provide a valid name for the device compliance policy and click Next
  5. On the Compliance settings page, navigate to the Custom Compliance section (as shown in Figure 2), provide the following information and click Next
  • Custom compliance: Select Require to enable the custom compliance setting
  • Select your discovery script: Select the just uploaded PowerShell script
  • Upload and validate the JSON file with your custom compliance settings: Select the just constructed JSON file
  1. On the Actions for noncompliance page, leave the default configuration of Action on Mark device noncompliant with Schedule (days after noncompliance) on Immediately and click Next
  2. On the Scope tags page, configure the applicable scope tags and click Next
  3. On the Assignments page, configure the assignment by selecting the applicable group and click Next
  4. On the Review + create page, review the configuration and click Create

Note: Keep in mind that a device compliance policy only supports a single custom compliance setting. That means a single PowerShell script. For multiple settings, use single PowerShell script to detect multiple different settings.

Experiencing the results of the update status check

Now let’s end this post by having a look at the results of the custom compliance setting for the update status. That will show it integrates with the compliance state of the device. Below in Figure 3 is an example of the update status of the latest cumulative update, that was created throughout this post.

More information

For more information about custom settings for compliance, refer to the following docs.

17 thoughts on “Using update status as part of the compliance of Windows devices”

  1. Hi Peter,

    Great post and great use of the service, I’ve been waiting for this functionality for some time now as will others I suspect!

    You mention that in order to use custom compliance it won’t be included in the Intune license, is this just the Intune license it’s not included in or will it really be an add-on for something like M365 BP/E3/E5?

    Reply
  2. Unfortunately this is typical Microsoft. After companies are heavily invested in Intune, they start making new features paid add-ons, even for those with E5 licenses. If I squint really hard, I could see where remote help might make sense, since you previously had to pay for TeamViewer or another product. But custom compliance? Come on.

    Within a few years I think any useful new features will be paid add-ons, with the Intune licenses only covering the very basics.

    Reply
  3. Hi Peter,

    You’ve already defined an offset of 7 days in the script to give the user time to update their device. What do you think about changing this offset to 0 and configure in the custom compliance policy to mark this device after 7 days?

    That would be much more customisable right?

    Reply
  4. This is such a great use of a cool feature, but I fear there must be some reason why Microsoft is not offering update compliance (for cumulative updates) out of the box?

    Reply
    • Hi JM,
      There are downsides of this method, as mentioned in the post, that are related to how often the compliance is checked. For a Microsoft standard option, you could use the build numbers, but that would require a monthly adjustment to the information.
      Regards, Peter

      Reply
  5. I’ve set this up in our environment and assigned it to a couple of test devices.
    When checking the compliance, the compliance status is ‘not applicable’ – any idea why this might be?
    They are Windows 10/11 devices.

    Reply
  6. Hello!
    Does this script work for any localization? I mean, won`t it be a problem to evaluate a compliance for Spanish, Polish, Ukrainian Windows?
    Thanks in advance!

    Reply
  7. Hi Peter,

    Nice blog, great idea. Though I have an issue.
    I configured this and followed your steps 1-on-1 with the intOffSet=7.
    I then installed a Windows 11 x64 22H2 22621.1105 VM and disabled the Windows Update service to prevent if from updating. This VM did not update, but it’s saying it’s compliant:
    “PreRemediationDetectScriptOutput”:”{\”Update status\”:\”Up-to-date\”}”

    Do you have an idea why that is? That build is of January 10th.

    Reply
  8. Hello Peter,

    Loved your explaination! However, when i tested this policy the device installed the update but needed the reboot to finish the update process but in ntune, device was always compliant (i guess as update was already installed). This is the problem we have been facing in our environment as user dont restart their systems.

    Do you have idea how we can modify the script to detect the reboot status of updates as well ?

    Thank you

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.