Define where permissions apply with Set-Acl
Asked Answered
P

1

2

I'm trying to emulate in PowerShell what I typically do in the windows folder properties window available from: Folder properties → Secutity → Advanced → Permissions → Change Permissions...

In that GUI there are tick boxes for

  • Include inheritable permissions from this object's parent
  • Replace all child object permissions with inheritable permissions from this object - I believe corresponds to PropagationFlag = None

When you click the Add/Edit... button you have a drop down list with the following options, what InheritanceFlags correspond with each of them? I've filled in the ones I've found by experimentation

  • This folder only - None
  • This folder subfolders and files
  • This folder and subfolders
  • This folder and files
  • subfolders and files only - ContainerInherit, ObjectInherit
  • subfolders only - ContainerInherit
  • files only - ObjectInherit

What flags correspond with the check box Apply these permissions to objects and/or containers within this container only?

I've also determined that these PropagationsFlags mean:

  • InheritOnly (the ACE is propagated to all current child objects only if they are set to inherit)
  • NoPropagateInherit (the ACE is not propagated to any current child objects)
  • None (this ACE is propagated to ALL child objects overwriting what they had before and turns on their inheritance)

I'm wanting to find out how to add extra permissions for existing users/groups or add extra users/groups to the permissions of a folder and have that propagate with "This folder subfolders and files" but NOT "Replace all child object permissions with inheritable permissions from this object" in case there is a subfolder with other special permissions on it on purpose for a good reason, such as the symbolic link folders in user profiles.

The code I'm working with at the moment is below. Eventually I'm going to be using it on a lot of different folders on many computers in multiple domains including user profiles in c:\users\{username}

function check-permissions ( $folder ) {
    $GroupName = "Domain Admins"
    if ( -not (Test-Path -LiteralPath $folder) ) {
        Write-Output "Cannot find $folder"
    } else {
        ((get-acl -literalPath $folder).access).IdentityReference.Value |
            findstr /i ($env:USERDOMAIN + "\"+ $GroupName) |
            out-null
        $result = $?
        if ( -not $result ) {
            write-output ($folder + ": adding permissions")
            #adding new permissions
            $colRights = [System.Security.AccessControl.FileSystemRights]"FullControl" 
            $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit, [System.Security.AccessControl.InheritanceFlags]::ObjectInherit
            $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::InheritOnly
            $objType =[System.Security.AccessControl.AccessControlType]::Allow
            $objUser = New-Object System.Security.Principal.NTAccount($env:USERDOMAIN + "\" + $GroupName)
            $objACE  = New-Object System.Security.AccessControl.FileSystemAccessRule ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
            # output the ACE
            $objACE | format-list *
            #$objACL = Get-Acl -literalPath $folder    # This gets the full security info but substitutes the different user as owner, which we don't want or it will overwrite the owner info with the wrong user when we use set-acl
            $objACL = (Get-Item -literalPath $folder).GetAccessControl('Access')
            if ( -not $? ) {
                Write-Output ("Failed to get permissions on: " + $folder)
            } else {
                $objACL.AddAccessRule($objACE)
                if ( $objACL ) { #objACL exists
                    #Set-ACL -literalPath ($folder) -AclObj $objACL  # This tries to set the owner too
                    [System.IO.Directory]::SetAccessControl($folder,$objACL) # This seems to work
                } else { # $objACL is null
                    write-output "Error developing new permissions object. Leaving folder permissions alone."
                }
            }
        } else {
            write-debug ($folder + ": Permissions OK")
        }
    }
}

check-permissions "c:\temp\test\a"
Propolis answered 2/9, 2015 at 9:1 Comment(1)
read here for some flag specs: msdn.microsoft.com/en-us/library/ms229747(v=vs.110).aspxDoorframe
N
3

The "Apply To" value is defined by a combination of InheritanceFlags and PropagationFlags (which actually define how propagation is restricted). Here's an overview of which values produce which "Apply To" setting (ContainerInherit and ObjectInherit abbreviated to CI and OI respectively due to limited space):

Apply To                            Inheritance   Propagation
--------                            -----------   -----------
This folder only                    None          any
This folder, subfolders and files   CI, OI        None or NoPropagateInherit
This folder and subfolders          CI            None or NoPropagateInherit
This folder and files               OI            None or NoPropagateInherit
Subfolders and files only           CI, OI        InheritOnly
Subfolders only                     CI            InheritOnly
Files only                          OI            InheritOnly

For a more detailed description of propagation rules see here as mentioned by @CB. in the comments to your question.

Nuclease answered 3/9, 2015 at 18:28 Comment(7)
So for the ones that have a propagation flag of "None or NoPropagateInherit" does that correspond to the checkbox that says "Replace all child object permissions with inheritable permissions from this object"?Propolis
I just tested and that is a no, about the Replace all child object permissions with inheritable permissions from this object checkbox. the CI, OI, NPI flag combo does This folder, subfolders and files but only 1 level of folders, as it doesn't include the grandchild comment on that MSDN article. When using CI, OI and the Propagation flag None it does what I want of This folder, subfolders and files including grandchildren but leaves subfolders alone if they previously were not inheriting permissions. Though it makes me wonder how to make it clobber those and force inheritence.Propolis
When I use CI and None, it applies permissions to the root folder. When I use CI, OI, and None, it checks the boxes like (Full Control, Read & Execute, etc). If I try to do CI and None (because I just want the root folder and sub folders, it checks the Special Permissions box. Why?Creath
@Creath Because by default permissions apply to folder, subfolder, and files. If you want permissions to not apply to files that differs from the default, hence special permissions. You don't want permissions to apply to just the folder and subfolders, BTW. Make them apply to folder, subfolder, and files.Nuclease
@AnsgarWiechers - Ok, I think i got you, so "CI, OI and None" is the default? Any other combination will mark the "Special Permissions" checkbox, correct?Creath
Although I will say the None propagation flag is a bit confusing. The documentation says Specifies that no inheritance flags are set., so how is setting CI,OI, and None valid if None means you didn't set Inheritance flags (CI,OI) or am I reading that wrong?Creath
You can use either CI,OI+None or CI,OI+NoPropagateInherit to get the permissions to apply to folders, subfolders, and files. Don't confuse inheritance flags (container inheritance, object inheritance) and propagation flags (None, NoPropagateInherit, InheritOnly). They're different things, which in combination govern where an ACL is applied. And yes, these settings are a bit confusing, particularly the propagation flags, which basically indicate where not to propagate ("none" means "propagate everywhere").Nuclease

© 2022 - 2024 — McMap. All rights reserved.