Checks/Teams/MET-Teams006-ExternalAccess.ps1

$issues = [System.Collections.Generic.List[string]]::new()

# Check Teams federation (external access) allow-list scope
try {
    $config = Get-CsTenantFederationConfiguration -ErrorAction Stop

    $allowedDomainsValue = $config.AllowedDomains
    $isAllowAllKnownDomains = $false
    if ($allowedDomainsValue -eq 'AllowAllKnownDomains') {
        $isAllowAllKnownDomains = $true
    }
    elseif ($allowedDomainsValue -and $allowedDomainsValue.ToString() -eq 'AllowAllKnownDomains') {
        $isAllowAllKnownDomains = $true
    }

    if ($config.AllowFederatedUsers -eq $true -and $isAllowAllKnownDomains) {
        $issues.Add('Federation is open to all external domains (AllowAllKnownDomains) - any external Teams user can attempt to chat with your staff, a common vector for Teams-based phishing and vishing')
    }

    if ($config.AllowTeamsConsumer -eq $true) {
        $inboundOpen = $config.AllowTeamsConsumerInbound -ne $false
        if ($inboundOpen) {
            $issues.Add('Teams accounts not managed by any organization (consumer/personal accounts) are allowed to federate, and AllowTeamsConsumerInbound is enabled - unmanaged personal accounts can discover and initiate first contact with your staff, the higher-risk direction for Teams-based phishing and vishing')
        }
        else {
            $issues.Add('Teams accounts not managed by any organization (consumer/personal accounts) are allowed to federate, but AllowTeamsConsumerInbound is disabled - this is partially mitigated: personal/consumer accounts cannot discover or initiate contact with your staff, only your staff can start a conversation outbound')
        }

        $restrictProperty = $config.PSObject.Properties['RestrictTeamsConsumerToExternalUserProfiles']
        if ($restrictProperty -and $config.RestrictTeamsConsumerToExternalUserProfiles -eq $true) {
            $issues.Add('RestrictTeamsConsumerToExternalUserProfiles is enabled, further limiting consumer/personal account interaction to users in the Extended Directory external user profiles rather than any arbitrary personal account')
        }
    }

    if ($config.AllowFederatedUsers -eq $true -and -not $config.BlockedDomains) {
        $issues.Add('No explicit BlockedDomains deny-list is configured - there is no domain-level backstop in place as a defense-in-depth measure if the allow-list scope is ever widened')
    }
}
catch {
    $issues.Add("Could not retrieve tenant federation configuration: $($_.Exception.Message)")
    Write-Verbose "Could not retrieve tenant federation configuration: $_"
}

if ($issues.Count -gt 0) {
    $result = if ($issues | Where-Object { $_ -match 'AllowAllKnownDomains' }) { 'Fail' } else { 'Warning' }
    New-METCheckResult -CheckId 'MET-Teams006' -Category Teams -Name 'External Access / Federation Allow-List' `
        -Result $result -Severity High -AffectedObject 'Teams External Access Configuration' `
        -Finding ($issues -join '; ') `
        -Recommendation 'Restrict AllowedDomains to a specific, reviewed allow-list of trusted partner domains instead of AllowAllKnownDomains, and configure a BlockedDomains deny-list as a defense-in-depth backstop. Disable AllowTeamsConsumer unless there is a specific business need for staff to chat with personal Teams/Skype accounts; if it must stay enabled, run Set-CsTenantFederationConfiguration -AllowTeamsConsumerInbound $false so personal/consumer accounts cannot discover or initiate contact with your organization, and consider -RestrictTeamsConsumerToExternalUserProfiles $true to further narrow exposure. Run: Set-CsTenantFederationConfiguration -AllowedDomains <AllowedDomainsObject> to scope federation, or -AllowFederatedUsers $false to disable entirely.' `
        -ReferenceUrl 'https://learn.microsoft.com/en-us/powershell/module/microsoftteams/set-cstenantfederationconfiguration'
}
else {
    New-METCheckResult -CheckId 'MET-Teams006' -Category Teams -Name 'External Access / Federation Allow-List' `
        -Result Pass -Severity High -AffectedObject 'Teams External Access Configuration' `
        -Finding 'Teams external access (federation) is appropriately scoped' `
        -ReferenceUrl 'https://learn.microsoft.com/en-us/powershell/module/microsoftteams/set-cstenantfederationconfiguration'
}