Powershell – (Powershell) Method to return a list of groups where a specific user has ‘write member’ security

access-control-listactive-directorygroupspowershell

We use a piece of web-based software that users can log on to in order to manage access to shares controlled with AD groups. The list of groups a user can manage are the groups on which they have 'Write Members' security. This allows users to maintain file shares without requiring knowledge of AD.

I am trying to write a Powershell script using the quest.activeroles.admanagement that will return a neat list of groups that a specified user has 'Write Members' security on, in order to clean out permissions for departed users. The groups I need to search through are stored in an OU, though there are over 1,000 of them.

I have so far come up with:

add-pssnapin quest.activeroles.admanagement
Get-QADObject -ShowProgress -SearchRoot 'domain.server.com/path/to/OU' -SearchScope 'OneLevel' -Type Group -SizeLimit 2500 | Get-QADPermission -Rights 'WriteProperty' -Property 'member' -Account "user" -WarningAction SilentlyContinue

This works fine (however inefficiently) but the host output is fairly messy:

Permissions for: full.domain.path/OU/path/group1

Ctrl   Account                                  Rights                              Source           AppliesTo                                    
----   -------                                  ------                              ------           ---------                                    
       Domain\user                              Write member                        Not inherited    This object and all child objects            
Permissions for: full.domain.path/OU/path/group2
       Domain\user                              Write member                        Not inherited    This object and all child objects                        Not inherited    This object and all child objects            
Permissions for: full.domain.path/OU/path/group3
       Domain\user                              Write member                        Not inherited    This object and all child objects                        Not inherited    This object only                             
Permissions for: full.domain.path/OU/path/group4
       Domain\user                              Write member                        Not inherited    This object and all child objects                        Not inherited    This object and all child objects            

I get the required information, but a whole lot of chaff surrounding it. If I pipe/append to a text file, I only get the username, not the group names.
Ideally what I'd want is just a list of group names without the OU path, or in a perfect world, a CSV where column one is the user name and column two is the group, so that I could run multiple users (foreach ($username in $usernames)):

User                Group
domain\username     group_name_one
domain\username     group_name_two
domain\username     group_name_three

What would be the best way to tackle this in such a way that Export-CSV would spit out something a little bit nicer?

Best Answer

There are two problems here.

  1. The CMDlet Get-QADPermission is writing directly to the console during execution which is why you're seeing Permissions for: .... Since your pipeline is writing to the same output, it all gets mixed together. Store the output from your pipeline to a variable instead.

  2. When you pipe the group into Get-QADPermission, you're throwing away the group object and getting a permissions object instead. If you want to keep the original object, you need to filter with Where-Object.

Also, be careful with Get-QADPermission. If you only query for WriteProperty, it won't return results with both Read+Write access. Usually you want to query for both. And in most cases, you also want to use -Inherited to get permissions granted from parent OU's. If you're really looking for once-off permissions, then you can ignore this switch.

function Test-UserCanModifyGroupsInOU ($Username, $OU)
{
  $results = Get-QADGroup -SearchScope 'OneLevel' -SearchRoot $OU |
    Where-Object {
      $_ | Get-QADPermission -Rights ReadProperty,WriteProperty -Property member -Account $username
    } |
    Select @{Name="User";Expression={$username}}, @{Name="Group";Expression={$_.Name}}
  $results | Write-Output
  $results | Export-Csv "$username.csv"
}

@("bob","sally") |
  ForEach-Object {
    Test-UserCanModifyGroupsInOU -Username $_ -OU 'domain.org.com/path/to/OU'
  }

Also note that this only works for permissions on specific properties. It won't return results for a user that has "Full Control" on the group, even though they're stil allowed to modify the member attribute.