Microsoft Intune

When does a Windows client sync with Intune?

It seems like a simple question, but a complete answer isn’t necessarily simple. We can start off with the documentation:

OK, so about every 8 hours. But it’s different right after you enroll, with the theory being that it might take a little more activity to get the device set up initially. The docs describe the behavior:

So with Windows 10/11, which is what I care about here, it’s going to be every 3 minutes for 15 minutes (5x times), then every 15 minutes for two hours (8x times), then every 8 hours for eternity. But what determines that? If you’ve seen one of my presentations on the inner workings of MDM, you’ve probably seen this in the initial WAP payload that is sent back by the MDM service (e.g. Intune):

So that “Poll” section is specifying the values, and those are documented in the DMClient CSP documentation. (We’ll come back to that one again later.) So Windows can poll at whatever frequency the service wants; the MDM service is what is specifying the frequency as part of this enrollment payload.

But is that all there is to it? If you’re using the Autopilot enrollment status page (ESP), it can do it more frequently, because we noticed a problem with that initial polling: It could take more than 15 minutes for everything to be sent to the device, and in that situation, things would really slow down with the device doing absolutely nothing while ESP monitors for changes that won’t happen until the next poll occurs. So logic was added to ESP to poll more frequently, to keep moving things along. What does this end up looking like? Well, I deployed a Windows 11 device yesterday that was Autopilot-enrolled with device ESP enabled; we can see each sync session start in the DeviceManagement-Enterprise-Diagnostics Admin event log by looking for event ID 208. Here’s the series from the device (oldest at the bottom, newest at the top):

There’s a flurry of activity from 4:42:55 to 5:15:01 (yes, the deployment took a while because I was installing updates from a Win32 app) — this is an intermingled set of syncs, some being performed by Windows automatically and others being initiated by ESP. After 5:15, then the “normal” cycle kicks in with syncs every 15 minutes, with the every-eight-hour cycle starting at 7am. But there’s one extra sync at 6:13:20. What caused that? Simple, I logged into Windows using my Azure AD/Entra ID credentials, and that logon caused a sync session.

That sounds somewhat logical: when logging into Windows, it initiates a sync to try to find any new user-targeted policies. What causes that to happen? That’s also configured via a DMClient CSP setting, PollOnLogin. That tells Windows every login should initiate a sync. Those DMClient settings are saved in the registry (HKLM\Software\Microsoft\Enrollments\<enrollment GUID>\Poll) so we can peek at them after the fact:

After that logon sync, when will the next sync occur? With the next scheduled sync (every 8 hours if we’re beyond the initial faster syncs, with that schedule unaffected by the logon), and it will pick up any new settings for the device or user.

You might wonder how those syncs are being initiated, since there’s no “MDM client” service or anything like that. You might periodically see an “OMADMClient.exe” process running on your machine though. How is that started? Task Scheduler to the rescue:

So we can see four items tied to the policies we’ve been looking at:

  • “Login Schedule created by enrollment client.” This runs at logon for any user.
  • “Schedule #1 created by enrollment client.” This is scheduled at enrollment to repeat every 3 minutes for 15 minutes.
  • “Schedule #2 created by enrollment client.” This is starts when the other one finishes, repeating every 15 minutes for 2 hours.
  • “Schedule #2 created by enrollment client.” This is starts when the previous one finishes, repeating every 8 hours indefinitely.

While we’re here, there are a couple of additional interesting scheduled tasks:

  • “Schedule to run OMADMClient by client.” This runs when you click “sync now” in the Settings app. I did a blog related to this one a while back that showed how to trigger the “PushLaunch” scheduled task, which then triggered this one, but that route doesn’t seem to work anymore (more on that below).
  • “Schedule to run OMADMClient by server.” This one is triggered when a Windows Notification Services (WNS) notification is received by the device. Intune can send these at any time to say “wake up and check for new stuff.” Years back, it would only do this for a small number of clients any time you created or modified a policy (e.g. create a new configuration profile); there were some changes underway to try to do this more in bulk (e.g. drop all the devices to be notified into a queue and then do a “best effort” to notify all of them, with a somewhat short “time to live” before throwing away the queued requests — no use in creating a backlog that can never be satisfied), but I don’t know the status of enabling this for customers. (Anyone know if this is being done now?)

There are also a few other random ones that trigger syncs on various events (changing the OS SKU, turning off S Mode, configuring Windows Hello for Business, etc.), but those are more “special purpose” and don’t fire often (if at all).

So are there any more complications worth mentioning? Of course. When a device first enrolls, Intune expects a shorter sync interval, but after things have settled down it will throttle requests that come in too frequently. (There is an alert sent with those initial sync sessions that Intune can see indicating that these are bootstrap sessions, so it can treat those differently.) How frequently is “too frequently”? The exact time isn’t documented anywhere I can find, but it used to be three minutes — if you try another sync before then, it can fail.

