Recursively set permissions on folders using Powershell?
Asked Answered
S

1

9

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).

Shanitashank answered 23/1, 2018 at 20:37 Comment(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.Marasco
M
8

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.

Marasco answered 23/1, 2018 at 20:55 Comment(9)
Hi, I am a bit confused on where I should put $acl.SetAccessRuleProtection. I get the $acl in the loop, but you said to only apply it to the topmost folder.Shanitashank
Do not recurse at all. Let inheritance take care of permission propagation.Marasco
So by setting permissions on the root folder, it will automatically set permissions on all sub folders (even sub/sub... folders)?Shanitashank
It should unless someone already tampered with the inheritance settings there. Should that be the case use icacls for resetting the permissions in the folder subtree (icacls "C:\perms" /reset /t /c), then re-apply your permission changes to c:\perms.Marasco
Ok I got the permissions to be removed, I updated my post about adding multiple ace'sShanitashank
I also noticed that when I add the user, it checks Special Permissions and not the other ones (Full Control, Modify....)Shanitashank
Ok changing the InheritanceFlags property to "None" fixed that issue with Special PermissionsShanitashank
@Shanitashank For information about the effect of inheritance and propagation flags see here.Marasco
Good answer but it only works when you are allowed to read the acls. If you have special folders where even administrators have no permission (e.g. Roaming User Profil Folders) then this solution does not work.Denizen

© 2022 - 2024 — McMap. All rights reserved.