Skip to main content

Forcing Windows 11 Feature Update Readiness Assessments

·
Intune Windows 10 and later Software Updates Feature Updates Remediation Scripts PowerShell Security
Author
Nick Benton
Principal Cloud Endpoint Consultant | Intune Blogger
Table of Contents

I’ve spent far too much time digging into the Windows Feature Update Readiness reports available in Intune, having used them extensively in a previous series of posts:

Using the data within the report to tag devices with their update risk score, hopefully making that move to Windows 11 a little smoother and without incident.

What happens to your devices that haven’t sent their precious readiness data to Microsoft for snooping processing, or those devices with results that have changed from say High to Low risk, or the devices that are marked as Unknown by the report because the data hasn’t been sent yet?

Feature Update Readiness Report
Windows 11 Feature Update Readiness report.

Can we help the devices with missing or stale data especially now that the Windows 11 24H2 report is now available?

Sure we can.

Microsoft Compatibility Appraiser
#

Before we start fiddling (ahem) with settings on devices to get them to send their data to Microsoft, we need an understanding of where the Feature Update Readiness data is stored on the device…

Feature Update Readiness settings
App Compatibility Registry settings.

…yeah it’s the registry, where else would it be?

Thanks to Johan Arwidmark for his post on the data stored in the registry and what it means, and the linked post from Adam Gross about the Compatibility Appraiser itself, we now have some way of identifying whether a device has been assessed for the feature updates available to it based on the data in the registry.

Simply put, we can use a detection script in Intune to check if the appraisal has run, when it has run, and then a remediation script to force the tool to run if we need to.

Remediation Scripts
#

Both PowerShell scripts are available in my GitHub repo, but to give you a little background to them, and how to use them, keep reading.

Detection
#

As I’m only interested in the latest and greatest Windows 11 Feature Update compatibility data, we only really need to check on the keys located in:

HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers\

Specifically these ones:

Registry Key Feature Update Version
GE24H2 Windows 11 24H2
NI23H2 Windows 11 23H2

We can populate the $featureUpdate variable in the detection script with the corresponding Registry Key to check to see if data exists, and if it doesn’t we’ll exit in a way that Intune will start a remediation.

So for Windows 11 24H2 it’s $featureUpdate = 'GE24H2', and for Windows 11 23H2 it would be $featureUpdate = 'NI23H2'.

$featureUpdate = 'GE24H2' # Windows 11 24H2
#$featureUpdate = 'NI23H2' # Windows 11 23H2
$registry = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers\$featureUpdate"

If the registry key does exist, we can then query the value of the string TimestampEpochString which is populated by the App Compatibility tool when it was last run successfully, and compare it to the date and time when the script runs, minus a set number of hours (in Epoch format), configured using the $schedule variable.

$featureUpdate = 'GE24H2' # Windows 11 24H2
#$featureUpdate = 'NI23H2' # Windows 11 23H2
$registry = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers\$featureUpdate"

$lastRun = Get-ItemPropertyValue -Path $registry -Name TimestampEpochString -ErrorAction SilentlyContinue
$schedule = 24 # update based on the remediation schedule
$nowLessHours = Get-Date $((Get-Date).AddHours(-$schedule)) -UFormat +%s

if ($lastRun -lt $nowLessHours) {
    Write-Warning "App Compat not run in last $schedule hours"
    Exit 1
}
Depending on your Remediation script schedule will depend on the value of this variable, you don’t want remediations running indefinitely.

If you’re running this every seven days for example, you want to set $schedule = 168, so the remediation will only run if the App Compatibility tool hasn’t run in the last seven days (7 x 24 = 168), more quick maths.

Feature Update Readiness Remediation Schedule
App Compatibility Remediation Script schedule in Intune.

So with a bit of error capture, we now have a complete detection script that can be tailored based on the Feature Update we want the data for, and the schedule that the remediation in Intune will be run.

Check-FeatureUpdateAppraisal-Detection.ps1
$schedule = 24 # update based on the remediation schedule
$featureUpdate = 'GE24H2' # Windows 11 24H2
#$featureUpdate = 'NI23H2' # Windows 11 23H2