Apparently they’ve also blocked the ability to trigger a sync by triggering the PushLaunch scheduled task manually. If you try it, it always fails with this error:

I don’t see any documentation around this 0x82ac0204 error (although there are other references to it, e.g. Rudy’s blog here), but I suspect it’s being done purposely by the Intune service to block this. Interestingly, the “Sync” button in the Settings app (Accounts > Access work or school > Managed by Contoso MN) always seems to work, as does the “Sync” button in the Company Portal app, without any throttling, and I can see that it (eventually) runs the “Schedule to run OMADMClient by client” scheduled task itself, but starting it via a different means. But if you try to trigger that scheduled task manually, it fails:

It’s not obvious if that’s intentional or not, but if I had to guess I would say that it probably is. I didn’t try it with older Windows 10 builds, but it did work in 2019 and it doesn’t work now, so it’s a reasonable assumption that they’ve tightened things up to prevent people from doing this sort of thing.

If you’ve tried out the SyncML Viewer app from Oliver Kieselbach, you might notice that the “MDM Sync” button in that does work fine, so it can be done with a little WinRT trickery, a three-line PowerShell script that you can run in PowerShell 5.1:

[Windows.Management.MdmSessionManager,Windows.Management,ContentType=WindowsRuntime]
$session = [Windows.Management.MdmSessionManager]::TryCreateSession()
$session.StartAsync()

Thanks to Oliver for that one. (Calling WinRT functions via PowerShell 5.1 is a good topic for a future blog post.)

Anything else? Yes, the Intune Management Extension service, used to install Win32 apps, run PowerShell scripts, and a variety of other things, runs on its own schedule, once an hour. There’s no provided way to initiate a sync prior to that, unless you want to stop and restart the Intune Management Extension service since it will poll when it starts up.

It used to be possible to change the polling interval by sending custom OMA-URI policies to the device, which would result in the scheduled tasks being recreated with the values that you specified. So if you wanted to poll every 5 minutes, you could — at least until Microsoft noticed and yelled at you (and they probably would). At this point, it looks like they’ve shut that path down: if you create an OMA-URI policy that tries to change the values, it appears that Intune just eats them and reports an error without ever sending them to the client. I suspect someone did that at some point, hence this not-so-subtle message:

What if you changed the scheduled tasks manually? It might work for a while, but it wouldn’t surprise me if a config refresh or something similar just puts it back again — Microsoft really doesn’t want you to overwhelm their Intune servers.

If the sync process wasn’t sending so much data back and forth, it might not be as bad to run this more often. But if you’ve ever watched the sync process using SyncML Viewer or something similar, you’ll see that there’s a lot of relatively static information being sent repeatedly from the client to the server (because the server asked for it). Examples include:

  • A full list of the CSPs supported by Windows and their versions. There are nearly 200 of these, so probably 10KB of stuff there.
  • The Autopilot hardware hash. That’s another 4KB.
  • Information on every UWP app installed on the device. That’s quite a lengthy list, and with all the XML that wrapped around it, it’s quite a sizable payload.
  • Repeated requests to install any MSI or UWP apps that have been targeted to the device (just in case they’ve been removed or failed the last time we synced?).

Every single sync session. (There was one piece of information that did seem reasonable: the free space on the C: drive.) Ah well, I guess that’s what you get with a protocol that was designed for Windows Phone…

9 replies »

  1. thanks for the detailed one.. I would like to know how do we validate what is the last sync time of the machine from the machine itself.. is it available in registry or eventlog or some other log file

    Like

    • This blog post shows how to check that information from the event log. You can also find it in the registry at HKLM\Software\Microsoft\Provisioning\OMADM\Accounts\\Protected\ConnInfo in the values “ServerLastAccessTime” (attempted/started) and “ServerLastSuccessTime” (sync completed successfully).

      Liked by 1 person

      • Hi Michael – I was looking a long time for an article like yours. Thank you !!How can I determine the ID that is between “Accounts” and “Protected” so that I can read the values using a powershell script?For example on my computer: HKLMSOFTWAREMicrosoftProvisioningOMADMAccounts9A01455E-XXXX-XXXX-9866-B2CCB06C0BF3ProtectedConnInfo

        Like

  2. Just found out a reference of the error thrown by the Intune service if you sync more often than 3mins window – OMADM_E_MSG_QUEUED in dmerrors.h library. So what I think is that the sync is queued and most probably never treated. Worth to check if after those 3 mins pass since the last sync, there will be a successful sync event written in the DM-Enterprise-Diagnostic-Provider ; Kind regards, Vasile

    Like