Isi
Isi

Reputation: 109

Get-acl repeating groups - Powershell

I am trying to get a list of groups assigned to a folder using below PowerShell command on a remote server in a same domain:

get-acl '\\Testserver\test' | % {$_.access} | ft IdentityReference -HideTableHeaders

What happens is there is a group that gets repeated 3 times. I checked the NTFS permissions and this group is assigned only once. below is the output. Any help on this? :(

testdiomin\testgroup
testdiomin\testgroup
testdiomin\testgroup
BUILTIN\Administrators

Just to add, I checked the advanced security on the folder and this group is assigned once. If I take ft off the command all the attributes look identical for the repeated group!

Upvotes: 1

Views: 3322

Answers (3)

Rohn Edwards
Rohn Edwards

Reputation: 2669

The security descriptor that Get-Acl returns will contain the discretionary ACL (which controls access) and the system ACL (which controls auditing) in a more unfiltered way than the Windows ACL Editor (the view you get on the Security tab for the folder's properties). In other words, the ACL Editor is trying to help you out and show the information in a format that's easier to work with. A simple example that should work on any Windows system is checking the actual Windows folder (there are actually several different folders and registry keys where you can see this):

PS> Get-Acl C:\Windows | select -exp access | Format-Table

           FileSystemRights AccessControlType IdentityReference                                      IsInherited                InheritanceFlags Propagation
                                                                                                                                                       Flags
           ---------------- ----------------- -----------------                                      -----------                ---------------- -----------
                  268435456             Allow CREATOR OWNER                                                False ContainerInherit, ObjectInherit InheritOnly
                  268435456             Allow NT AUTHORITY\SYSTEM                                          False ContainerInherit, ObjectInherit InheritOnly
        Modify, Synchronize             Allow NT AUTHORITY\SYSTEM                                          False                            None        None
                  268435456             Allow BUILTIN\Administrators                                       False ContainerInherit, ObjectInherit InheritOnly
        Modify, Synchronize             Allow BUILTIN\Administrators                                       False                            None        None
                -1610612736             Allow BUILTIN\Users                                                False ContainerInherit, ObjectInherit InheritOnly
ReadAndExecute, Synchronize             Allow BUILTIN\Users                                                False                            None        None
                  268435456             Allow NT SERVICE\TrustedInstaller                                  False                ContainerInherit InheritOnly
                FullControl             Allow NT SERVICE\TrustedInstaller                                  False                            None        None
ReadAndExecute, Synchronize             Allow APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES       False                            None        None
                -1610612736             Allow APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES       False ContainerInherit, ObjectInherit InheritOnly

If you compare that output to the output that the ACL Editor gives you, you'll notice that the number of ACEs doesn't match, e.g., there should be a single entry for 'Users' instead of the two that Get-Acl's output is showing. Notice above how there are some numeric rights mixed in with the friendly text rights? Those are called generic rights, and they're kind of a shortcut to define four sets of rights: Read, Execute, Write, All. They're a shortcut because they're translated differently depending on the type of object the ACE belongs to, i.e., file/folder, registry key, service, printer, AD object, etc, but you can use those four bits to describe basically the same thing for each type of object.

Anyway, the ACL Editor is translating the generic rights into the object specific rights, and then it is looking to see if there are any ACEs that can be logically grouped together. Let's try an example. In the output above, there were two ACEs for 'Users':

IdentityReference              FileSystemRights                   InheritanceFlags     PropagationFlags
-----------------              ----------------                   ----------------     ----------------
BUILTIN\Users                       -1610612736    ContainerInherit, ObjectInherit          InheritOnly
BUILTIN\Users       ReadAndExecute, Synchronize                               None                 None

When translated from generic rights to FileSystemRights, the -1610612736 value means ReadAndExecute, Synchronize. Once that's been translated, notice that the two ACEs match in Type (Allow), IdentityReference (BUILTIN\Users), and FileSystemRights (ReadAndExecute, Synchronize). The only things that don't match are the InheritanceFlags and PropagationFlags. The first one has the ContainerInherit, ObjectInherit inheritance flags, which means that the ACE will apply to sub folders and files, and the InheritOnly propagation flag, which means that the ACE will not apply to the folder itself. The second ACE has no inheritance or propagation flags, which means it will only apply to the folder itself. That means you can logically combine them into a single ACE that grants ReadAndExecute to Users that will apply to the folder, sub folders, and files.

So, it's probably normal. You'll need to look at the raw output from the Access property to confirm that, though.

There's a module available here that tries to display the information the way that the ACL Editor does. Here's what the output looks like for C:\Windows:

PS> Get-AccessControlEntry C:\Windows


    DisplayName      : C:\Windows
    Owner            : NT SERVICE\TrustedInstaller
    DACL Inheritance : Disabled


AceType             Principal                      AccessMask                     InheritedFrom        AppliesTo                     
-------             ---------                      ----------                     -------------        ---------                     
AccessAllowed       CREATOR OWNER                  FullControl                    <not inherited>        CC CO                       
AccessAllowed       SYSTEM                         FullControl                    <not inherited>        CC CO                       
AccessAllowed       SYSTEM                         Modify, Synchronize            <not inherited>      O                             
AccessAllowed       Administrators                 FullControl                    <not inherited>        CC CO                       
AccessAllowed       Administrators                 Modify, Synchronize            <not inherited>      O                             
AccessAllowed       Users                          ReadAndExecute, Synchronize    <not inherited>      O CC CO                       
AccessAllowed       NT SERVICE\TrustedInstaller    FullControl                    <not inherited>      O CC                          
AccessAllowed       APPLICATION PACKAGE            ReadAndExecute, Synchronize    <not inherited>      O CC CO                       
                    AUTHORITY\ALL APPLICATION                                                                                                  
                    PACKAGES                                                                                                                   

The current version that's available for download doesn't always logically group ACEs when they can be grouped (it won't group ACEs that are equal in the 'AppliesTo' area that can have their rights combined). Look for that in a future version.

Upvotes: 2

TheMadTechnician
TheMadTechnician

Reputation: 36322

As Matt has already touched on this comes down to how [System.Security.AccessControl.FileSystemAccessRule]'s are constructed. When you create an access control rule you have to designate 5 things. Those are:

  • User: Security.Principal.NTAccount object, this is something like 'Domain\TMTech'
  • Rights: Security.AccessControl.FileSystemRights object, you know, Read, Write, DeleteSubdirectoriesAndFiles... you can do a [enum]::GetNames([Security.AccessControl.FileSystemRights]) to see what your options are.
  • Inheritence: Security.AccessControl.InheritanceFlags object, affects how files and folders within this inherit this rule
  • Propegation: System.Security.AccessControl.PropagationFlags object, very similar to Inhertence, except this only applies to the objects within the container, and not the container itself.
  • Type: Security.AccessControl.AccessControlType object, this is simply Allow or Deny

With all that said, since there are so many things that you can have set as access rules it's well possible to have more than two items show up for the same user, especially if you have seperate Allow and Deny rules, and different Inheritence and Propegation rules setup. Such as allowing users to read a folder's attributes, and all of the objects within it's attributes, but only allowing the user to change the attributes of the objects within it. That's one rule with Inheritence, and one with Propegation setup. Then you setup a Deny rule so they can not delete anything, and there's a third rule that'll show up for them.

ACLs can get extremely complicated very quickly. I actually keep a code snippet on hand just to help me remember all of it for when I have to work with ACLs in any depth beyond just copying from one object to another, or simple removal of a rule from something. Here's what I keep for myself:

$colRights = [System.Security.AccessControl.FileSystemRights]"Read, Write, Modify, DeleteSubdirectoriesAndFiles" 

$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None 
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None 

$objType =[System.Security.AccessControl.AccessControlType]::Allow 

$objUser = New-Object System.Security.Principal.NTAccount("DigitalGhost\$strOwnerName") 

$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
    ($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType) 

$objACL = Get-ACL "Z:\ACLSource" 
$objACL.AddAccessRule($objACE) 

#If the output path doesn't exist, make it quietly.
If(!(Test-Path "z:\$strOwnerName")){$null = New-Item "Z:\$strOwnerName" -ItemType directory}


Set-ACL "Z:\$strOwnerName" $objACL

Upvotes: 1

Matt
Matt

Reputation: 46710

I have a test folder in where I gave a user both allow and deny permissions. In windows if i just look at the security tab of the folder I see the user listed once. However when I use Get-Acl on that particular I see the permission break down. Yes the user is listed multiple time but the FileSystemRights and AccessControlType are different. You should just run get-acl '\\Testserver\test' | % {$_.access} without the Format-Table and you will see what I am talking about.

Some truncated sample output from my own folder described above.

get-acl 'c:\temp\new folder' | Select-Object -ExpandProperty access 

FileSystemRights  : ReadExtendedAttributes, ReadAttributes
AccessControlType : Deny
IdentityReference : BA\sslvpn
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

..........

FileSystemRights  : ReadData, ExecuteFile, Synchronize
AccessControlType : Allow
IdentityReference : BA\sslvpn
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

As you can see a single user is listed twice. This is also illustrated in Windows Explorer File/Folder properites under Security > Advanced.

If you are just looking for the name and dont care about the permissions themselves you could just use -Unique

get-acl 'c:\temp\new folder' | Select-Object -ExpandProperty access | Select IdentityReference -Unique | Ft -HideTableHeaders

Upvotes: 2

Related Questions