Last Updated on February 25, 2024 by rudyooms
This blog will be about a new Intune feature that is in development (Insider Preview canary for now). This wonderful magical feature is called “ConfigRefresh” AKA Config Refresh.
A small note: We don’t need to mix this new feature up with ConfigLock or the declarative stuff I have been talking about lately.
I am dividing this blog into multiple parts
- Enable Config Refresh
- Pausing Config Refresh
- Launching the Scheduled Refresh Task
- The Flow
- Providers Cache
Keeping an eye out for what’s new in Intune development is always a smart thing to do. This time something got my attention.
ConfigRefresh was added to the in-development and is now available for Windows Insiders! It mentions the fact that this feature will let you set a cadence (time frame) for Windows devices to reapply previously received policy settings, WITHOUT requiring devices to check-in to Intune. Does this Config Refresh sound like magic?
At first, I had the stupid idea that this feature was going to make use of the Windows Declared Configuration service because it looked and smelled like ConfigLock. ConfigLock seems to have performed the same kind of actions and could be the father of “ConfigRefresh” in my opinion.
But then again, the Declared Configurations already had their dedicated schedule to refresh any setting on the device (Declared Configuration Policies like EPM settings)
So what else does it use or abuse? I installed the latest Insider “canary” preview and started testing but after a couple of minutes I noticed that the Enterprisecsps.dll itself was only holding 1 function to create the node instance of the ConfigRefresh and nothing more
So trying to enable the ConfigRefresh or trying to perform a get on the node will fail with the error status 404
Luckily last weekend I noticed that my Insider Canary Preview Windows VM just got updated to the latest build (25941.1000)
I immediately copied the enterprisecsps.dll to my own device and opened it with IDA. YES!!!! All the functions and related nodes are mentioned in it!
So I guess Dano was right 🙂 … Just a couple of days later the required functions were included in the enterprisecsps.dll. Finally, I can start taking a look at the famous Config Refresh!
2. Enable Config Refresh
When looking at the DMClient CSP, we can also enable it with a CSP or a settings catalog as shown below. Just search for config refresh and make sure it’s enabled (not disabled)
But that wouldn’t be fun, right? Enabling it with a CSP and syncing the device with Intune will give me a lot of false information and a lot that is not related to ConfigRefresh. So I fired up a PowerShell MTA session in system context and fired off this SyncML message with the send-localmdmrequest command
This time no 404 error but a nice and expected 200 status. Please note that I needed to use “replace” and not “add”…
While trying to manually enable ConfigRefresh I was also already looking at the code so I knew where to start looking.
When you enable config refresh a new scheduled task named: “schedule created by DM client to refresh settings” will be created inside the Enterprisemgtmtnoncritical scheduled tasks folder. After clearing out the garbage I noticed the scheduled task being created
Besides this task being created the “ConfigRefresh” registry key in the corresponding enrollment will also be set. You will spot the ConfigRefresh registry key inside the Intune enrollment GUID
A funny thing to add here, when ConfigRefresh was first released this ConfigRefresh key was created in the DMClient key instead. Weird isn’t it??
Once the CSP enabled Config Refresh, I opened the scheduled tasks and started searching for that specific task. As shown below, there it is! A nice scheduled task. Inside a new folder called EnterpriseMgtmNonCritical, a new task was created. (The same folder as in which the queued task was created when we remotely sync our device from Intune)
When taking a closer look at that task, we will notice that it (OF COURSE!!) uses
fightclub the device enroller to trigger the /ConfigRefresh with some parameters. /o and the enrollmentguid that belongs to the Intune enrollment.
If we decide to take a closer look at the “triggers” we will notice that this scheduled task is repeated every 90 minutes
These 90 minutes correspond with the default cadence time from the DMClient CSP Docs
Of course, we can change them from 30-1440 minutes (but you could also just change the scheduled task?)
But of course, that’s not allowed, right? Don’t do that in production! So before we are going to take a closer look at what happens when the scheduled task to refresh it all, we need to take a good look at how we could pause ConfigRefresh when we want to test something
3. Let’s pause the Refresh
When we take a look at the DMClient CSP, I showed you earlier we can also pause the refresh for a while when we don’t want our policies to be refreshed. To do so we need to configure the PausePeriod CSP. Hopefully, the settings catalog will also contain this option in the future.
If we configured this CSP with an integer value of 1440, the scheduled task that was created in the enterprisemgtnoncritical scheduled task folder will be postponed for….. yes you guessed correctly! 1440 Minutes.
When we take a look at the Config Refresh registry keys, we will notice that the PausePeriod has been set.
After the pause period has ended and the schedule to refresh the policies has been run, the deviceenroller.exe would kick out that registry key as if it never existed!
We could also spot this on the fly when we are running Procmon
Looking at what’s new in Intune, we will spot that we will have the option to perform a remote action to pause the config refresh enforcement! That sounds way better than creating a CSP to pause the refresh for a while!
If we take a look at the Intune Custom Roles we could define, we will also notice, that we now have an option to disable the possibility to Pause Configuration Refresh remotely!
Now we know how we can enable it/configure it and how we pause it, let’s find out how it behaves when we launch the scheduled task to refresh the policies
4. Launching the scheduled refresh task
Before launching the scheduled task, just like first, I wanted to know what to monitor. I opened another IDA session and opened the deviceenroller.exe
As shown above, after searching for the ConfigRefresh part, I stumbled upon a function inside the main one. This function first uses the known issue rollback/KIR (if GetCachedFeatureEnabledState is mentioned, I know there is something brand new being added.. The fun thing is, you can just search for that keyword with IDA)
From there on it imports a function from the PolicyManager called “RefreshAll”.
We will notice this by looking at Procmon. First, it will load the policymanager.dll. So the real power behind ConfigRefesh lies in the RefreshAll function from the PolicyManager and not in the deviceenroller.exe!
Let’s open the policymanager.dll and just start searching for RefreshAll. When taking a look at the RefreshAll function below, I noticed some things
When the scheduled task is executed, it will try to find all the related policies that are set at the device and user level (GetActiveUserSid) in the Policymanager registry key
So by the looks of it, it only refreshes the policies configured in the PolicyManager\Current registry key…. So for example no Applocker Refresh! The deviceenroller.exe will look up all the providers and the corresponding ADMX settings and will “flag” them all as “dirty”!
After all the policies are flagged as dirty, it will start to search for all the “dirty” policies and will delete all of them!! Yeah ALL of them! I was also amazed but it will first get rid of all existing configured policies (values) even while there is nothing wrong with them.
I was expecting it would try to figure out if there is a mismatch between the configured and the applied policies. Still, by the looks of it, it just trashes all of the policies its values and will set them again within a couple of milliseconds!
So after removing the OneDrive in the software\policies registry key as shown below, I fired off the scheduled task to refresh all settings, and literally within a second or 2, the policies came back to life!
The funny thing is I also tried it with some security-related settings that are mentioned in the ConfigLock that I mentioned at the start of this blog post.
Guess what came back after clearing all of the Defender Security Center subkeys? Yeah you guessed correctly
So ConfigRefresh… Indeed taste like ConfigLock to me? Shall we take a look at the corresponding flow before diving a bit more into where the refreshed policies came from?
5. The Flow
In this flow I monitored the OneDrive KFMSilentOptin policy to determine the flow and what happens. Looking closely at the timeframe… within a couple of milliseconds, everything is refreshed!
- Queries policymanager\providers for all settings (cache with the last known good config policies?)
- Queries the policymanager\ADMXdefault and looks up all settings and in which registry key they are configured
- Flags the policies in the policymanager\current as dirty and detects if there are missing one
- Queries policies in the policymanager\providers for the lastwrite dword
- Refreshes (deletes/sets) the policy in the policymanager\current registry key (aka brings it back to life) and sets the ADMX instance data
- Refreshes (deletes/sets) the policy again in the software\policies registry node
6. Policy Cache
And now I guess everyone is thinking the same….. that’s a nice ProcMon flow… but I can’t do jack shit with it… can you explain it a bit better in human readable language and how ConfigRefresh knows what the policy looked like before it was deleted?? Well let’s try again
As shown above, all of the policies and their settings also exist in policymanager\providers.. the moment ConfigRefresh kicks off, it will check this specific registry node and all of its subkeys. Good to know is, that when you mess around with (aka delete) the policy that lives in the policymanager\providers registry key, it won’t refresh the software\policies that may have been deleted.
It’s just refreshing! I love it! This refresh task isn’t exactly using a desired state config but it does the same thing. It will make sure that the policies are refreshed on the device without contacting Intune!
A small side note: It looks like only policies that live in the PolicyManager and the corresponding PolicyCSP settings are refreshed