Search code examples
azurepowershellmicrosoft-graph-apimicrosoft-entra-id

Get-MgGroupMember by user search - need help on array match


I'm having a PowerShell syntax issue: I can't seem to match members of one array to another array, but I can confirm the members exist in both arrays. Can someone point out my logic error?

Background:

I want to search Entra for all members of a specific group, based on a search string of the member's properties (e.g. DisplayName and Surname). Given limitations to the Get-Mg* -filter calls, I've come up with this approach:

$groupName = 'staff'            # all results should be in staff group
$userMatchString = 'Be'         # e.g. [Be]n Smith, Jim [Be]am...
$domainMatch = 'example.com'    # custom domain - no Entra guests

## choose a central M365 group filter
$group = get-mggroup -Filter "DisplayName eq '$($groupName)'"
$groupMemberIds=Get-MgGroupMember -GroupId $group.id  -ConsistencyLevel eventual -All | select Id

## find Entra users matching a search string
## Due to graph filter limitations we do separate calls per attribute
$userMatches=@(Get-MgUser -ConsistencyLevel eventual -Count userCount -Filter "startsWith(DisplayName, '$($userMatchString)')" | where { $_.Mail -like "*@$($domainMatch)"})

$userMatches+=@(Get-MgUser -ConsistencyLevel eventual -Count userCount -Filter "startsWith(Surname, '$($userMatchString)')" | where { $_.Mail -like "*@$($domainMatch)" })

At this point $groupMemberIds contains every qualifiable person to search for and $userMatches contains every Entra search result (that may or may not be in the group).

This confirms (for my resultset) that the first record is already a match: $groupMemberIds | where { $_.Id -eq $userMatches[0].Id }

Can someone help me with syntax for (any userMatches ) in (groupMemberIds)?

This doesn't work - it returns 'false' for all of them: $userMatches | ForEach-Object { $($_.Id -in $groupMemberIds) }

Any ideas? Thanks!

UPDATE: With my code I'm apparently comparing string to PSCustomObject... trying to figure out how to compare these as apples to apples...

$userMatches[0].Id.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

$groupMemberIds[0].gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

Solution

  • In order to compare these apples to apples, I need to specify the .id property of the array members versus the array members themselves.

    This version with $groupMemberIds.id is returning matches, as it is now a String comparison:

    $userMatches | ForEach-Object {
        if ($_.Id -in $groupMemberIds.id) { 
            "{0} was found in {1}" -f  $_.DisplayName,$groupName 
            }
        }