Search code examples
powershellpermissionsntfs

PowerShell Setting advanced NTFS permissions


I'm trying to apply NTFS permissions that are defined in the 'Advanced' tab of the Windows security settings. One ACL $Rule is for This folder only and another one is for the Subfolders and files only.

The permissions are heavily modified as you can see below:

(Get-Acl 'L:\Test\Beez\RAPJOUR\Appels List\Correct').Access

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : CreateFiles, AppendData, DeleteSubdirectoriesAndFiles, ReadAndExecute, Synchronize
AccessControlType : Allow
IdentityReference : Domain\Dirk
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

FileSystemRights  : DeleteSubdirectoriesAndFiles, Modify, Synchronize
AccessControlType : Allow
IdentityReference : Domain\Dirk
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : InheritOnly

This folder only

  • Everything is on except for : Full control, Write attributes, Write extended attributes, Delete, Change permissions and Take ownership.

Subfolders and files only

  • Everything is on except for : Full control, Change permissions and Take ownership.

This is a piece of the code I use to apply permissions. In this case it has to be defined in the part Change:

 $f = 'L:\Test\Beez\RAPJOUR\Appels List\Wrong'
 $ADobject = 'Domain\User'
 $acl = Get-Acl $f

 $Grant = 'Change'
    # Remove user/group first
    $rule = New-Object system.security.AccessControl.FileSystemAccessRule("$ADobject","Read",,,"Allow")
    $acl.RemoveAccessRuleAll($rule)

    # Add read permissions
    if ($Grant -eq 'ReadAndExecute') {
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "ReadAndExecute", "ContainerInherit, ObjectInherit", "None", "Allow")
    }

    if ($Grant -eq 'Change') {
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "Modify", "ContainerInherit, ObjectInherit", "Synchronize", "Allow  DeleteSubdirectoriesAndFiles")
        $acl.AddAccessRule($rule)
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "AppendData", "ContainerInherit, ObjectInherit", "ReadAndExecute","Synchronize", "Allow  CreateFiles","DeleteSubdirectoriesAndFiles")
    }

    if ($Grant -eq 'Modify') {
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "Modify", "ContainerInherit, ObjectInherit", "None", "Allow")
    }

    if ($Grant -eq 'FullControl') {
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
    }

    if ($Grant -eq 'ListFolderContents') {
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("$ADobject", "ReadAndExecute", "ContainerInherit", "None", "Allow")
    }

$acl.AddAccessRule($rule)
Set-Acl $f $acl

I can't seem to get the syntax right.. Thank you for your help.

Thanks to this post I've already found the part for:

  • 'Subfolders and files only': "ContainerInherit, ObjectInherit", "InheritOnly"
  • 'This folder only': "None", "InheritOnly"

Solution

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