Skip to main content

Use PowerShell to determine which groups a set of users have in common

From my PowerShell class in May, here is one of the problems a student wanted PowerShell to help with.  He needed a script that will let him feed in a list of user names and output which groups that all the users were members of.  Below is the code to do that.  Remember that you can Dot Source this into your shell or turn it into a module.

<#
.SYNOPSIS
Takes a list of users and displays the groups that
they have in common.

.DESCRIPTION
Utilizes Active Directory to take a list of users
and enumerates all the groups that the users have in
common.

.PARAMETER UserList
Comma delimited list of user names that are to
be processed.

.PARAMETER ListAll
Displays not only the groups that all users
are members of, but also the groups that at
least one user is not a member of.

.EXAMPLE
compare-group g:\userlist.txt | FT -AutoSize

Name         UserPresent
----         -----------
Domain Users        True
Marketing           True

Description
-----------
Imports a txt file containing the SAMAccountName of
the users that you want to examine.  It is then piped to
Format-Table and auto sized it to make the data more readable.



.EXAMPLE
F:\mod09\democode> compare-Group g:\UserList.txt -ListAll | FT -AutoSize

Name                                    UserPresent
----                                    -----------
Administrators                                False
Users                                         False
Guests                                        False
Print Operators                               False
Backup Operators                              False
Replicator                                    False
Remote Desktop Users                          False
Network Configuration Operators               False
Performance Monitor Users                     False
Performance Log Users                         False
Distributed COM Users                         False
IIS_IUSRS                                     False
Cryptographic Operators                       False
Event Log Readers                             False
Certificate Service DCOM Access               False
Domain Computers                              False
Domain Controllers                            False
Schema Admins                                 False
Enterprise Admins                             False
Cert Publishers                               False
Domain Admins                                 False
Domain Users                                   True
Domain Guests                                 False
Group Policy Creator Owners                   False
RAS and IAS Servers                           False
Server Operators                              False
Account Operators                             False
Pre-Windows 2000 Compatible Access            False
Incoming Forest Trust Builders                False
Windows Authorization Access Group            False
Terminal Server License Servers               False
Allowed RODC Password Replication Group       False
Denied RODC Password Replication Group        False
Read-only Domain Controllers                  False
Enterprise Read-only Domain Controllers       False
DnsAdmins                                     False
DnsUpdateProxy                                False
Marketing                                      True
Research                                      False
Production                                    False
IT                                            False
demo                                          False

Description
-----------
Loads a list of SAMAccountNames from a text file and
examines their group membership.  It outputs
a list off all groups listed in Active Director with
a $True/$False value.  If the value is $True, all the
users in the list are members of that group.  If it
is false, at least one member of that list is not in
that group.



.NOTES
The Active Directory Module for PowerShell must be
Available

The input file must contain only SAMAccountNames.

Each line of the file must only contain one
SAMAccountName.


.LINK

#>
Function Compare-Group
{
param (
[Parameter(Position=0,Mandatory=$True)]$UserList,
[Switch]$ListAll
)


# Test to verify that the Active Directory module is
# available.
If ((Confirm-module ActiveDirectory) -eq $True)
{
# Import the Active Directory module.
   Import-Module ActiveDirectory -cmdlet Get-ADUser, Get-ADGroup,
Get-ADGroupMember
}
ELSE
{
Write-Host "Active Directory Module is not availible."
-ForegroundColor Red -BackgroundColor Yellow
Break
}

# Load list of users
Try {
$Users = Get-Content $UserList -ErrorAction Stop
}
Catch
{
# If the file or path is not correct or does not
   # Exist, Warn the user and stop execution.
   Write-Host "The file or path is not correct" -ForegroundColor Red
-BackgroundColor Black
BREAK
}

# Create an object of users names
$UserObj = @()
ForEach ($U in $Users)
{
$UObj = New-Object PSObject
$UObj | Add-Member NoteProperty -name Name -Value $U
$UserObj += $UObj
}


# Load list of Groups
$Groups = Get-ADGroup -Filter *


# Only show groups that all users in the list are
# members of.

$MatchAll = $True
If ($MatchAll = $True)
{
# Create a custom object to hold the Group
   # names.  Include a Boolean property to
   # be used to determine if a user is a member of
   # that group.

$GroupObj = @()

Foreach ($G in $Groups)
{
# Create an instance of a PSObject
       $Group = New-Object PSObject

# Add the name value from the group being
       # processed to the object.
       $Group | Add-Member NoteProperty -Name Name -Value $G.Name

# Add the Boolean value property to the object.
       $Group | Add-Member NoteProperty -Name UserPresent -Value $false

# Add this instance of the object to the group of objects.
       $GroupObj += $Group
}


# Cycle through each group and compare the members of
   # Each group.  If a member if in the group, set the
   # 'UserPresent' property to $True.  If not, set the
   # the value to $False.  Any group tat is marked $true
   # at the end of this process contains all the users from the
   # list.

ForEach ($G in $GroupObj)
{
# Get the list of user Names

$MemberList = Get-ADGroupMember $G.Name

# Loop through the list of users and determine
       # if they are members of the group.  If they
       # are, set the value of 'UserPresent' to $True
       # If not, set it to $False.

ForEach ($Member in $MemberList)
{

ForEach ($User in $Users)
{
# Format each variable that will be
                # tested to make sure there are no
                # carriage returns.  Also, make sure they
                # are of data type [String] and have
                # no leading or trailing spaces.
                $Testmember = ($Member.SamAccountName) -as [String]
$User = (($User -Replace "\n","") -as [String]).trim()



# Test to see if the user is a member of the
               # group.
               If ($User -ieq $Testmember)
{

If ($User -ne "")
{
# Set the UserPresent property to
                       # $True if the user and member
                       # properties match.
                       $G.UserPresent = $True
}

}
}

}



} # End of forEach ($G in $Groups)

} # End If ($MatchAll = $True)

# Send the output to the Pipeline.

# Send all the results to the pipeline if
# the user request it.
If ($ListAll -eq $True)
{
Write-Output $GroupObj
}

# Send only the groups that all users are
# members of to the pipeline by default.
If ($ListAll -eq $False)
{
ForEach ($obj in $GroupObj)
{
If ($Obj.UserPresent -eq $True)
{
Write-Output $Obj
}
}
}


}

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.