0

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.

TrixD
  • 7
  • 2

2 Answers2

0

It's more about LDAP than PowerShell. LDAP queries cannot accept an array. If you want the equivalent of "description is one of these", then you will need to end up with something like this:

(|(description=Supporter)(description=System Eng)(description=etc.))

Notice the | for "OR".

To do that from your array, you can use the -join operator:

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

About your code to add a user: it works, but the -like is unnecessary since your matching string doesn't have any wildcards. You can use -eq instead, which will save a little processing power. You may not even notice it though.

Where-Object {$_.Description -eq $Description}
Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • First of all Thanks The Problem is i have over 50 Descriptions i have to check so the first idea is a little bit unwieldy. I change the -eq thanks for reminding me :). Also the join statement worked thank you very much. – TrixD Oct 17 '19 at 13:31
0

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
AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
  • Thank you for your answer, I also tried this one and it works aswell, also it is way more compact. – TrixD Oct 17 '19 at 13:49