(Powershell) Method to return a list of groups where a specific user has 'write member' security
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?
There are two problems here.
The CMDlet
Get-QADPermission
is writing directly to the console during execution which is why you're seeingPermissions 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.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.