The Lord of Compliance: The War of the Check Access Button

Last Updated on February 23, 2024 by rudyooms

In this updated blog, I am going to take a closer look at what exactly happens when you press the “Check Access” button in the Company Portal and why it takes so long to get your device compliant. I will divide this blog into multiple parts

  1. Introduction
  2. Check Access Button
  3. Defender Firewall Non-Compliant
  4. NodeCache
  5. Other Compliance Checks
  6. The ExpectedValue
  7. The Compliance Flow
  8. False Positive

1. Introduction

Last year I received an additional question while I was trying to answer a question on Reddit. As shown below, the OP asked me the question of what the device status check was actually doing

Afbeelding met tekst, binnen, schermafbeelding, sluiten

Automatisch gegenereerde beschrijving

I guess this question was a bit different than the blog I already wrote about build-in compliance policies

Intune and the built-in device compliance policies (call4cloud.nl)

With the device status check question, the OP was referring to the “Check Access” button and what is happening in the background when you press it and press it and press it like a maniac!

Afbeelding met tekst

Automatisch gegenereerde beschrijving

I am going to dedicate this blog to that button! Let’s see what happens when pressing this magical button of pleasure.

This script above “only” syncs the Custom Compliance Scripts!

2. Clicking on “it”

When we decide to press the “Check Access” button in the magical place Company Portal (Almost sounds like Tahiti) it seems that not that much is happening in the background….at first…

Afbeelding met tekst

Automatisch gegenereerde beschrijving

When we take a look at the code behind the button when we are pressing the “Check Access” button we will notice that it will trigger the “CheckForLatestComplianceStatusAsync() Task from the selfserviceportal DLL File

As shown above, it will try to fetch the current device state for the device. To do so it will first perform a “POST” operation to the URL https://fef.amsub0302.manage.microsoft.com/StatelessIWService/Devices(guid”)/CheckCompliance (GUID is your DeviceID AKA EntDMID)

To perform this post, it will also need to send over the required Bearer token to authenticate itself

Once it performed the initial POST to the service, it will try to get some details about the status of the device. To do so it will now perform a GET to the service. In this “GET” operation we will notice that the device will try to fetch the most recent compliance summary Intune has about the device

The response contains the LastContactDate and the ComplianceState we also noticed in the “CheckForLatestComplianceStatusAsync function.

After it initiated a connection to the service and asks for the latest contact date, it will kick off the PollingMonitor to keep an eye out for the status

While doing so it will also trigger the DeviceEnroller with the default /o parameter and 2 additional parameters: /c /z

This will create a queued schedule which would eventually (5 minutes delay) kick off the sync with the Intune service

We will notice the same behavior when we look at Fiddler. After 5 minutes the device would start reaching out to r.manage.microsoft.com.

After the deviceenroller its important job is done and the device is finally synced successfully with the service, the PollingMonitor will ask again for its Compliance Status. To do so, it will perform a get operation to the service.

As shown above, because of the 5-minute delay and the deviceenroller needed to do its job we will notice that it took about 11 minutes (10:02 – 10:13) to get our device Compliant!

In the response of the latest get operation we will notice that the LastContact date is updated and we are also noticing the up-to-date compliancestate and if the device IsCompliantInGraph

When the Polling Monitor has determined the new compliancestate, it will show you the message that you can access the company resources

At that same moment, a file in the user its local appdata\packages\microsoft.companyportal folder will be created and updated with the latest compliancestate. As shown below in a tmp file we will notice that my device seems to be Compliant

Now let’s zoom in and take a look at what exactly happens when we disable the firewall and configure a compliance policy to require the Firewall to be enabled on the device.

3. Defender Firewall Not Compliant!

I decided to make my device “NON-compliant” by disabling the Firewall and making sure the compliance policy to require the firewall to be enabled was configured

Afbeelding met tekst

Automatisch gegenereerde beschrijving

As shown below, I changed the compliance rule to require the Firewall to be enabled!

Afbeelding met tekst

Automatisch gegenereerde beschrijving