Try {
    $registry = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers\$featureUpdate"
    # Checks if the key exists and the last run of the App Compat
    Try {
        $lastRun = Get-ItemPropertyValue -Path $registry -Name TimestampEpochString -ErrorAction SilentlyContinue
    }
    Catch {
        Write-Warning "App Compat not run for Windows 11 $featureUpdate"
        Exit 1
    }

    # if the key and dword exist checks the last run time
    $nowLessHours = Get-Date $((Get-Date).AddHours(-$schedule)) -UFormat +%s
    if ($lastRun -lt $nowLessHours) {
        Write-Warning "App Compat not run in last $schedule hours"
        Exit 1
    }
    else {
        Write-Output "App Compat run in last $schedule hours"
        Exit 0
    }
}
Catch {
    Write-Error $_.Exception
    Exit 2000
}

Remediation
#

The detection now sorted, we should test a concept of a remediation.

Go and delete the following key in the registry from a test device, or your own if you feel like it:

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\CompatMarkers\GE24H2

We’ll bring the data in that key back, I promise, truss mi daddi.

We do need a way to kick off the App Compatibility tool using a remediation script, so we can start the application itself CompatTelRunner.exe located $env:windir\system32, with the associated arguments:

$filePath = "$env:windir\system32\CompatTelRunner.exe"
$argumentList = "-m:appraiser.dll -f:DoScheduledTelemetryRun"
Start-Process -WindowStyle Hidden -FilePath $filePath -ArgumentList $argumentList -Wait

To bring back the registry data we deleted, just run the above from an elevated PowerShell prompt…

And all being well, the App Compatibility tool will have run successfully, and the registry will be populated with the report information we so desperately need:

Feature Update Readiness settings
App Compatibility Registry settings.

So throwing those three lines into something that should handle errors, we get a remediation script.

Check-FeatureUpdateAppraisal-Remediation.ps1
Try {
    $filePath = "$env:windir\system32\CompatTelRunner.exe"
    $argumentList = "-m:appraiser.dll -f:DoScheduledTelemetryRun"

    if (Test-Path -Path $filePath){
        Start-Process -WindowStyle Hidden -FilePath $filePath -ArgumentList $argumentList -Wait
        Write-Output "App Compat Assessment started"
        Exit 0
    }
    else {
        Write-Output "Unable to start App Compat Assessment"
        Exit 1
    }

}
Catch {
    Write-Error $_.Exception
    Exit 2000
}

So if the detection identifies either that the key doesn’t exist, or if the last time the App Compatibility tool was run is outside of your schedule, it will kick off the tool to run and evaluate the Feature Updates it has available.

Deployment
#

You should be using remediation scripts in Intune already, so go and create one using the two provided scripts after updating the variables in the detection script, with it looking something like this:

Feature Update Readiness remediation
Feature Update remediation script settings in Intune.

With whatever schedule you’ve decided and updated the $schedule variable in the detection script to, in this example it’s once daily i.e., 24 hours.

If you’re lucky your devices will then start checking to see the last time the tool was run, and kick off a new run if needed.

Feature Update Readiness Remediation Report
Feature Update remediation report status.

Now just to wait a quick 52 hours for the report data to update 😅.

Summary
#

You should be aiming to get your devices to Windows 11 sharpish if you haven’t done so already, and Intune provides you with the tooling to at least understand the impact of what that update process looks like with the readiness report.

The readiness report needs your devices to send them data, and if the data doesn’t exist, then they’ll have nothing to send, hence the raft of devices classified as ‘Unknown’ when it comes to their update risk state.

All we’re doing is helping those devices along, and ensuring that they have their compatibility data ready to send to Microsoft, so you can make informed choices when it comes to distributing Windows 11 feature updates.

Off you trot now, you’ve got Windows 10 devices to update.

Related

Keeping Windows Store Apps Updated with Microsoft Intune
Intune Windows 10 and later Software Updates Remediation Scripts Apps PowerShell Windows Autopilot Security
Automatically Resizing the WinRE Partition for Windows Update KB5034441
Intune Windows 10 and later Software Updates PowerShell Remediation Scripts BitLocker Endpoint Security Security
Patching Gaps in the CIS Windows 11 Benchmark - Level 2 Windows 11
Intune Windows 10 and later Security Center for Internet Security (CIS) Custom Profiles Settings Catalog Remediation Scripts PowerShell