4

I'm new to AD and Powershell so please forgive me if I use the wrong terminology.

I have a series of 50+ Active Directory groups called "ABC-something". Every active user needs to belong to exactly one group. Users are also members of other groups that are used for different purposes and that should not affect this exercise.

Since we're in the middle of a big move, my population is a moving target. I'm dealing with around 1000 users, so going through an export of all the memberships for all users is less than desirable.

I'm hoping to be able to write a script that will return the userid (or samAccountName) of every user that is a member of more than one group ABC* that I could run on demand. (I assume writing a script to find active AD users NOT in a group is a different question altogether.)

Putting on my database hat, I see the logic as follows:

1) Iterate trough all groups called ABC*. For each, capture all group members. I should end up with a table or object in memory looking like

Group1 PersonA
Group1 PersonB
Group2 PersonB

2) Find a way to group, or count, or iterate through this list.

This is where I get stuck because the Powershell examples I've seen so far don't manipulate the data much before exporting or displaying data.

Can you suggest a sample script to get me started, or at least point to online resources about manipulating data in Powershell?

chabzjo
  • 149
  • 1
  • 1
  • 3

4 Answers4

6

Using Get-ADUser -Filter * -Properties memberOf gets a list of all users, and the groups they are a member of.

You could pipe that into a foreach or where-object and apply any required criteria. If you wanted to know if a user was in foo, and bar you could run a command like this.

Get-ADUser -Filter * -Properties memberOf | `
Where-Object {
    $_.memberof.contains('CN=foo,OU=allsites,DC=example,DC=org') -and `
    $_.memberof.contains('CN=bar,OU=allsites,DC=example,DC=org' ) 
}

Or lets say you just wanted to know how many people were in at least 7 groups?

Get-ADUser -Filter * -Properties memberOf | `
Where-Object {$_.memberof.count -ge 7}
Zoredache
  • 130,897
  • 41
  • 276
  • 420
4

Unless you're just dead-set on going at it from the groups angle, I'd run through every user and look at their group membership, instead:

$Users = get-aduser -filter '*' -ResultSetSize 10

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

The -ResultSetSize 10 on the first line is just for testing, remove that part completely to run it against the entire domain. This will iterate through the users, and list the people w/ more than 1 group, and what they are.

Get-ADGroup and Get-ADGroupMember should work similarly to the above commands for users.

You could also use something like the following as a start for looking at it from the groups side of the equation:

Get-ADGroup 'ABC-something' | Get-ADGroupMember
Hunter Eidson
  • 493
  • 5
  • 8
2

Powershell can do most of the heavy lifting for you here. I'm using the Quest AD cmdlets for this example, but the standard ones should also work.

$FullList = @(ForEach $group in (Get-QADGroup -Identity ABC_))
{
    Get-QADGroupMember $group|Select @{name="Group";expression={$group.Name}}, @{name="Member";expression={$_.SAMAccountName}}
} )

$FullList | Group-Object -Property Member |Where {$_.Count -gt 1}

Will give you an output of all the user SAM Account Names and the number of the groups they're in, if greater than one.

Dave_J
  • 121
  • 2
0

In my case, I needed to take an array of many AD group names, and then see if there were any users that were in more than any one of them.

  • If any user is in more than one of any of these groups, then this will be a problem and cause conflicts with Group Policy Preferences and their 'member of' conditions.

With the help of an answer here, I came up with this variation that helped me automate a routine scheduled process that'll send an email with the detail if there are any accounts in more than one groups from the list of groups defined in the $g variable.

This basically creates a list with SamAccountName and Group, then does a Group-Object against the SamAccountName to list only those where its counts is greater than 1.

PowerShell

$g = @("group1","group2","group a","group z");
$g | ForEach-Object { 
    $b = $_; Get-ADGroupMember -Identity $_ | Select-Object SamAccountName, @{n="ADGroup";e={$b};}
        } | Group-Object -Property SamAccountName | 
                Where-Object {$_.Count -gt 1};

Output List Sample

Note: This is a sample of the list that is grouped with group-object to then show SamAccountName values with a count greater than 1.

SamAccountName ADGroup
-------------- -------
jsmith         group1    
bobama         group1    
dtrump         group2    
swalton        group2    
pjuiceit       group a    
aventura       group a    
apowers        group z    
drevil         group z   
Pimp Juice IT
  • 1,077
  • 1
  • 9
  • 16
  • Posting in case someone finds this helpful since I pieced it together with the help of one of the answers here but more native AD cmdlets. I tried various techniques from another answer but didn't get expected results and once I ironed out this logic, it seemed to work great without issue. – Pimp Juice IT Dec 29 '22 at 22:57