technology from back to front

Programmatically updating local policy in Windows

“Group Policy is a feature of the Microsoft Windows NT family of operating systems that control the working environment of user accounts and computer accounts. Group Policy provides the centralized management and configuration of operating systems, applications, and users’ settings in an Active Directory environment…Local Group Policy (LGP) is a more basic version of the Group Policy used by Active Directory.” – Wikipedia

There are various settings in Windows that come under the remit of the group policy. Even for computers that do not belong to an Active Directory domain there are settings that can only be changed via the local group policy.

The graphical editor, gpedit.msc, is pretty easy to use. But what to do when we need to script policy changes?

There is the Group Policy Management Console Class Library, a .NET library, and also a set of Powershell cmdlets based on top of it. However there are frustrating problems with these.

Firstly, they only come packaged with Remote Server Administration Tools, which is a large Windows update. My use case is aimed at targeting policy settings on newly created machines – I don’t want to have to install an 100MB update and then install Windows features – I just want to update a file.

Secondly, and more damningly, this library, coming as it does in the Remote Server Administration Tools, is aimed at managing Active Directory based group policy. It can’t actually modify the local policy – at least so far as I can tell. Documentation is thin on the ground.

Instead, we need to take the following approach.

Firstly, discover which registry keys are changed when you make the change you are interested in using the GUI. Launch gpedit.msc. Additionally, launch ProcessMonitor with these filters active:

  • Process Name is mmc.exe
  • Operation is RegCreateKey
  • Operation is RegDeleteKey
  • Operation is RegSetValue
  • Operation is RegDeleteValue

Secondly, make the changes you want through the GUI, and take note of which registry keys have been changed.

However, you can’t just then apply those same registry changes directly and expect things to work. The group policy doesn’t actually use the registry to store its settings. Rather, it seems to temporarily write them there, and then compile them down to a binary .pol file that lives in C:\Windows\System32\GroupPolicy\. We need to trigger this same process.

There exists a Win32 API for making these changes, that I discovered through this blog post, which I am indebted to. Using some hints from this other blog post, I have created a .NET library that allows managed access to this API.

Here is a code sample of using to change one of the RDP settings (my original use case!):

var gpo = new ComputerGroupPolicyObject();
const string keyPath = @"SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services";
using (var machine = gpo.GetRootRegistryKey(GroupPolicySection.Machine))
    using (var terminalServicesKey = machine.CreateSubKey(keyPath))
        terminalServicesKey.SetValue("SecurityLayer", 00000000, RegistryValueKind.DWord);

You can get the source or compiled assembly from BitBucket. Please note that this code is not thoroughly tested – I have yet to figure out how to write meaningful unit tests against a library that is so bound up in the OS – watch this space. If and when you find bugs, please raise issues over on BitBucket.

Martin Eden
  1. Joshua M. Murphy
    on 02/04/13 at 9:15 pm

    This is something I’ve been looking for off and on for the past 5 or more years. I was about to resort to writing a tool solely to parse and modify registry.pol directly… but I’ll definitely be giving this a try. I have a few hundred systems with differing local policies that need a few added things set, and I believe you just saved me a lot of hours!

  2. Martin Eden
    on 22/04/13 at 2:27 pm

    Glad to be of assistance. :)

  3. Hi, I’m not a coder at all but wondered if you could give me some guidance. This would be very handy but how would I make use of it?


  4. Martin Eden
    on 12/02/14 at 9:57 am

    This is just a code library. It won’t be of any help to you unless you know how to code in .NET. Sorry – I think the topic of how you could make use of this is too large to address in a blog comment – it involves learning how to write programs.

  5. Understood thanks anyway!


five × 9 =

2000-14 LShift Ltd, 1st Floor, Hoxton Point, 6 Rufus Street, London, N1 6PE, UK+44 (0)20 7729 7060   Contact us