6
votes

I have a directory which I want to go through recursively and set permissions on all the folders. So the order of operations should be:

  1. Remove all ACL from folder
  2. Add ACL to folder
  3. Set ACL

I tried the below code, but I am getting the error

Cannot set the ACL because the method that it needs to invoke, SetSecurityDescriptor, does not exist.

foreach ($folder in Get-ChildItem -Path c:\perms -Recurse -Directory) {
    $AccessRule = New-Object System.Security.Accesscontrol.FileSystemAccessRule ("user", "FullControl", "ContainerInherit,ObjectInherit", "InheritOnly", "Allow")
    $acl = Get-Acl $folder
    $acl.SetAcccessRule($AccessRule)
    Set-Acl -Path $folder.FullName -AclObject $acl
}

I got rid of the error message, and it added the ACL, but I want to basically remove all ACLs from the folder and add new ones.

I updated my script to look like this:

$acl = Get-Acl -Path "c:\perms"
$acl.SetAccessRuleProtection($true,$false)
$acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) | Out-Null }
$ace = New-Object System.Security.Accesscontrol.FileSystemAccessRule ("user", "FullControl", "ContainerInherit,ObjectInherit", "InheritOnly", "Allow")
$acl.AddAccessRule($ace)
Set-Acl -Path "c:\perms" -AclObject $acl

If I want to add multiple $ace, is it just a matter of declaring $ace2, $ace3 and then calling $acl.AddAccessRule($ace2), $acl.AddAccessRule($ace3).

1
If I want to add multiple $ace, is it just a matter of ... Please test simple stuff like that yourself before posting. Adding this update to your question probably took you longer than it would have taken to verify it by running a quick test. I'm not going to spoon-feed you a solution.Ansgar Wiechers

1 Answers

5
votes

Use SetAccessRuleProtection() to disable inheritance and remove inherited ACEs:

$acl.SetAccessRuleProtection($true, $false)

Use RemoveAccessRule() to remove existing (non-inherited) ACEs:

$acl.Access | ForEach-Object { $acl.RemoveAccessRule($_) | Out-Null }

Use AddAccessRule() to add new ACEs:

$ace = New-Object Security.AccessControl.FileSystemAccessRule "user", ...
$acl.AddAccessRule($ace)
...

Do this only for the topmost folder. Leave inheritance enabled everywhere below, so your changes are propagated automatically.