After making sure the prerequisites were configured, I pressed the “Check Access” button. Let’s see what happens when watching Fiddler.

  1. The device will perform a POST operation with the bearer token to

https://fef.amsub0302.manage.microsoft.com/StatelessIWService/Devices(guid’a903f3c6-ace8-440c-83c3-c3b5b2a1f3df’)/CheckCompliance?

2. The device will perform a GET to the same URL and get back a JSON with some Check Compliance settings in it

Afbeelding met tekst

Automatisch gegenereerde beschrijving

Looking at the NonCompliantRules, it looks like this is still the “old compliant version” as my device wasn’t compliant anymore with the firewall disabled!

Afbeelding met tekst

Automatisch gegenereerde beschrijving

3. After receiving the old JSON, we will indeed again notice that the device will “eventually” perform a sync with Intune.

https://r.manage.microsoft.com/devicegatewayproxy/cimhandler.ashx

In this “post operation“, we will notice the AADusertoken

And some details about the device:

  • ./DevInfo/HWDevID:
  • ./DevInfo/DevID
  • I guess after letting the service know, who is knocking on the door it will POST general information about MDM configuration capabilities on the device.
Afbeelding met tekst

Automatisch gegenereerde beschrijving

4. Now the service knows about the MDM configuration capabilities of the device it will post information about all of the “Nodes” that changed.

5. After posting the changed device settings to the r.manage.microsoft service, the device will again establish a connection to https://fef.amsub0302.manage.microsoft.com to determine if the device is still compliant or NOT. As shown below in the response we got, we now notice the NonCompliantRules.

Please take A good look at the “ExpectedValue”

Afbeelding met tekst

Automatisch gegenereerde beschrijving

When opening the Company Portal, we will notice that the device is indeed no longer compliant and is failing on the Firewall Status

Afbeelding met tekst

Automatisch gegenereerde beschrijving

So it seems that the NodeCache seems to play an important role in the whole compliance conversation. I guess we need to take a closer look at the NodeCache and the ChangedNodesData

4. NodeCache

When taking a closer look at different kinds of compliance settings and watching Fiddler I noticed that each time it mentioned a different “Changed” node. This example below is the one when playing around with the Firewall Compliance rule.

When looking at the “ChangedNodesData” I noticed that it mentions 22. NodesData, that rings a bell or two! Some time ago I wrote a blog about why you could run into the -201681112 error when you added a local admin. In this blog below I also mentioned the expected value and the NodeCache!

Remediation Error -201681112 when adding a Local Admin (call4cloud.nl)

Let’s find out if we could spot something in the registry mentioning Nodes 22, shall we? So I opened the provisioning\NodeCache\CSP\Device\MS DM Server\Nodes and opened the 22-node

As shown below, it is pointing us to the Firewall/Status… That can’t be a coincidence, right? With the Firewall being disabled, the expected value is 2

Afbeelding met tekst

Automatisch gegenereerde beschrijving

Did you also spot the NodeUri? This NodeUri refers to the ./vendor/MSFT/DeviceStatus CSP.

If we take a look with WMIExplorer (Running with System privileges) we could also spot the same status

When looking at the documentation of this CSP, it mentions that the DeviceStatus configuration is used by the enterprise to keep track of device inventory and query the state of COMPLIANCE of these devices. I guess we are on the right track here!

When we turned back on the heater, enabled the Firewall, synced a bit, and checked for compliance, the expected value was reverted to 0 (Enabled)

Afbeelding met tafel

Automatisch gegenereerde beschrijving

With this NodeCache change in the back of my mind, I also spotted something called: “CacheVersion” just a few stairs up in the MS DM Server part.

So we got these pointers

  • NodeCache
  • ChangedNodesData
  • ExpectedValue
  • NodeUri
  • CacheVersion
  • DeviceStatus

Those pointers led me to the NodeCache CSP. Sometimes I do read too quickly and I just skip parts if they aren’t important. This part I didn’t skip!

It synchronizes the client cache with the service side cache and!!!! It also provides an API for monitoring Device-Side cache changes….I guess when checking for compliance, the Intune service will check the expected value against the node’s actual value.

