How To Get Mailbox Forwarding Rules With Powershell in Exchange Online

Mailbox forwarding rules in Exchange Online can be especially damaging if messages are being forwarding outside of your organisation. It is important you have visibility over your users mailboxes to ensure there are no forwarding rules in place. It is also common that you would want to know how to check for forwarding rules after a user account has been breached in Microsoft 365.

Auto-forwarding can however have its use cases, but in most environments it can be disabled by default to prevent any data loss. It is often used by malicious actors once they have access to your mailbox to manipulate conversations and engineer users to give away important information or transfer funds to malicious accounts.

It is important that if you do not already have security defaults enabled in your tenant you consider turning it on. Read my how-to guide here.

In this post we are going to look at how we can use PowerShell to check for forwarding mailboxes rules across all of our users in Exchange Online.

How to check for mailbox rules that forward mail in your Microsoft 365 tenant

  • Start by connecting to Exchange Online. You will be prompted for your login details.

Connect-ExchangeOnline

Connect-ExchangeOnline
  • If mailbox forwarding has been enabled by the user from OWA > Settings > View all Outlook settings > Forwarding, then use the following command to view all users with forwarding enabled.

Get-Mailbox | Where {$null -ne $_.ForwardingSmtpAddress} | FT UserPrincipalName,ForwardingSmtpAddress,DeliverToMailboxAndForward

Get-Mailbox | Where {$null -ne $_.ForwardingSmtpAddress} | FT UserPrincipalName,ForwardingSmtpAddress,DeliverToMailboxAndForward 

You will see a result like the following.

Get mailbox forwarding results
  • If you want to see which mailboxes have mailbox rules configured to forward emails, you can run the following.

$Mailboxes = Get-Mailbox -ResultSize unlimited | where {$_.RecipientTypeDetails -eq “UserMailbox”}

foreach ($Mailbox in $Mailboxes)
{
Get-InboxRule -mailbox $Mailbox.Name | Where-object {$_.forwardto -or $_.forwardasattachmentto} | fl mailboxownerid,name,description
}

$Mailboxes = Get-Mailbox -ResultSize unlimited  | where {$_.RecipientTypeDetails -eq "UserMailbox"}

foreach ($Mailbox in $Mailboxes)
	{
Get-InboxRule -mailbox $Mailbox.Name | Where-object {$_.forwardto -or $_.forwardasattachmentto} | fl mailboxownerid,name,description
}

You will see a result like the following.

external forward example

Daniel Bradley

My name is Daniel Bradley and I work with Microsoft 365 and Azure as an Engineer and Consultant. I enjoy writing technical content for you and engaging with the community. All opinions are my own.

This Post Has 5 Comments

  1. Aaron

    Thanks Daniel, this script looks really good. What if you wanted to export these results to a text file with the name of the file being the users email address?

    1. Daniel Bradley

      Hi Aaron,

      Depends how you want the files to be exported. But if you wanted a .txt for each user, you could do something like:

      foreach ($Mailbox in $Mailboxes) {
      $rules = $null
      Write-Host "Exporting rules for $mailbox" -ForegroundColor Cyan
      $rules = Get-InboxRule -mailbox $Mailbox.Name | Where-object {$_.forwardto -or $_.forwardasattachmentto} | fl mailboxownerid,name,description
      $rules | Out-File "C:\temp\($mailbox)_Rules.txt"
      }

  2. Aaron

    Thanks Daniel for your response, I really appreciate it. I do want a txt file for each user, but I was hoping to name each txt file as the users email address. For example [email protected]. To do this I think you would need to use PrimarySmtpAddress property from get-mailbox. Is that possible to do? Thanks for your help.

  3. Aaron

    I was able to get this working with the script below. It seems inefficient though. Thanks for your help.
    $mailboxes = get-mailbox | select userprincipalname
    foreach ($Mailbox in $Mailboxes){
    $path = “C:\temp\$(($mailbox | select userprincipalname).userprincipalname).txt”
    Get-InboxRule -mailbox $(($mailbox | select userprincipalname).userprincipalname) | fl Name,Description > $path
    }

  4. Hipinkx

    Thanks for your help Daniel !

    Because the query could be long, i’ve juste make some change to have a beter tracking when you use it with bulks mailboxes

    $Mailboxes = Get-Mailbox -ResultSize unlimited | where {$_.RecipientTypeDetails -eq “UserMailbox”}

    $array = @()
    $array.Clear()

    foreach ($Mailbox in $Mailboxes){
    Write-Host “Checking Mailbox” $Mailbox -ForegroundColor Yellow
    $ExtFwd = Get-InboxRule -mailbox $Mailbox.Name | Where-object {$_.forwardto -or $_.forwardasattachmentto} | fl mailboxownerid,name,description
    $array += $ExtFwd
    }

    $array

    Cheers

Leave a Reply