How many of you remember that, long before GP Preferences was acquired by Microsoft, they used to refer to any Administrative Template settings that did not set values in the 4 magic registry keys as…wait for it…preferences?
That’s right, there were “preferences” long before there were Preferences. One of those things that I wrote about was the registry policy “archive file”, and its role in allowing Group Policy to not “tattoo” the registry (i.e., leave the value stuck in the registry) when an Admin Template setting was removed. So, let’s review how this magic actually works.
The Four Magic Keys
Remember that for the non-tattooing behavior to work, a policy setting must store its value in one of the 4 magic registry keys (2 are per computer and 2 are per user) as shown here:
HKEY_LOCAL_MACHINE\Software\Policies
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies
HKEY_CURRENT_USER\Software\Policies
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies
You’ll notice an interesting thing about these 4 keys. The permissions on them are such that only privileged users (in this case, members of the local Administrators group and LocalSystem–the machine account) can write to them. Everyone else has read access only. This design allows Group Policy to reliably enforce settings, particularly for user configurations that should not be altered by end users. As a result, even though a user typically has full control over most of their HKEY_CURRENT_USER hive, they are generally unable to modify the two per-user policy keys.
An interesting, relatively recent development I’ve noticed is that Intune-joined machines seem to also grant your Entra user write permissions on these keys. So, while normal AD users can’t write to the per-user policy keys, Entra users logging into Intune-joined machines seemingly can! I’m frankly not sure why Microsoft did that, but perhaps it relates to how Intune interacts with these keys.
Seeking more tips on managing your Windows configurations?
The Archive File
The role of the registry archive file is straightforward. When Group Policy is processed, such as when you run gpupdate or when a user signs in, the GP engine checks the archive file to see which registry settings were previously applied to the user or computer. It starts by removing those existing values, then almost immediately reapplies any settings from the GPOs that currently apply.
For example, suppose the following registry entries have been applied to a user’s HKCU hive:
Software\Microsoft\Windows\CurrentVersion\Policies\System,HideLogoffScripts,REG_DWORD,"00000000" Software\Microsoft\Windows\CurrentVersion\Policies\Explorer,ForceStartMenuLogOff,REG_DWORD,"00000001" Software\Microsoft\Windows\CurrentVersion\Policies\Explorer,LockTaskbar,REG_DWORD,"00000001" Software\Microsoft\Windows\CurrentVersion\Policies\System,DisableTaskMgr,REG_DWORD,"00000001" Software\Policies\Microsoft\Windows\CurrentVersion\QuietHours,Enable,REG_DWORD,"00000000"
On the next policy refresh, these five values are removed from the registry based on what is recorded in the archive file. The system then determines which GPOs currently apply to the user and reapplies the appropriate registry settings. Those newly applied settings are written back into the archive file.
For example, if the GPO that sets the DisableTaskMgr value is unlinked from the user’s OU, that setting will be removed during the next policy refresh through the archive file process. Because the GPO is no longer in scope, the value is not reapplied. This is how Group Policy achieves non‑tattooing behavior in the registry. You can observe this process in action by enabling GPSVC logging on a system, as shown here:
Differences Between Computer and User Archive Files
As you can see from the screenshot above, the values are first deleted (DeleteRegistryValue call), then the applied GPO’s registry.pol file is read (in this case, there’s only one GPO applying to the user), and the SetRegistryValue commands apply the current policy to the user’s profile.
So where is this magical archive file? Well, it so happens that there are two instances of the file, one for the computer and one for the user, and both share the same filename: ntuser.pol. The file is marked with System and Hidden attributes so it will not appear in a standard directory listing.
The per-computer file is stored in %systemdrive%\ProgramData and maps to HKLM registry values. Write access is restricted to members of the local Administrators group and the LocalSystem account. The per-user file is stored in the user’s profile root (e.g., C:\Users\Darren) and is writable by the user themselves. It’s also important to note that the ntuser.pol file uses the same policy file format that is used by registry.pol files found in SYSVOL within GPOs. This format is documented by Microsoft.
Keep in mind that only registry values applied via a GPO will make their way into the registry archive file, ntuser.pol. This means that if you deliver a registry value to one of the 4 magic policy keys by some means outside of a GPO (e.g. via script or other configuration mechanism), that value will not find its way into the archive file and therefore will not get “cleaned up” during each policy refresh (note that Intune has its own, different mechanism for handling registry tattooing). What this means is that settings delivered that way essentially tattoo the system in a way that GP does not.
Finally, remember my discussion of “old-style” preferences (i.e. settings that don’t write to one of the 4 policy keys)–these settings will get written to ntuser.pol, but they will not be removed during a refresh cycle. They also essentially tattoo the registry, which is interesting.
Abusing the Archive File
There are a couple of ways the registry archive file can be misused, although their practical impact is more limited in modern environments. One scenario involves the per-user ntuser.pol file, which is stored in the user’s profile and typically writable by that user. Because Group Policy removes all values listed in this file before reapplying current settings, a user can add entries that cause certain registry values to be deleted during policy processing.
This becomes relevant when registry-based settings are applied outside of Group Policy, such as through logon scripts or manual configuration. Since those settings are not tracked by Group Policy, adding them to ntuser.pol can result in their removal without being reapplied.
A second, less practical scenario involves holding an open handle on the archive file, which can interfere with policy processing. While this can disrupt how registry settings are reapplied, modern versions of Windows are more resilient to this kind of behavior, making it more of an edge case than a realistic concern. A while back ago, I wrote a utility, which is still very popular among sysadmins, called Registry Policy Viewer:
Registry.Pol Viewer presents the contents of any .pol file. One side effect of this utility, is that it creates an open file handle on the pol file that’s under scrutiny. This means that the pol file, while open, cannot be deleted or moved by another process on the box—say, GP Processing itself. As a normal user, if I fire up this tool and open up ntuser.pol for either the computer (c:\programdata) or user (within the user’s profile), it has the effect of breaking policy processing in an interesting way. Namely, the archive file is read and registry entries are removed for the user or computer, but then the new archive file can’t be re-built, and as such, policy application of the new policy settings can’t proceed. You can see this in effect in the GPSvc.log file here:
The result of this failure is that the new registry values are not re-written to the machine. In effect, a non-privileged user simply opening the archive file for read has prevented registry Group Policy from processing on either the computer or user side (depending upon which archive file they open). This means the machine is essentially unprotected during this time, without the user having any privileged access to do so.
Change Manager for Group Policy/Intune catches policy tampering in real time, including the changes directly in SYSVOL
Ready to see it in action?
Summary
Much of the original concern around these abuse patterns is less relevant today due to changes introduced with MS16-072 and the evolution of Group Policy processing. Modern systems handle policy application primarily in the machine context, reducing the need for direct user access to policy files. As a result, tightening permissions on Group Policy-related files is now a more viable mitigation than it once seemed. Because these risks haven’t been completely eliminated, one should still focus on enforcing least-privilege access to SYSVOL and policy assets, monitor for unauthorized changes, and rely on updated security baselines rather than assuming these attack paths are unavoidable.



