Powershell if condition returning no results when some exist

Viewed 29

The code block below executes without the CSV being generated suggesting it has no return. However the conditions given are definitely valid for at least one object.

A Mail Enabled Security group in O365 has the "SecurityEnabled" property set to true, the "MailEnabled" property set to true and the property "GroupTypes" is an empty array? string? "{}" whatever the curly brackets are supposed to represent but they're empty.

$Groups = Get-MgGroup -Property "Members" -All
foreach($group in $Groups){
    if ( (($group.SecurityEnabled) -and ($group.MailEnabled)) -and ($group.GroupTypes -ne 'Unified')){
        $members = Get-MgGroupMember -GroupId $group.Id
        [PSCustomObject]@{
            'Display Name' = $group.DisplayName
            'Members' = $members.AdditionalProperties.displayName -join ";"
        } | Export-Csv -path "$OutputFolder\MailEnabledSecurityGroups.csv" -Append -NoTypeInformation
    }
    continue
}
1 Answers

The GroupTypes property from the MicrosoftGraphGroup instance is an array, in this case you want to use containment operators, more specifically -notin or -notcontains, the condition would look like:

# with `-notcontains`
if ($group.SecurityEnabled -and $group.MailEnabled -and $group.GroupTypes -notcontains 'Unified') {

# with `-notin`
if ($group.SecurityEnabled -and $group.MailEnabled -and 'Unified' -notin $group.GroupTypes) {

As for why it was not working before, -ne and -eq can act as a filter when the LHS (left hand side) of the comparison is an array and because $group.GroupTypes was an empty array, the comparison returned null and the if condition evaluated to false because of this.

$obj = [pscustomobject]@{
    GroupTypes = @()
}
$obj.GroupTypes -ne 'Unified' # => null

$obj = [pscustomobject]@{
    GroupTypes = @('something else')
}
$obj.GroupTypes -ne 'Unified' # => something else

As aside, it's probably a better idea to export the output all at once instead of appending to the CSV file on each loop iteration (Disk I/O is expensive and will slow down your script a lot!):

Get-MgGroup -Property "Members" -All | ForEach-Object {
    if ($_.SecurityEnabled -and $_.MailEnabled -and 'Unified' -notin $_.GroupTypes) {
        $members = Get-MgGroupMember -GroupId $_.Id

        [PSCustomObject]@{
            'Display Name' = $_.DisplayName
            'Members'      = $members.AdditionalProperties.displayName -join ";"
        }
    }
} | Export-Csv -path "$OutputFolder\MailEnabledSecurityGroups.csv" -NoTypeInformation

Filtering on Azure side may increase the speed of your code and also reduce the amount of conditions being evaluated on client side:

Get-MgGroup -Property "Members" -Filter "securityEnabled eq true and mailenabled eq true" | ForEach-Object {
    if ('Unified' -notin $_.GroupTypes) {
        # code here
    }
}
Related