Src/Private/Get-AbrExoConnectors.ps1

function Get-AbrExoConnectors {
    <#
    .SYNOPSIS
    Documents Exchange Online inbound and outbound mail flow connectors with ACSC E8 and CIS compliance assessments.
    .NOTES
        Version: 0.1.0
        Author: Pai Wei Sing
    #>

    [CmdletBinding()]
    param (
        [Parameter(Position = 0, Mandatory)]
        [string]$TenantId
    )

    begin {
        Write-PScriboMessage -Message "Collecting Exchange Online Connectors for $TenantId."
        Show-AbrDebugExecutionTime -Start -TitleMessage 'Connectors'
    }

    process {
        Section -Style Heading2 'Connectors' {
            Paragraph "The following section documents inbound and outbound mail flow connectors configured for tenant $TenantId."
            BlankLine

            $InboundConnectorNoTlsCount  = 0
            $OutboundConnectorNoTlsCount = 0

            #region Inbound Connectors
            try {
                Write-Host " - Retrieving inbound connectors..."
                $InboundConnectors = Get-InboundConnector -ErrorAction Stop | Sort-Object Name

                if ($InboundConnectors) {
                    Section -Style Heading3 'Inbound Connectors' {
                        Paragraph "The following $(@($InboundConnectors).Count) inbound connector(s) are configured in tenant $TenantId."
                        BlankLine

                        $InObj = [System.Collections.ArrayList]::new()
                        foreach ($Conn in $InboundConnectors) {
                            $RequiresTls   = $Conn.RequireTls -eq $true
                            if (-not $RequiresTls) { $InboundConnectorNoTlsCount++ }

                            $inConnInObj = [ordered] @{
                                'Connector Name'          = $Conn.Name
                                'Enabled'                 = $Conn.Enabled
                                'Connector Type'          = $Conn.ConnectorType
                                'Sender Domains'          = ($Conn.SenderDomains -join ', ')
                                'Sender IP Ranges'        = if ($Conn.SenderIPAddresses) { ($Conn.SenderIPAddresses -join ', ') } else { 'Not Set' }
                                'Require TLS'             = $RequiresTls
                                'TLS Sender Certificate'  = if ($Conn.TlsSenderCertificateName) { $Conn.TlsSenderCertificateName } else { 'Not Set' }
                                'Validate Cert'           = $Conn.CloudServicesMailEnabled
                                'Restrict to IP'          = if ($Conn.RestrictDomainsToCertificate) { 'Yes' } else { 'No' }
                                'EOP Enabled'             = $Conn.EFSkipIPs
                            }
                            $InObj.Add([pscustomobject](ConvertTo-HashToYN $inConnInObj)) | Out-Null
                        }

                        $null = (& {
                            if ($HealthCheck.ExchangeOnline.Connectors) {
                                $null = ($InObj | Where-Object { $_.'Require TLS' -eq 'No' } | Set-Style -Style Warning | Out-Null)
                                $null = ($InObj | Where-Object { $_.'Enabled' -eq 'No' } | Set-Style -Style Warning | Out-Null)
                            }
                        })

                        $InTableParams = @{ Name = "Inbound Connectors - $TenantId"; List = $false; ColumnWidths = 14, 7, 9, 14, 14, 8, 14, 7, 7, 6 }
                        if ($Report.ShowTableCaptions) { $InTableParams['Caption'] = "- $($InTableParams.Name)" }
                        $InObj | Table @InTableParams

                        $script:ExcelSheets['Inbound Connectors'] = $InObj
                    }
                } else {
                    Paragraph "No inbound connectors are configured in tenant $TenantId. All inbound mail flows via Exchange Online Protection defaults."
                }
            } catch {
                Write-ExoError 'Connectors' "Unable to retrieve inbound connectors: $($_.Exception.Message)"
                Paragraph "Unable to retrieve inbound connector data."
            }
            #endregion

            #region Outbound Connectors
            try {
                Write-Host " - Retrieving outbound connectors..."
                $OutboundConnectors = Get-OutboundConnector -ErrorAction Stop | Sort-Object Name

                if ($OutboundConnectors) {
                    Section -Style Heading3 'Outbound Connectors' {
                        Paragraph "The following $(@($OutboundConnectors).Count) outbound connector(s) are configured in tenant $TenantId."
                        BlankLine

                        $OutObj = [System.Collections.ArrayList]::new()
                        foreach ($Conn in $OutboundConnectors) {
                            $HasTls = $Conn.TlsSettings -in @('EncryptionOnly', 'CertificateValidation', 'DomainValidation')
                            if (-not $HasTls) { $OutboundConnectorNoTlsCount++ }

                            $outConnInObj = [ordered] @{
                                'Connector Name'       = $Conn.Name
                                'Enabled'              = $Conn.Enabled
                                'Connector Type'       = $Conn.ConnectorType
                                'Recipient Domains'    = if ($Conn.RecipientDomains) { ($Conn.RecipientDomains -join ', ') } else { 'All Domains' }
                                'Smart Hosts'          = if ($Conn.SmartHosts) { ($Conn.SmartHosts -join ', ') } else { 'None (MX)' }
                                'TLS Settings'         = if ($Conn.TlsSettings) { $Conn.TlsSettings } else { 'None' }
                                'TLS Domain'           = if ($Conn.TlsDomain) { $Conn.TlsDomain } else { 'Not Set' }
                                'Use MX Record'        = $Conn.UseMXRecord
                                'Route All Mail'       = $Conn.RouteAllMessagesViaOnPremises
                                'Cloud Services Mail'  = $Conn.CloudServicesMailEnabled
                            }
                            $OutObj.Add([pscustomobject](ConvertTo-HashToYN $outConnInObj)) | Out-Null
                        }

                        $null = (& {
                            if ($HealthCheck.ExchangeOnline.Connectors) {
                                $null = ($OutObj | Where-Object { $_.'TLS Settings' -eq 'None' } | Set-Style -Style Warning | Out-Null)
                                $null = ($OutObj | Where-Object { $_.'Enabled' -eq 'No' } | Set-Style -Style Warning | Out-Null)
                            }
                        })

                        $OutTableParams = @{ Name = "Outbound Connectors - $TenantId"; List = $false; ColumnWidths = 14, 7, 9, 14, 13, 12, 10, 7, 7, 7 }
                        if ($Report.ShowTableCaptions) { $OutTableParams['Caption'] = "- $($OutTableParams.Name)" }
                        $OutObj | Table @OutTableParams

                        $script:ExcelSheets['Outbound Connectors'] = $OutObj
                    }
                } else {
                    Paragraph "No outbound connectors are configured in tenant $TenantId. All outbound mail flows via Exchange Online Protection defaults (direct MX delivery)."
                }
            } catch {
                Write-ExoError 'Connectors' "Unable to retrieve outbound connectors: $($_.Exception.Message)"
                Paragraph "Unable to retrieve outbound connector data."
            }
            #endregion


            BlankLine
            Paragraph "ACSC Essential Eight Assessment"
            BlankLine
            $e8Vars = @{
                InboundConnectorNoTlsCount  = $InboundConnectorNoTlsCount
                OutboundConnectorNoTlsCount = $OutboundConnectorNoTlsCount
            }
            $e8Checks = Build-AbrExoComplianceChecks -Definitions (Get-AbrExoE8Checks 'Connectors') -Framework 'E8' -CallerVariables $e8Vars
            New-AbrExoE8AssessmentTable -Checks $e8Checks -Name 'Connectors' -TenantId $TenantId
            if ($e8Checks) {
                foreach ($row in $e8Checks) {
                    $null = $script:E8AllChecks.Add([pscustomobject]@{
                        Section = 'Connectors'
                        ML      = $row.ML
                        Control = $row.Control
                        Status  = $row.Status
                        Detail  = $row.Detail
                    })
                }
            }
        }

    }



    end {

        Show-AbrDebugExecutionTime -End -TitleMessage 'Connectors'

    }

}