Private/Groups.SecurityDistribution.ps1

function Get-M365SnapshotSecurityAndDistributionGroups {
    param(
        [Parameter(Mandatory=$false)]
        [AllowNull()]
        [hashtable]$GraphHeaders,

        [Parameter(Mandatory=$true)]
        [object[]]$Groups,

        [Parameter(Mandatory=$true)]
        [ValidateRange(1, [int]::MaxValue)]
        [int]$EffectiveMaxSecurityDistributionGroups,

        [Parameter(Mandatory=$true)]
        [switch]$ReturnObjects
    )

    $securityGroups = @()
    $distributionGroups = @()

    function ConvertTo-BooleanValue {
        param([Parameter(Mandatory=$false)]$Value)

        if ($Value -is [bool]) {
            return [bool]$Value
        }

        if ($null -eq $Value) {
            return $false
        }

        $text = [string]$Value
        if ([string]::IsNullOrWhiteSpace($text)) {
            return $false
        }

        switch -Regex ($text.Trim().ToLowerInvariant()) {
            '^(true|1|yes|y)$' { return $true }
            '^(false|0|no|n)$' { return $false }
            default { return $false }
        }
    }

    try {
        foreach ($group in @($Groups)) {
            $groupTypesValue = $group.GroupTypes
            $groupTypes = @()
            if ($groupTypesValue -is [System.Collections.IEnumerable] -and -not ($groupTypesValue -is [string])) {
                $groupTypes = @($groupTypesValue | ForEach-Object { [string]$_ })
            }
            elseif ($null -ne $groupTypesValue) {
                $groupTypes = @(([string]$groupTypesValue) -split '[,;|]')
            }

            $isUnified = @($groupTypes | Where-Object { ([string]$_).Trim().ToLowerInvariant() -eq 'unified' }).Count -gt 0

            if ($isUnified) {
                continue
            }

            $isSecurityEnabled = ConvertTo-BooleanValue -Value $group.SecurityEnabled
            $isMailEnabled = ConvertTo-BooleanValue -Value $group.MailEnabled

            $groupRecord = [PSCustomObject]@{
                DisplayName = $group.DisplayName
                PrimarySmtpAddress = $group.PrimarySmtpAddress
                GroupId = $group.GroupId
                MailEnabled = $isMailEnabled
                SecurityEnabled = $isSecurityEnabled
                GroupTypes = $group.GroupTypes
                OwnerCount = if ($null -ne $group.OwnerCount) { [int]$group.OwnerCount } else { $null }
                SharingType = $group.SharingType
                Label = $group.Label
                Site = $group.Site
                MemberCount = if ($null -ne $group.MemberCount) { [int]$group.MemberCount } else { $null }
            }

            if ($isSecurityEnabled) {
                $securityGroups += $groupRecord
            }

            if ($isMailEnabled -and -not $isSecurityEnabled) {
                $distributionGroups += $groupRecord
            }
        }

        $securityGroups = @($securityGroups | Select-Object -First $EffectiveMaxSecurityDistributionGroups)
        $distributionGroups = @($distributionGroups | Select-Object -First $EffectiveMaxSecurityDistributionGroups)

        if (-not $ReturnObjects) {
            Write-Host "[OK] Found $($securityGroups.Count) security group(s) and $($distributionGroups.Count) distribution group(s)`n" -ForegroundColor Green
        }
    }
    catch {
        if (-not $ReturnObjects) {
            Write-Host "[WARNING] Could not classify security/distribution groups: $($_.Exception.Message)`n" -ForegroundColor Yellow
        }
    }

    return [PSCustomObject]@{
        SecurityGroups = @($securityGroups)
        DistributionGroups = @($distributionGroups)
    }
}