Question

First up, I am not a script writer, so I apologise if this sounds like a real newbie question.

I am trying to write a Powershell query to list all user accounts within a certain OU sub-tree who do not belong to at least one of 4 groups.

As far as I can tell you cannot query this directly on the AD User object, so you need to iterate through the groups to get the membership, but I'm not clear on how to go about this across multiple groups.

I have put together a script that can find all users, add them to a temporary group and then remove them if they belong to one of the four other groups, but this looks like a horrible way to approach it, so I am hoping someone has a better solution.

Here's what I currently have (don't laugh) :-(

Import-Module ActiveDirectory
$groupname = "TempGroup"
$excludegroup1 = "Group1"
$excludegroup2 = "Group2"
$excludegroup2 = "Group4"
$excludegroup2 = "Group4"
$users = Get-ADUser -Filter * -SearchBase "ou=xxx,dc=xxx,dc=xxx" -SearchScope Subtree
foreach($user in $users)
{
  Add-ADGroupMember -Identity $groupname -Member $user.samaccountname -ErrorAction SilentlyContinue
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup1
foreach($member in $excludemembers)
{
 Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup2
foreach($member in $excludemembers)
{
 Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup3
foreach($member in $excludemembers)
{
 Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$members = Get-ADGroupMember -Identity $groupname
$excludemembers = Get-ADGroupMember -Identity $excludegroup4
foreach($member in $excludemembers)
{
 Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}

All help gratefully accepted.

Was it helpful?

Solution

All users, computers, groups and contacts (and possibly other objects) in Active Directory have a property called memberof. This property contains the distinguished names of all groups from the whole forest that this entity is a member of, as the attribute's name implies.

Given this information, you can now construct an ldap search query to find all entities that are not members of at least one of those groups:

(!(|(memberof=CN=Group1,dc=domain,dc=com)(memberof=CN=Group3,dc=domain,dc=com)(memberof=CN=Group3,dc=domain,dc=com)))

Other conditions may be included as necessary.

If you need to obtain the distinguished names of those groups first, you can either hard-code them in your filter or do a normal Powershell search for the groups and then read their distinguished names.

You can use the ldap query via the command's -LDAPFilter parameter.

OTHER TIPS

In case anyone is interested, this is the code I have now. It uses a group, which it flushes each run, because then I can simply double-click a user to get into their object and add them to the group they're missing from.

Import-Module ActiveDirectory
$groupname = "NotInGroups"
$members = Get-ADGroupMember -Identity $groupname
foreach($member in $members)
{
 Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$users = Get-ADUser -Filter {((memberof -notlike "CN=Group1,DC=domain,DC=local") -AND (memberof -notlike "CN=Group2,DC=domain,DC=local") -AND (memberof -notlike "CN=Group3,DC=domain,DC=local") -AND (memberof -notlike "CN=Group4,DC=domain,DC=local"))} -SearchBase "ou=users,dc=domin,dc=local" -SearchScope Subtree
foreach($user in $users)
{
  Add-ADGroupMember -Identity $groupname -Member $user.samaccountname -ErrorAction SilentlyContinue
} 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top