5. Other Compliance Checks

Besides the Firewall compliance policy, we also have some other compliance checks we need to take a look at. Let’s find out if we can spot some similarities

Device Health Attestation Flow | DHA | TPM | PCR | AIK (call4cloud.nl)

DefenderVersion

First, I am changing the required minimum version of Microsoft Defender Antimalware to 5.18.0 (should be 4.18.x.x)

Afbeelding met tekst

Automatisch gegenereerde beschrijving

We will notice that the ChangedNodeData is pointing us to “246”

This one is mentioning the ./vendor/MSFT/defender/health CSP instead of the ./vendor/MSFT/DeviceStatus we noticed earlier.

RealTimeProtection

Let’s take a look at which node is called upon when we disable Real-Time Protection of Microsoft Defender and require it in a compliance policy

Afbeelding met tekst

Automatisch gegenereerde beschrijving

This time I used the SYNCML viewer and Fiddler

  • SyncML Output
Afbeelding met tekst

Automatisch gegenereerde beschrijving
  • Fiddler ChangeNodes Output

As shown above, in the SYNCML and Fiddler output we got, we will notice the nodes 237 and 238. Guess which node URI they are mentioning? As shown below, again the ./vendor/MSFT/defender/health CSP

Afbeelding met tekst

Automatisch gegenereerde beschrijving

RtpEnabled, I guess that just stands for Real-Time Protection enabled. Guess what difference we spot when RTP is enabled or disabled

Afbeelding met tafel

Automatisch gegenereerde beschrijving

Minimum OS

Let’s finish this part of the blog by changing the Minimum OS version to something that doesn’t exist.

Afbeelding met tekst

Automatisch gegenereerde beschrijving

Here you go!! After pressing the check access button and waiting and waiting, the Noncompliantrules mention I need to update the operating system as it is expecting (ExpectedValue) a value greater than 14.0.18363.900

When looking at the SyncML output, this time it doesn’t use the devicestatus or defender NodeUri but by the looks of it, it uses the ./devdetail/SwV nodeURI

Afbeelding met tekst

Automatisch gegenereerde beschrijving

SwV as in SoftWareVersion?

Afbeelding met tekst

Automatisch gegenereerde beschrijving

6. The ExpectedValue

Looking at this ExpectedValue that changed each time we “broke” something to get non-compliant I guess we need to read some other blogs that mention the “ExpectedValue” keys because this value seems important

Intune -2016281112 Remediation failed Chrome Policies CSP (call4cloud.nl)

Remediation Error -201681112 when adding a Local Admin (call4cloud.nl)

Every time “We change” something to get the device not compliant anymore, the expected value in the NodeCache changes.

After setting up Procmon to start watching the NodeCache and pressing the sync button, we will notice that (of course) before this information is uploaded to Intune, the Omadmclient.exe will set this registry key to the value it corresponds to

When the management session is initialized the configuration service will check if this value in the expected registry key corresponds with the node’s actual value….. Let’s continue to see what happens when that process is a bit broken

7. The Compliance Flow

Let’s add all the pieces of the puzzle together and see what we can come up with when combining all the keywords and reading the documentation.

  1. The device initializes a compliance check (CheckCompliance) and connects to MDM service
  2. The deviceenroller kicks off the sync and Intune queries the “cacheversion” on the device
  3. Intune sends a get operation for the “changednodes”
  4. The device sends a list of “changednodes”
  5. For each changed node, Intune sends a get command to retrieve the actual value with the Get <nodeuri> (as we noticed earlier)
  6. The CachedNode “ExpectedValue” will be updated with the actual value
  7. Intune will update their side of things with the most recent value
  8. A new “CacheVersion” will be created and sent back to the device

8. False Positive

While playing around with the Compliance policy I decided to see what happen when I rebooted the device and immediately clicked on the “Check Access” button

Looking at the noncompliant rules, it somehow mentioned the fact that I didn’t have an Antivirus enabled or registered with the Windows Defender Security Center. That’s odd as I didn’t disable the AV only the Real-time protection part of it

When looking at the corresponding registry key, I noticed that the expected value was empty! Just like I noticed in the blog mentioning the -201628112 remediation error when you configured a local admin account with the corresponding CSP.

Luckily Microsoft their documentation is quite accurate about this behavior….yes, I said it out loud!!!

Afbeelding met tekst

Automatisch gegenereerde beschrijving

When immediately syncing the device after a reboot the setting may report as an Error. After pressing the “sync button” first and waiting some time, that not configured expectedvalue changed back to zero

Afbeelding met tekst

Automatisch gegenereerde beschrijving

If all those steps took place the device will reach out again (every 30 seconds) to https://fef.amsub0302.manage.microsoft.com/StatelessIWService/Devices to determine if it is compliant or not compliant

Conclusion

Summary… Conclusion… it is almost the same… Let’s create a simple summary of stuff that the “Check Access button” touches when you click on it. The device will reach out to the service and start syncing the device. After syncing the device it would fetch the latest compliancestate to determine if it’s compliant. This process to get the device compliant will take some time because we have a 5-minute delay before the sync starts and we need to wait until the sync is successfully!

8 thoughts on “The Lord of Compliance: The War of the Check Access Button

  1. Rudy,
    Another great post.

    I have some comments around the blank ExpectedValue state and its impact on compliance.
    I am wondering about the timing of the sync process, and it is causing the synml500 error (blank ExpectedValue state). The default scheduled task that runs on the device that kicks off the deviceenroller.exe sync process has one that starts at user logon. If say the user reboots the device and is using bio face/finger or types their pw super fast the task would appear to start the sync too fast and cause those blank values for fw/av components. Causing devices to report a syncml500 error message in the portal and cause compliance issues, mainly for never before compliant devices (new). Devices that were marked compliant at least once will follow the error handling compliance grace period.

    Since we are using pre-provisioning the initial scheduled tasks that does the 3min/15 syncs after enrollment are no longer in scope because of the delay in the time it is provisioned and the time a user receives the device and completes enrollment. Causing issues for these devices after user enrollment where we have to manually sync device that get in this syncml500 error state because of too fast login/sync, and it causes a delay in a user’s onboarding and becoming compliant. Otherwise, we are relying on the 8 hour sync scheduled task. ;(

    We have been dealing with these for months on new devices and really hoping Microsoft sees these issues and resolves them. I suggested they put a delay in the scheduled task for logon to prevent these error states. We are also asking them to modify the tasks to use/update the date and time the user completes enrollment and not when the device was pre-provisioned.

    If any of this makes sense to you and you can reach out to your contacts at Microsoft that would be great.

  2. HI Rudy, thanks for sharing your technical advice on this topic. For me with company portal app and the “check access” button – it’s a hot and cold situation. Because with our “Corporate Device Compliance Policy” – I’ve set the option “require bitlocker – yes” And it seems like this is something that the company portal app doesn’t like 😀

    I’m looking forward to read an article about BitLocker and Company Portal App/Check Access. (Maybe with some tips how to fasten the process to get a green check mark :P)

    Thx!

    1. Hehehe… The DHA bitlocker requirement is something more .. Because before the device could know that its compliant the health attestation needs to do it work first

      https://call4cloud.nl/2021/10/device-health-attestation-age-of-compliance/

      to pass the latest informaiton from the pcr the device needs to reboot.. Once it reboot it could communicate with the health attestation service
      Which could also give you some issues… 🙂 ..

      https://call4cloud.nl/2023/04/are-you-there-intune-its-me-hac/

      So if you combine those 2 blogs to the check access button 🙂 …

  3. This is great insight into the Check Access button! Thank you for sharing.
    As someone commented previously, I too am trying to figure out if there is a way to silently trigger the Check Access button when the user logs into their device to overcome the False positive issue.
    Would you know if there is a way this can be manually triggered? Either through re-running some scheduled task or triggering it via the enrollment service.
    If so, it can be integrated into a script to run on new deices once the user has been logged in for greater than 5 minutes.

Leave a Reply

Your email address will not be published. Required fields are marked *

6  +  4  =