Working with ACL’s in PowerShell

I recently had the need to make some permission changes to a folder and decided to take the time to figure out how to do it with PowerShell without using Cacls. The sources I used will be at the bottom of this post.

The first thing you need is a folder. For this we’ll use a folder called “Test” on C:, so “C:Test”. You then need to use Get-Acl to aquire the security descriptor for the folder.

$acl = Get-Acl “C:Test”

At this point you can call the $acl variable and you’ll get back a table that specifies the Path, Owner, and Access for the folder “Test”. To get a more friendly view of the Access column, call $acl.Access. You’ll then get a nice breakdown of each rule.

Now that we have information on the folder we can start making changes. The first thing I’ll cover is working with configuring inheritable permissions. For this we’ll use the ‘ObjectSecurity.SetAccessRuleProtection’ method. There are two parameters to this method, ‘isProtected’ and ‘preserveInheritance’. ‘isProtected’ is what determines if a folder inherits permissions. A value of true will break inheritance, while a value of false will allow inheritance. ‘preserveInheritance’ is only used if ‘isProtected’ equals true. When ‘isProtected’ equals false, the parameter ‘preserveInheritance’ still needs to be set, however it will be ignored. If you’re breaking inheritance on the folder, this parameter determines if the existing permissions are retained or removed. A value of true will preserve the existing access rules, while a value of false will remove existing access rules. An example of using this method to allow inheritance is below.

$acl.SetAccessRuleProtection($false,$false)

Here’s an example of using the method to remove inheritance but copy existing access rules.

$acl.SetAccessRuleProtection($true,$true)

And here’s an example of using the method to remove inheritance and also remove existing access rules.

$acl.SetAccessRuleProtection($true,$false)

Now onto configuring access rules. Let’s assuming that for this folder we’ve gone with leaving inheritance in place. By default we have the following existing access rules.

FileSystemRights  : ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : BUILTINUsers
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITYSYSTEM
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTINAdministrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : BUILTINUsers
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

Lets say we want to change the access rules so that the built in Users group has modify access to the folder. The first thing we need to do is create a variable that will store the new access rule. For this we’re going to use the ‘FileSystemAccessRule’ class. This class has 7 properties, however we’re only going to need to use 5 to give the Users group modify access. The properties we’ll use are:

  • IdentityReference: The identity that the access rule will apply to. In this case, it will be “Users”.
  • FileSystemRights: The access being given. In this case it will be “Modify”.
  • InheritanceFlags: Determines how this rule is inherited by child objects (folders and files). In this case it will be “ContainerInherit, ObjectInherit” (Container meaning folder, Object meaning file).
  • PropagationFlags: Determines how inheritance of this rule is propagated to child objects. In this case it will be “None”.
  • AccessControlType: Specifies whether a access rule is used to allow or deny access. In this case it will be “Allow”.

Putting this all together you’ll get this:

$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(“Users”,”Modify”,”ContainerInherit, ObjectInherit”,”None”,”Allow”)

You then need to add the rule to the $acl variable we already created by doing this:

$acl.AddAccessRule($rule)

That’s all there is to creating new access rules and applying them to the $acl variable, however that’s not all you have to do to apply the access rule and the inheritance settings to the folder. I”ll get to the step that applies the changes right after we go over making changes to the ownership.

When working with ownership you have to use the ‘ObjectSecurity.SetOwner’ method.  To set the owner to the local Administrators group, we would run:

$acl.SetOwner([System.Security.Principal.NTAccount] “Administrators”)

In the end, once you’ve finished with making your modifications, you need to apply your changes to the folder. To do this we use the ‘Set-Acl’ cmdlet like so:

Set-Acl “C:Test” $acl

After you do that, you can relist your access rules and you’ll see that the Users group now has modify access in addition to the existing inherited rules. Just to point it out, you’ll notice that the access rule for granting the modify access will have the ‘IsInherited’ flag set to False.

FileSystemRights  : Modify, Synchronize
AccessControlType : Allow
IdentityReference : BUILTINUsers
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITYSYSTEM
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTINAdministrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : BUILTINUsers
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

And that’s all there is to it.

My sources for figuring this all out are below:

Blog post from Jose Barreto on TechNet that pointed me in the right direction (while this article does describe how to do the above as well, I feel my post is much more clear and to the point of how to do this)

MSDN article on the FileSystemAccessRule class

MSDN article on the SetAccessRuleProtection Method