How to Change Registry Permissions with PowerShell

How to Change Registry Permissions with PowerShell

The Windows registry can be a goldmine for attackers and clueless employees. There’s no place better suited for introducing security vulnerabilities or completely screwing up a Windows system than the registry.

To control permissions to registry keys for security and troubleshooting purposes, you can use a few different methods. In this article, you’ll learn PowerShell. Using a couple of PowerShell cmdlets and a little .NET magic, you can read and manipulate registry permissions at your discretion.


What is a Registry Permission?

For this article, a registry permission is a set of access control entries (ACEs) that make up an access control list (ACL). These ACLs then apply to a registry key.

ACLs are a common term amongst many entities in IT, and ACLs assigned to registry keys are no different. The ACL defines what and how an account can access that registry key.

A registry permission (ACL) defines what account can access a particular registry key and what kind of permissions that account has.

Finding Existing Registry Key Permissions

Start out by looking for a registry key you’d like to change permissions on. I’ll randomly pick one with the path of *HKCU:. You can pick any key you’d like to try this out.

Before you change anything, it’s a good idea to see what the current ACL is and to make a backup if things go awry. PowerShell provides a cmdlet called Get-Acl that will do just that.

PS> $acl = Get-Acl 'HKCU:\AppEvents\EventLabels\ActivatingDocument'
PS> $acl.Access

RegistryRights    : ReadKey
AccessControlType : Allow
IsInherited       : False
InheritanceFlags  : ContainerInherit
PropagationFlags  : None

Now that you have the existing ACL captured, you can change it. If you’re concerned, you could even save the ACL to the file system using the Export-CliXml cmdlet, but that’s for another day.

You can see an example of using the Export-CliXml cmdlet to save objects to disk here.

Creating an ACL with PowerShell

In the above section, you captured an ACL with Get-Acl. Since you’re using the registry, this particular ACL captured only works with the registry. To update the ACL, you’ll need to add a rule (ACE) to the ACL that’s meant for the registry.

When defining permissions for the Windows registry with PowerShell, you’ll need to create a System.Security.AccessControl.RegistryAccessRule object. This object allows you to define criteria like the principal (user, group, etc.) that this ACE applies to, level of access, and if you’re going to allow or deny that access.

Defining the Right

The first step is to assign the appropriate rights to the registry key. There are 14 different rights to choose from. Check out the table in this Microsoft doc to discover the right you’re looking for.

You can discover all possible rights by typing [System.Security.AccessControl.RegistryRights]:: and hitting the tab key. PowerShell will cycle through all available rights.

Creating the RegistryAccessRule Object

Once you have the correct right name, you’ll then need to create the RegistryAccessRule object. This object has three arguments you’ll need to pass to it:

  • An identity (a Windows account)
  • The right (has multiple different objects to create this)
  • Allow or Deny that right

First, create the identity by creating an System.Security.Principal.NTAccount object passing in the identity reference as shown below.

$idRef = [System.Security.Principal.NTAccount]("HOSTNAME\username")

Next, create a System.Security.AccessControl.RegistryRights object using one of the rights in the table above.

$regRights = [System.Security.AccessControl.RegistryRights]::FullControl

Now define the inheritance and propagation flags. Here you can choose between None, ContainerInherit, or ObjectInherit. You can find more information about these options here.

The following snippet’s inheritance setting is set to None, meaning it will not inherit any permissions from its parent registry key.

$inhFlags = [System.Security.AccessControl.InheritanceFlags]::None
$prFlags = [System.Security.AccessControl.PropagationFlags]::None

Once you’ve set the inheritance and propagation flags, then set the access control type enum.

$acType = [System.Security.AccessControl.AccessControlType]::Allow

Finally, create the RegistryAccessRule object using all of the objects you’ve just collected.

$rule = New-Object System.Security.AccessControl.RegistryAccessRule ($idRef, $regRights, $inhFlags, $prFlags, $acType)

You now have a RegistryAccessRule defined in the $rule variable. You’ll need this in the next section.

Adding the ACL

The next step is adding the RegistryAccessRule you created in the previous section to the current ACL using the AddAccessRule() method on the ACL object you grabbed earlier.

PS> $acl.AddAccessRule($rule)

Overwriting an Existing ACL

Alternatively, you could also completely overwrite the existing ACL by using the SetAccessRule() method.

PS> $acl.SetAccessRule($rule)

Assigning the ACL

But you’re not done yet! You haven’t actually committed the new ACL to the registry key. To apply the new ACL to the registry key, use the Set-Acl command. To use the Set-Acl command, pass the saved ACL in $acl directly to Set-Acl while pointing to the key you’d like to apply it to.

You want to set the ACL on the same key that you gathered the original ACL from. Pass that key path to the Path parameter of Set-Acl to apply it.

$acl | Set-Acl -Path 'HKCU:\AppEvents\EventLabels\ActivatingDocument'

The ACL with the added registry access rule has been applied to the original registry key. You can now verify the change was made by again calling Get-Acl and ensuring that the IdentityReferenceRegistryRights, and AccessControlType properties are as you expect.

PS> (Get-Acl 'HKCU:\AppEvents\EventLabels\ActivatingDocument').Access

RegistryRights    : FullControl
AccessControlType : Allow
IdentityReference : <hostname>\Administrator
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None


In this blog post, you learned how to capture, change, and commit ACEs to registry key ACLs. You used the Get-Acl PowerShell cmdlet to find existing ACLs and the Set-Acl cmdlet to change them. Using these two cmdlets is just about all you need to work with registry permissions in PowerShell.


Related Posts

Comments are disabled in preview mode.
Loading animation