PowerShell Setting advanced NTFS permissions PowerShell Setting advanced NTFS permissions powershell powershell

PowerShell Setting advanced NTFS permissions


Object access permissions in Windows are controlled via Access Control Lists (ACL), which basically consist of a list of Access Control Entries (ACE). Each ACE is a set of attributes that controls whether access is granted or denied, who the ACE applies to, if the ACE was inherited from a parent object, and whether it should be inherited by child objects.

If you take a look at the documentation of the FileSystemAccessRule class, you'll see that the "full" constructor takes 5 parameters:

  • IdentityReference/String: An object or string that identifies the trustee (user, group, computer, ...) to whom the ACE applies.
  • FileSystemRights: The actual permissions to be granted or denied.
  • InheritanceFlags: Flags to control which object types inherit permissions from this object (containers, leaf objects, or none).
  • PropagationFlags: Flags to control propagation of permissions. The flag InheritOnly exempts the current object from receiving the ACE. The flag NoPropagateInherit restricts inheritance to immediate child objects.
  • AccessControlType: The type of the ACE (allow or deny).

Now, if you want to assign multiple access rights to a given trustee, you can either do that with individual ACEs:

$acl  = Get-Acl $path$ace1 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',        'ListDirectory', 'ContainerInherit, ObjectInherit', 'InheritOnly',        'Allow'$acl.AddAccessRule($ace1)$ace2 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',        'ReadAttributes', 'ContainerInherit, ObjectInherit', 'InheritOnly',        'Allow'$acl.AddAccessRule($ace2)...

Or by providing the permissions as a comma-separated string:

$acl = Get-Acl $path$ace = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',       'ListDirectory, ReadAttributes, ...', 'ContainerInherit,  ObjectInherit',       'InheritOnly', 'Allow'$acl.AddAccessRule($ace)

Note, however, that you cannot grant and deny permissions with the same ACE. If you want to deny specific access rights you need to do it with a separate ACE:

$acl  = Get-Acl $path$ace1 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',        'Modify', 'ContainerInherit, ObjectInherit', 'InheritOnly',        'Allow'$acl.AddAccessRule($ace1)$ace2 = New-Object Security.AccessControl.FileSystemAccessRule 'DOMAIN\user',        'CreateDirectories', 'ContainerInherit, ObjectInherit', 'InheritOnly',        'Deny'$acl.AddAccessRule($ace2)...

Note also, that explicit permissions take precedence over inherited permissions, and Deny takes precedence over Allow.


You know how it goes when you're fighting world problems. The moment you post the question, you find the answer 5 minutes later...

Thanks to the answer of Frode F. on another question, I found the solution to my own problem. I had to copy the output of the line FileSystemRights in $Correct.Access and paste it in an Array as you can see below:

 $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", @("CreateFiles", "AppendData", "DeleteSubdirectoriesAndFiles"," ReadAndExecute", "Synchronize"), "None", "InheritOnly", "Allow") # This folder only    $acl.AddAccessRule($rule) $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", @("DeleteSubdirectoriesAndFiles", "Modify", "Synchronize"), "ContainerInherit, ObjectInherit", "InheritOnly", "Allow") # Subfolders and files only