PS loop not finding string in array?

Hey all, I’m looking at writing some scripts to clean up distribution lists in our Exchange environment.

My script:

# Groups in AD that we're working on-
$exceptionsList=import-csv $exceptionsPath
$allStaffFacultyAdjuncts=foreach ($group in $Affiliations) { Get-ADGroupMember $group }

foreach ($user in $allStaffFacultyAdjuncts)
    $dsgot=dsget user $userDN -memberof
    if ($exceptionsList.Name -contains "$userN")
        write-host Bypassing $userN
    elseif ($dsgot -contains "Staff")
        write-host $userN is in the Staff group.

Some relevant data as returned from pieces of the script:

$dsgot=dsget user $userDN -memberof

$userDN : CN=ben,ou=staff,ou=accounts,dc=domain,dc=int
$dsgot : “CN=TestUsers,OU=Groups,OU=accounts,DC=domain,DC=int”
“CN=Domain Users,CN=Users,DC=domain,DC=int”

My exceptions list works fine. The problem is where my script is trying to determine which groups a user is a member of. The script appears to successfully get the user’s DN, and uses dsget to pull the group information (returned DN LDAP values with quotes). My loop in PS where it checks $dsgot if it contains “Staff” doesn’t ever catch anything. My value of $dsgot is an array if I’m not mistaken since most users are in more than one group- how do I parse an array in such a way so that my loop can “see” a value somewhere within it to trigger it?

Try use the -match comparison operator instead, like this:

elseif ($dsgot -match "Staff")

Should work with your example :slight_smile:

For more info please see:

Best regards

Hi Ben,

The external “dsget” tool will not return an array but plain text with line breaks. That is why your -contains condition does not work.

One of the many PowerShell best practices is to use cmdlets if available instead of command line tools like “dsget” because the cmdlets return rich objects instead of plain text. In your case you’re already using the Get-ADGroupMember cmdlet from the ActiveDirectory Module. This module also contains a cmdlet called Get-ADUser which is perfect for getting an array of distinguished names of groups.

Example of using Get-ADUser to get the group membership:

$GroupDNs = Get-ADUser -Identity $user.distinguishedName -Property MemberOf

Even better instead of doing the work twice like in your script would be to use the objects returned by your Get-ADGroupMember call that already contain the necessary information to match against your exception list.

Here is an example function which I’ve created based on your script. It returns custom object to the pipeline which hold the group and user objects to process further.

Function Get-InvalidGroupMembers
        [Parameter(Mandatory = $true)]

        [Parameter(Mandatory = $true)]

    # Get members of each group and output a custom object to the pipeline with group and user details
    $GroupName | ForEach-Object -Process {
        foreach ($GroupMember in Get-ADGroupMember -Identity $_)
            if (($GroupMember.objectClass -eq 'user') -and
                ($ExceptionList.Name -notcontains $GroupMember.Name))
                Write-Output -InputObject [pscustomobject]@{ Group = $Group; User = $GroupMember }

$ExceptionList = Import-Csv -Path 'C:\Temp\FacStfexceptions.csv'
$Results = Get-InvalidGroupMembers -GroupName @('Staff','Faculty') -ExceptionList $ExceptionList

I hope above helps.


The issue is that $dsgot is an array of distinguished names and you need to see if it contains the distinguished name for the staff group including the quote marks because of the way dsget returns the results:

elseif ($dsgot -contains '"CN=Staff,OU=Groups,OU=accounts,DC=domain,DC=int"')

Using the -match operator, at least the way the previous poster is using it will return false positives if the user is in a group that contains the word “Staff” anywhere in the distinguished names such as a group named test in an OU named Staff.

Also note that the way the script is written, if a user is a member of both the Staff and Faulty group and not contained in the CSV, they will be in the results twice.

You could also accomplish your task with a couple of lines of PowerShell and eliminate a lot of the complexity:

$exceptionsList = Import-Csv -Path 'C:\temp\FacStfexceptions.csv'
'Staff','Faculty' | Get-ADGroupMember | Get-ADUser | Where {$ -notcontains $_.Name} | Select-Object -Property Name -Unique

I’m not sure what version of PowerShell you’re using so I’ve written this to be compatible with version 2.0 or higher.

Actually, you could even eliminate the Get-ADUser portion since Get-ADGroupMember returns their name:

$exceptionsList = Import-Csv -Path 'C:\temp\FacStfexceptions.csv'
'Staff','Faculty' | Get-ADGroupMember | Where {$ -notcontains $_.Name} | Select-Object -Property Name -Unique