SHELL/6.2.1.ps1

$CheckId = "6.2.1"
$Title = "Ensure all forms of mail forwarding are blocked and/or disabled"
$Level = "L1"
$BenchmarkType = "Automated"

function Get-RecipientAddressText {
    param([AllowNull()]$Recipient)

    if ($null -eq $Recipient) { return $null }

    if ($Recipient.PSObject.Properties.Match("Address").Count -gt 0 -and $Recipient.Address) {
        return [string]$Recipient.Address
    }

    return [string]$Recipient
}

function Get-DomainFromAddress {
    param([AllowNull()][string]$Address)

    if ([string]::IsNullOrWhiteSpace($Address)) { return $null }

    if ($Address -match "@(?<domain>[^>\s]+)$") {
        return $Matches.domain.Trim().ToLowerInvariant()
    }

    return $null
}

try {
    $AcceptedDomains = @(Get-AcceptedDomain -ErrorAction Stop | ForEach-Object {
        if ($_.DomainName) { [string]$_.DomainName } elseif ($_.Name) { [string]$_.Name } else { $null }
    } | Where-Object { $_ } | ForEach-Object { $_.ToLowerInvariant() } | Sort-Object -Unique)

    $RedirectRules = @(Get-TransportRule -ErrorAction Stop | Where-Object { $_.RedirectMessageTo -ne $null })

    $ExternalRedirects = @()
    foreach ($Rule in $RedirectRules) {
        $Recipients = @($Rule.RedirectMessageTo)
        foreach ($Recipient in $Recipients) {
            $Address = Get-RecipientAddressText -Recipient $Recipient
            $Domain = Get-DomainFromAddress -Address $Address

            if ($Domain -and ($AcceptedDomains -notcontains $Domain)) {
                $ExternalRedirects += [pscustomobject]@{
                    RuleName = $Rule.Name
                    RedirectAddress = $Address
                    RedirectDomain = $Domain
                }
            }
        }
    }

    $OutboundPolicies = @(Get-HostedOutboundSpamFilterPolicy -ErrorAction Stop)
    $NonCompliantOutboundPolicies = @($OutboundPolicies | Where-Object { [string]$_.AutoForwardingMode -ne "Off" })

    $NoExternalTransportRedirect = $ExternalRedirects.Count -eq 0
    $AllOutboundPoliciesOff = $NonCompliantOutboundPolicies.Count -eq 0

    $Pass = $NoExternalTransportRedirect -and $AllOutboundPoliciesOff
    $Status = if ($Pass) { "PASS" } else { "FAIL" }

    [pscustomobject]@{
        CheckId = $CheckId
        Title = $Title
        Level = $Level
        BenchmarkType = $BenchmarkType
        Status = $Status
        Pass = $Pass
        Evidence = [pscustomobject]@{
            AcceptedDomains = $AcceptedDomains
            RedirectRuleCount = $RedirectRules.Count
            ExternalRedirectCount = $ExternalRedirects.Count
            ExternalRedirectDetails = $ExternalRedirects
            OutboundPolicyCount = $OutboundPolicies.Count
            NonCompliantOutboundPolicyCount = $NonCompliantOutboundPolicies.Count
            NonCompliantOutboundPolicies = @($NonCompliantOutboundPolicies | Select-Object Name, AutoForwardingMode)
            SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
        }
        Error = if ($Pass) { $null } else { "External transport forwarding and/or outbound spam policy auto-forwarding settings are not compliant." }
        Timestamp = Get-Date
    }
}
catch {
    [pscustomobject]@{
        CheckId = $CheckId
        Title = $Title
        Level = $Level
        BenchmarkType = $BenchmarkType
        Status = "ERROR"
        Pass = $null
        Evidence = [pscustomobject]@{
            SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1"
        }
        Error = $_.Exception.Message
        Timestamp = Get-Date
    }
}