Search code examples
powershellactive-directoryadgroup

Modify ADGroup if the Description of a User changes - Powershell


I'm still pretty new to powershell. I have now the order to create a group / mail distribution which gets updated weekly. It looks for the description of the user. I have an Arraylist in which I have listed all Descriptions which should be in there. Add the User is not a problem but i want aswell that if the discription of someone changes he gets removed from the group. I tried with some examples from here but its not working. Im glad for every answer.

Add:

$Descriptions =  @("Supporter","System Eng", "etc.","etc.")
Foreach($Description in $Descriptions){
$user = Get-ADUser -Filter * –SearchBase "OU=Int,OU=user,OU=1,DC=test,DC=me,DC=nl" -properties *| Where-Object {$_.Description -like $Description}
$group = Get-ADGroup "CN=testgroup,OU=Dirs,OU=Global,OU=group,OU=1,DC=test,DC=me,DC=nl"

Add-ADGroupMember $group -Members $user

}

Remove:

$groupname = 'testgroup'
$members = Get-ADUser -LDAPFilter "(&(!(description=$Descriptions))(memberOf=CN=testgroup,OU=Dirs,OU=Global,OU=group,OU=1,DC=test,DC=me,DC=nl))"

foreach($member in $members)
{
    Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname-Confirm:$false
}

I guess the mistake is here "(&(!(description=$Descriptions)) maybe im wrong but i have no clue how to do it.


Solution

  • Since you are using the -like operator without wilcard characters, you gain no benefit from using -like. When comparing a single value against a collection, you should consider using the -in operator. However, Containment Comparison Operators like -in and -contains are not supported in the -filter of the ActiveDirectory cmdlets. You are left with either iterating over your collections and using -filter comparing single values or relying on Where-Object, which does support all of the comparison operators.

    The Get-ADGroupMember and Remove-ADGroupMember -Members parameter supports arrays. If you create an array of users you want to add or remove, you can perform the add/remove with one command.

    $Descriptions =  @("Supporter","System Eng", "etc.","etc.")
    $group = Get-ADGroup "CN=testgroup,OU=Dirs,OU=Global,OU=group,OU=1,DC=test,DC=me,DC=nl"
    
    $UsersToAdd = Get-ADUser -Filter "MemberOf -ne '$($group.DistinguishedName)'" –SearchBase "OU=Int,OU=user,OU=1,DC=test,DC=me,DC=nl" -properties MemberOf,Description |
        where Description -in $Descriptions
    $UsersToRemove = Get-ADUser -Filter "MemberOf -eq '$($group.DistinguishedName)'" -properties MemberOf,Description |
        where Description -notin $Descriptions
    
    Add-ADGroupMember $group -Members $UsersToAdd
    Remove-ADGroupMember $group -Members $UsersToRemove
    

    The -Properties switch does allow you to selectively choose properties (in an array format for multiple properties and string format for a single property) you want to display. I would not recommend using * as that will increase the resource demand on your system during queries and data retrieval.

    Note: The solution assumes that your $Descriptions array contains the exact descriptions you expect to see on a user objects.


    If $Descriptions contains partial strings that you want to match against, you can opt for using the -match operator. Instead of an array, just create a single delimited (delimited by |) string.

    $Descriptions =  "Supporter|System Eng|etc\."
    $group = Get-ADGroup "CN=testgroup,OU=Dirs,OU=Global,OU=group,OU=1,DC=test,DC=me,DC=nl"
    
    $UsersToAdd = Get-ADUser -Filter "MemberOf -ne '$($group.DistinguishedName)'" –SearchBase "OU=Int,OU=user,OU=1,DC=test,DC=me,DC=nl" -properties MemberOf,Description |
        where Description -match $Descriptions
    $UsersToRemove = Get-ADUser -Filter "MemberOf -eq '$($group.DistinguishedName)'" -properties MemberOf,Description |
        where Description -notmatch $Descriptions
    
    Add-ADGroupMember $group -Members $UsersToAdd
    Remove-ADGroupMember $group -Members $UsersToRemove