Find external forwarding mailboxes in all Office 365 customer tenants with PowerShell

Find External Forwarding Mailboxes in all Office 365 Customer tenants


Hackers and rogue employees can set Office 365 accounts to automatically forward all received email outside of the company. If you’re looking after the security of a number of Office 365 tenants as a Microsoft Partner, it can be difficult to find external forwarding mailboxes in your customer tenants.

This script will help you identify any mailboxes that are forwarding mail externally. It works by connecting to Office 365 using your delegated administrator credentials, then connecting to the Exchange Online organisation for each of your customers. It’ll check the ForwardingSmtpAddress value on each mailbox in the organisation, and if it’s sending to a domain that isn’t included in that company’s accepted domains, it’ll export the details to a CSV.

You can use this script to find out whether there are any breached accounts in your customers’ Office 365 environments.

To keep track of these types of forwarders in future, I recommend following this guide to set up a monitoring solution.

How to check for external forwarding mailboxes in all Office 365 customer tenants with PowerShell.

  1. Ensure that you can run this script with an MFA enabled account by whitelisting your current static IP. You can do this temporarily if you like.
  2. Double click to select, then copy and paste the script below into Visual Studio Code.
  3. Save it as a PowerShell (.ps1) file
  4. Press F5 to run it.
  5. Enter the credentials of an Office 365 administrator with delegated access to your customer tenants. Note that this script doesn’t support multi-factor authentication.
  6. Wait for it to complete.external forwarding mailboxes
  7. Check the CSV output at C:\temp\customerExternalForward.csvExternal forwarding mailbox csv

PowerShell Script to check for external forwarding mailboxes in all Office 365 Customer tenants

$credential = Get-Credential
Connect-MsolService -Credential $credential
$customers = Get-msolpartnercontract
foreach ($customer in $customers) {

    $InitialDomain = Get-MsolDomain -TenantId $customer.TenantId | Where-Object {$_.IsInitial -eq $true}
    Write-Host "Checking $($customer.Name)"
    $DelegatedOrgURL = "" + $InitialDomain.Name
    $s = New-PSSession -ConnectionUri $DelegatedOrgURL -Credential $credential -Authentication Basic -ConfigurationName Microsoft.Exchange -AllowRedirection
    Import-PSSession $s -CommandName Get-Mailbox, Get-AcceptedDomain -AllowClobber
    $mailboxes = $null
    $mailboxes = Get-Mailbox -ResultSize Unlimited
    $domains = Get-AcceptedDomain

    foreach ($mailbox in $mailboxes) {

        $forwardingSMTPAddress = $null
        Write-Host "Checking forwarding for $($mailbox.displayname) - $($mailbox.primarysmtpaddress)"
        $forwardingSMTPAddress = $mailbox.forwardingsmtpaddress
        $externalRecipient = $null
                $email = ($forwardingSMTPAddress -split "SMTP:")[1]
                $domain = ($email -split "@")[1]
                if ($domains.DomainName -notcontains $domain) {
                    $externalRecipient = $email

            if ($externalRecipient) {
                Write-Host "$($mailbox.displayname) - $($mailbox.primarysmtpaddress) forwards to $externalRecipient" -ForegroundColor Yellow

                $forwardHash = $null
                $forwardHash = [ordered]@{
                    Customer           = $customer.Name
                    TenantId           = $customer.TenantId
                    PrimarySmtpAddress = $mailbox.PrimarySmtpAddress
                    DisplayName        = $mailbox.DisplayName
                    ExternalRecipient  = $externalRecipient
                $ruleObject = New-Object PSObject -Property $forwardHash
                $ruleObject | Export-Csv C:\temp\customerExternalForward.csv -NoTypeInformation -Append

Was this article helpful?

Related Articles

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *