In this updated blog, I will 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
Last year, I received an additional question while trying to answer a question on Reddit. As shown below, the OP asked me what the device status check in the Company Portal App in Windows was actually doing.
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 the check access button and continue to press it like a maniac!
I am going to dedicate this blog to that check access button! Let’s see what happens when pressing this magical button of pleasure.
A small side note here: for everyone thinking that this command below does the same, you are wrong!!
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 much is happening in the background….at first…
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 performs 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 initiates 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.
As shown below, I changed the compliance rule to require the Firewall to be enabled!
After making sure the prerequisites were configured, I pressed the “Check Access” button. Let’s see what happens when watching Fiddler.
- The device will perform a POST operation with the bearer token to
2. The device will perform a GET to the same URL and get back a JSON with some Check Compliance settings in it
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!
3. After receiving the old JSON, we will again notice that the device will “eventually” 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.
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”
When opening the Company Portal, we will notice that the device is indeed no longer compliant and is failing on the Firewall Status
So, it seems that NodeCache plays 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 I examined different kinds of compliance settings and watched Fiddler, I noticed that each time, it mentioned a different “Changed” node. This example below is when I played around with the Firewall Compliance rule.
When looking at the “ChangedNodesData” I noticed that it mentions 22. ChangesNodesData, 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 node 22.
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
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
The documentation of this CSP 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)
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 read too quickly and skip parts that aren’t important. This part, I didn’t skip!
It synchronizes the client cache with the service-side cache and provides an API for monitoring Device-Side cache changes….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
Please note: I am only talking about the NON-DHA compliance policies.. if you want to know how DHA works you will need to read a different blog:
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)
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
This time I used the SYNCML viewer and Fiddler
- SyncML Output
- 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
RtpEnabled, I guess that just stands for Real-Time Protection enabled. Guess what difference we spot when RTP is enabled or disabled.
Minimum OS
Let’s finish this part of the blog by changing the Minimum OS version to something that doesn’t exist.
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
SwV as in SoftWareVersion?
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.
- The device initializes a compliance check (CheckCompliance) and connects to MDM service
- The deviceenroller kicks off the sync and Intune queries the “cacheversion” on the device
- Intune sends a get operation for the “changednodes”
- The device sends a list of “changednodes”
- For each changed node, Intune sends a get command to retrieve the actual value with the Get <nodeuri> (as we noticed earlier)
- The CachedNode “ExpectedValue” will be updated with the actual value
- Intune will update their side of things with the most recent value
- A new “CacheVersion” will be created and sent back to the device
8. False Positive: 2016345612(Syncml(500)
While playing around with the Compliance policy, I decided to see what happened 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.
I noticed that the expected value was empty when I looked at the corresponding registry key! When switching back to the Intune Portal, we will notice that,the device is no longer compliant.
2016345612(Syncml(500): The recipient encountered an unexpected condition which prevented it from fulfilling the request)
Luckily Microsoft their documentation is quite accurate about this behavior….yes, I said it out loud!!!
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.
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. (at least that’s what should happen!
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!
Nice one mate looking forward to the bitlocker error in your next blog!
Yep… me too 😛 but not sure if I could already share that blog (need confirmation :P)
That Chat gpt song hit me hard . Awesome Blog entry though!very informative .Thanks for sharing , Rudy! Cheers
Thanx for your kind reply!!!
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.
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!
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 🙂 …
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.