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 flagInheritOnly
exempts the current object from receiving the ACE. The flagNoPropagateInherit
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