Just about every object in Windows can set who and what can access it. The registry is no different. Since PowerShell ties into the .NET Framework, you can change these restrictions with a script. In this post, you're going to learn how to change registry permissions with PowerShell using the Get-Acl and Set-Acl cmdlets.

Changing registry permissions with PowerShell �is a four-step process.

  1. Capture the initial ACL.
  2. Create a RegistryAccessRule object representing permission
  3. Adding or overwriting the new rule to the existing ACL
  4. Committing the ACL back to the registry key

Let's find out how to follow these four steps!

But first...

What is a Registry Permission?

I'm calling a registry permission 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:\AppEvents\EventLabels\ActivatingDocument. 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
IdentityReference : APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES
IsInherited       : False
InheritanceFlags  : ContainerInherit
PropagationFlags  : None
--snip--

Now that you have the existing ACL captured, you can now 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

Since you're using the registry, this particular ACL we have captured only works with the registry. You'll need to add a rule (ACE) to the ACL that's meant for the registry. There are many different options when creating an ACL.

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.

Assigning Rights

You'll need to figure out what kinds of rights to grant to the registry key. Those rights are below. Table found here.

NameBit ValueDescriptionChangePermissions262144The right to change the access rules and audit rules associated with a registry key.CreateSubKey4The right to create subkeys of a registry keyDelete65536The right to delete a registry key.EnumerateSubKeys8The right to list the subkeys of a registry key.FullControl983103The right to exert full control over a registry key, and to modify its access rules and audit rules.Notify16The right to request notification of changes on a registry key.QueryValues1The right to query the name/value pairs in a registry key.ReadKey131097The right to query the name/value pairs in a registry key, to request notification of changes, to enumerate its subkeys, and to read its access rules and audit rules.ReadPermissions131072The right to open and copy the access rules and audit rules for a registry key.SetValue2The right to create, delete, or set name/value pairs in a registry key.TakeOwnership524288The right to change the owner of a registry key.WriteKey131078The right to create, delete, and set the name/value pairs in a registry key, to create or delete subkeys, to request notification of changes, to enumerate its subkeys, and to read its access rules and audit rules.

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.

For a list of all available rights, type [System.Security.AccessControl.RegistryRights]:: and start hitting the tab key. It will cycle through all available rights. The same can be done for any objects that you create with ::.
$regRights = [System.Security.AccessControl.RegistryRights]::FullControl

Next, define the inheritance. Here you can choose between:

  • None
  • ContainerInherit
  • ObjectInherit

You can find more information about these options here.

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

Next is the propagation flags.

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

Then the access control type enum.

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

Finally, you can 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)

Now that you have the RegistryAccessRule created, now you'll need to either overwrite the original ACL you grabbed or add another one.

Adding the ACL

If you'd like to add the ACL to the registry key, you can use the AddAccessRule() method on the ACL object you grabbed earlier with the Get-ACL command.

PS> $acl.AddAccessRule($rule)

Overwriting an Existing ACL

You could also overwrite the existing ACL on the registry by using SetAccessRule().

PS> $acl.SetAccessRule($rule)

Assigning an ACL to a Registry Key

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 IdentityReference, RegistryRights, 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

Summary

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.

For more posts on working with the registry, check out How to Get Registry Values With PowerShell.

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!