'Get associated security group for each folder?

I am using the powershell code below to get a list of folders and subfolders on a network share. Is it possible to also display the associated security group with it? For instance Select-Object fullname,securitygroup? And if possible also then grab the list of users that are a member of that group? Thank you!

Output would be like:

\Server\Share\Folder1 Folder1-W John Doe....

Get-ChildItem \\Server\Share | Where { $_.PSIsContainer } | Foreach  {Get-Childitem $_.FullName}| Where { $_.PSIsContainer } | Select-Object fullname


Solution 1:[1]

I assume that by "associated security group" you mean a group used to grant users permissions to access the folder. There's no way for the OS to identify inherently what purposes the groups in the ACL are being used for, so you need to determine some set of consistent criteria that can be used to identify which groups are "associated security groups".

Some examples:

  • Are the "associated security groups" always the only security principals with permissions? (If so, that makes things simpler; but it's also very unlikely, because you'll generally have at least BUILTIN\Administrators, Domain Admins, NT AUTHORITY\SYSTEM, and CREATOR OWNER.)
  • Do the groups follow some naming convention that can be derived from the folder names? For example, I've used a naming convention like ACL_ServerName_ShareName_PermissionsCode (e.g. ACL_HQFP01_Shared-Folder1-M). In that scenario, it's always possible to identify the permissions group names given the share and subfolder names.
  • Are the groups always the only security principals with explicit (i.e. non-inherited) permissions?

I'm going to take a guess that you're following Microsoft's recommended best practices: that you're using NTFS permissions, and you're not assigning explicit permissions to anything other than domain groups designated for that purpose, which would make these "associated security groups" the only security principals with explicit permissions. In that case, you can include a comma-separated list of these groups like this:

| Select-Object FullName, @{Name = 'AssociatedSecuirtyGroups'; Expression = {((Get-Acl $_).Access | ?{! $_.IsInherited} | Select-Object -ExpandProperty IdentityReference) -join ', '}}

You can get the members of the groups by importing the Active Directory module and using Get-ADGroupMember (or there are more complicated ways to query AD without the module), but exactly how depends on which way you want to "grab" them, because if you can have multiple associated security groups for one folder, then you can't do it in a one line per folder display, at least not without making things very messy.

Solution 2:[2]

Rather than filter for folders after you pull the directory listing, why not filter first? It should speed things up considerably. Then you can run the results through a loop to pull security groups with Get-ACL, and get the members with Get-ADGroupMember at that point. Try this on for size...

$Output = @()
$DirList = GCI \\server\share -directory | %{$_.FullName; GCI $_ -Directory|select -expandproperty FullName}
ForEach($Dir in $DirList){
    $ACLs=@()
    (get-acl $Dir).accesstostring.split("`n")|?{$_ -match "^(.+?admin(istrators|141))\s+?(\w+?)\s+?(.+)$"}|%{
        $ACLs+=[PSCUSTOMOBJECT]@{Group=$Matches[1];Type=$Matches[2];Access=$Matches[3]}
    }
    ForEach($ACL in $ACLs){
        if($Members){Remove-Variable Members}
        $Members = Get-ADGroupMember $ACL.Group -ErrorAction SilentlyContinue|%{[string]$_.SamAccountName}
        $Output += "$Dir $($ACL.Group) $($ACL.Access) $($Members -join ",")"
    }
}

Now, your output doesn't seem very realistic considering what all you want, so I made it one line per group for each folder in this format: such as:
\\Server01\ShareA ShareA-R ReadOnly JohnDoe,JaneSmith
\\Server01\ShareA ShareA-W Read,Write JackDaniels,CaptMorgan
\\Server01\ShareB ShareB-R ReadOnly JohnDoe
That just made more sense to me since you wanted groups split out to the user level. I suppose you could list each person on their own line for each share, but your list is going to be really long. Anyway, you should be able to get something that you want with what I gave you.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adi Inbar
Solution 2 TheMadTechnician