# FindAccountsWithForwarding.PS1 # Script to find accounts with mail forwarding addresses enanled or with rules to forward messages # https://github.com/12Knocksinna/Office365itpros/blob/master/FindAccountsWithForwarding.PS1 # Check that the right modules are loaded [array]$Modules = Get-Module If ("ExchangeOnlineManagement" -notin $Modules.Name) { Connect-ExchangeOnline -ShowBanner:$False -ErrorAction Stop } Write-Host "Finding user and shared mailboxes..." [array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox, SharedMailbox -Properties ForwardingSmtpAddress -ResultSize Unlimited If (!$Mbx) { Write-Host "No user or shared mailboxes found!" -ForegroundColor Yellow Break } Else { Write-Host ("{0} user and shared mailboxes found" -f $Mbx.Count) -ForegroundColor Green } $Report = [System.Collections.Generic.List[Object]]::new() Clear-Host; $MbxNumber = 0 ForEach ($M in $Mbx) { $MbxNumber++ $ProgressBar = "Checking mailbox " + $M.DisplayName + " (" + $MbxNumber + " of " + $Mbx.Count + ")" Write-Progress -Activity "Looking for forwarding settings and inbox rules" -Status $ProgressBar -PercentComplete ($MbxNumber/$Mbx.Count*100) $Rule = $Null If ($null -ne $M.ForwardingSmtpAddress) { # Mailbox has a forwarding address $ReportLine = [PSCustomObject]@{ Mailbox = $M.DisplayName UPN = $M.UserPrincipalName "Mailbox type" = $M.RecipientTypeDetails ForwardingAddress = $M.ForwardingSmtpAddress.Split(":")[1] InboxRule = "N/A" "Rule Removed" = "N/A" Enabled = "N/A"} $Report.Add($ReportLine) } [array]$InboxRules = (Get-InboxRule -Mailbox $M.ExternalDirectoryObjectId | Where-Object {$_.ForwardTo -or $_.ForwardAsAttachmentTo -or $_.RedirectTo}) If ($null -ne $InboxRules) { Write-Host "Processing inbox rules" ForEach ($Rule in $InboxRules) { $Ex = $null $ForwardTo = @() $ForwardTo = ($Rule.ForwardTo | Where-Object { ($_ -Match "SMTP") -or ($_ -Match "EX:") } ) $ForwardTo += ($Rule.ForwardAsAttachmentTo | Where-Object {($_ -Match "SMTP") -or ($_ -Match "EX:")}) $ForwardTo += ($Rule.RedirectTo | Where-Object {($_ -Match "SMTP") -or ($_ -Match "EX:")}) If ($ForwardTo.Count -gt 0) { ForEach ($Recipient in $ForwardTo) { If ($Recipient -Match "EX:") { # Recipient known in Exchange directory $Ex = (Get-Recipient -Identity ($Recipient-Split "Ex:")[1].trim("]}")) $EmailAddress = $Ex.PrimarySmtpAddress } Else { # Simple SMTP address $EmailAddress = ($Recipient -Split "SMTP:")[1].Trim("]") $Ex = (Get-Recipient -Identity $EmailAddress) } } Write-Host $M.RecipientTypeDetails $M.DisplayName "has a rule to forward email to" $EmailAddress -ForegroundColor Red # Remove the rule if the address is unknown to the directory If ($null -eq $Ex) { Remove-InboxRule -Identity $Rule.Identity -Confirm:$False; $RuleRemoved = "Yes" Write-Host "Rule" $Rule.Name "removed from mailbox!" } Else { Write-Host "Destination is known to the tenant directory. Please remove" $Rule.Name "manually if necessary"; $RuleRemoved = "No" } $ReportLine = [PSCustomObject]@{ Mailbox = $M.DisplayName UPN = $M.UserPrincipalName "Mailbox type" = $M.RecipientTypeDetails ForwardingAddress = $EmailAddress InboxRule = $Rule.Name "Rule Removed" = $RuleRemoved Enabled = $Rule.Enabled} $Report.Add($ReportLine) } } } } [array]$InboxRulesFound = $Report | Where-Object {$_.InboxRule -ne "N/A"} [array]$MailForwarding = $Report | Where-Object {$_.InboxRule -eq "N/A"} $MailboxesWithRules = $InboxRulesFound.Mailbox -join ", " $MailboxesForwarding = $Mailforwarding.Mailbox -join ", " Write-Host ("{0} mailboxes found with forwarding addresses: {1}; {2} mailboxes found with forwarding inbox rules: {3}" -f $MailForwarding.Count, $MailboxesForwarding, $InboxRulesFound.Count, $MailboxesWithRules) # An example script used to illustrate a concept. More information about the topic can be found in the Office 365 for IT Pros eBook https://gum.co/O365IT/ # and/or a relevant article on https://office365itpros.com or https://www.pratical365.com. See our post about the Office 365 for IT Pros repository # https://office365itpros.com/office-365-github-repository/ for information about the scripts we write. # Do not use our scripts in production until you are satisfied that the code meets the need of your organization. Never run any code downloaded from the Internet without # first validating the code in a non-production environment.