Powershell command to compare AD user group member

2019-09-13 10:07发布

I'm trying to figure out the logic to do something like this:

  • Query all AD groups in a specific OU
  • Query all the users in a specific OU
  • Query all the user's group memberships
  • If any user belongs to one or more groups in the initial group query, output that information
  • If any user belongs to none of the groups in the initial group query, also output that information

I've dug around on this site and found a script that works for the most part, but I'm stuck on how I can compare the user's group membership to the original group query that I'm pulling. It looks like I could use the compare-object cmdlet but the parameters don't seem to include anything that would let me keep track of how many groups the two objects have in common.

The code I found online is below:

$groups = Get-ADGroup -Filter * | where {$_.distinguishedname -like "*,OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv"}
$users = Get-ADUser -Filter * | where {$_.distinguishedname -like "*,OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv"}

foreach ( $User in $Users ) {
    $userGroups =  Get-ADPrincipalGroupMembership $User
    if ( $userGroups.Count -gt 1 ) {
        "{0} is a member of the following {1} groups:" -f $User.SamAccountName, $userGroups.Count
        foreach ( $group in $userGroups ) {
            "`t{0}" -f $group.Name 
        }
    } elseif ( $userGroups.Count -lt 1 ) {
        "{0} is a member of the following {1} groups:" -f $User.SamAccountName, $userGroups.Count
        foreach ( $group in $userGroups ) {
            "`t{0}" -f $group.Name 
        }
      }
}

The problem with this is that I don't have a way of comparing the user group names to the names of the group query in line 1. I also can't determine that a user belongs to 1 or more groups from that list. I'm not sure if I can use the same count method.

2条回答
我命由我不由天
2楼-- · 2019-09-13 10:42

You can validate that accounts are member of at least one group from your reference list by using Compare-Object:

foreach ( $User in $Users ) {
    $userGroups =  Get-ADPrincipalGroupMembership $User
    if (!(Compare-Object $userGroups $groups -IncludeEqual -ExcludeDifferent)) {
        "{0} doesn't belong to any reference group." -f $User.SamAccountName
    }
}

Side note: use the -SearchBase parameter instead of filtering the results of Get-ADUser and Get-ADGroup by a wildcard match on the distinguished name:

$groups = Get-ADGroup -Filter * -SearchBase 'OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv' -SearchScope Subtree
$users  = Get-ADUser -Filter * -SearchBase 'OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv' -SearchScope Subtree
查看更多
太酷不给撩
3楼-- · 2019-09-13 10:53

I ended up doing the following and it works well for what I need. In case anyone is interested, sample code is below:

#gets a list of all groups in a given OU and stores the objects in the $groups variable
$groups = Get-ADGroup -Filter * -SearchBase 'OU=TUNE_TEST_GROUPS,OU=TUNE_TEST,DC=tune,DC=priv' -Properties name | select name

#pipe each group object into a foreach loop and output a string value of the same group name and stores it into the $groups_string variable
$groups_string = $groups | % {$_.name}

#gets a list of all users in a given OU and stores the objects in the $users variable
$users = Get-ADUser -Filter * -SearchBase 'OU=TUNE_TEST_USERS,OU=TUNE_TEST,DC=tune,DC=priv'


$results=@{
"Username" = ""
"Groupname" = ""
}

$table=@()

#iterates through every user in the $users variable and retrieves their group memberships
foreach ($user in $users) {
    #selects each group name and stores it in the $groupMembership variable
    $groupMembership = Get-ADPrincipalGroupMembership $user | select name

    #compares the names of each user's group to the baseline group name.
    $groupMembership | foreach ($_) {

        #If there is a match add the group name and the username to the $results hash table
        if ($groups_string -contains $_.name) {
            $results."Groupname" = $_.name
            $results."Username" = $user.Name

            #create a new PS object and supply the properties of the $results hash table to each object
            $objresults = New-Object psobject -Property $results

            #add each object to the $table array
            $table += $objresults
        }
    }  

}

#display/output the $table array and format it to fit 
$table | ft -AutoSize
查看更多
登录 后发表回答