Remove Forwarding Office 365 PowerShell
Scenario:
Remove Forwarding Office 365 PowerShell.
Exposure of data is a critical subject that you have to think about. A simple way to expose data from a company is to forward emails outside of the company. It is very difficult to decide whether to allow or block forwarding outside of the organization as it has a major impact on the business. As a security measure what you can do, is to try and limit the exposure on this. This depends also on the type of organization and if the business allows it. The below script deals with auto-forwarding of emails received by internal email accounts to external email accounts and runs every 1 hour.
Script runs on Azure Automation
The below script has been set up to run directly on Microsoft Azure. Microsoft Azure provides you with the ability to have scripts run directly on it. Under Azure automation you can have your runbooks. Runbooks can be a plain PowerShell script but also it allows you to create a runbook visually. In Azure automation credentials are saved in a secure way and can be retrieved from any runbook / script that you have configured. You can have multiple credentials saved and you are able to use any credentials that you may need in a script. When you run a script on Azure automation, a virtual environment is launched at the back-end there is no need to have a VM set up to run the scripts on it.
Details of script
First, the script retrieves the credentials that they are saved under Azure automation. Two different credentials are retrieved and saved in variables. The first one is the credentials of the user that will connect on Exchange Online (Office365) and perform the changes if needed on the mailboxes. The second credentials that are retrieved, are the ones that will be used to send the email report and / or the error report if there are any errors during the run. Please note that some times there is issue on Azure and script is not able to retrieve the credentials at all. In this case you may not receive any error email. You can this in Azure as it provide you history for each runbook if it was successful or not. After the credentials will be saved in variables, some other variables are defined that are used later for the emails.
You will find weird the next command but I found it very useful for me as sometimes the runbooks stuck and the next run on the scheduled fails if the same runbook is in that state. The only things it does is to check if there are and sessions opened and will close them so you will start fresh. The next four commands import the MSOnline module and Exchange session and then it connects to them so the commands will be available for our script.
Retrieve the mailboxes
At the next part we will try to find the mailboxes that apply to our filter. In general the mailboxes that will be retrieved, they have auto forwarding enabled outside of the organization. Let’s analyse out filter. If a mailbox is forwarded, the value that you will receive from the ForwardingSmtpAddress attribute will start with “smtp:”. So the first part of filtering is to find the mailboxes that the ForwardingSmtpAddress attribute is not null.
The next part of the filter is to exclude the mailboxes that forwarding has been set to internal domain or domains if you have more than one. Excluding the internal domains will allow you to keep auto forwarding of emails internally and not affect the business. After that, there is a small combination that we want to allow auto forwarding of emails. There is a possibility that you may want to allow a specific mailbox to auto forward email to a specific email address outside of the organization. So by defining the internal email address in combination with the external email address will exclude also the mailbox from the list.
The above filter will build the list of mailboxes that we do not want to have auto forwarding to external domains. If the list is not empty, the script will check each mailbox in the list to retrieve the forwarding address that has been set. The value will be saved in a variable to be used later in the email report. After that the script will clear the value and will fill the email variable to be sent.
Reporting
If there were any changes applied the the script will send a report with the changes. More specific, the report will include the mailbox that forwarding was enabled and removed and what was the email address it was forwarded to. If there were any errors during the run of the script, and the error variable is not empty then the script will send the error report to provide you with the errors and / or exceptions appeared.
You can download the script here or copy it from below.
Comment below and let me know your thoughts or anything else you would like to ask.
Related Links:
- Send Email using PowerShell
- Email error variable in PowerShell
- Credential assets in Azure Automation | Microsoft Docs
- Get-PSSession – Microsoft Docs
- Remove-PSSession – Microsoft Docs
- Import-Module – Microsoft Docs
- Connect-MsolService (MSOnline) | Microsoft Docs
- New-PSSession – Microsoft Docs
- Import-PSSession – Microsoft Docs
- Get-Mailbox – TechNet – Microsoft
- Set-Mailbox – TechNet – Microsoft
- Send-MailMessage – Microsoft Docs
- Get-Date – Microsoft Docs
Solution / Script:
$Credentials = Get-AutomationPSCredential -Name 'Script-User'
$EmailCredentials = Get-AutomationPSCredential -Name 'Email-Script-User'
$To = 'User1@domain.com','User2@domain.com'
$From = 'Email-Script-User@domain.com'
$EmailResult = ""
Get-PSSession | Remove-PSSession
Import-Module MSOnline
Connect-MsolService -Credential $Credentials
$Session = New-PSSession –ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credentials -Authentication Basic -AllowRedirection
Import-PSSession -Session $Session -DisableNameChecking:$true -AllowClobber:$true | Out-Null
$FWEnabled = Get-Mailbox -Filter {((ForwardingSmtpAddress -like "smtp:*") -and ((ForwardingSmtpAddress -notlike "*@domain.com") -and
(ForwardingSmtpAddress -notlike "*@internal-domain1.com") -and (ForwardingSmtpAddress -notlike "*@internal-domain2.com") -and
((UserPrincipalName -like "internal-user@domain.com") -and (ForwardingSmtpAddress -notlike "external-user@external-domain.com")) -and
(ForwardingSmtpAddress -notlike "*@internal-domain3.com")))} | select Name,Alias,ForwardingSmtpAddress
if ($FWEnabled -ne $null) {
$FWEnabledAlias = $FWEnabled.Alias
foreach ($User in $FWEnabledAlias) {
$FWAddress = (Get-Mailbox -Identity $User).ForwardingSmtpAddress
Set-Mailbox -Identity $User -ForwardingSmtpAddress $null
$EmailTemp = @"
<tr>
<td class="colorm">$User</td>
<td>$FWAddress</td>
</tr>
"@
$EmailResult = $EmailResult + "`r`n" + $EmailTemp
}
$EmailUp = @"
<style>
body { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; color:#434242;}
TABLE { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TR {border-width: 1px;padding: 10px;border-style: solid;border-color: white; }
TD {font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;padding: 10px;border-style: solid;border-color: white; background-color:#C3DDDB;}
.colorm {background-color:#58A09E; color:white;}
.colort{background-color:#58A09E; padding:20px; color:white; font-weight:bold;}
.colorn{background-color:transparent;}
</style>
<body>
<h3>Script has been completed successfully</h3>
<h4>Forwarding has been removed from the following accounts:</h4>
<table>
"@
$EmailDown = @"
</table>
</body>
"@
$Email = $EmailUp + $EmailResult + $EmailDown
send-mailmessage `
-To $To `
-Subject "AutoForwarding Removal Report $(Get-Date -format dd/MM/yyyy)" `
-Body $Email `
-BodyAsHtml `
-Priority high `
-UseSsl `
-Port 587 `
-SmtpServer 'smtp.office365.com' `
-From $From `
-Credential $EmailCredentials
}
if ($error -ne $null) {
foreach ($value in $error) {
$ErrorEmailTemp = @"
<tr>
<td class="colorm">$value</td>
</tr>
"@
$ErrorEmailResult = $ErrorEmailResult + "`r`n" + $ErrorEmailTemp
}
$ErrorEmailUp = @"
<style>
body { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; color:#434242;}
TABLE { font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TR {border-width: 1px;padding: 10px;border-style: solid;border-color: white; }
TD {font-family:Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif !important; border-width: 1px;padding: 10px;border-style: solid;border-color: white; background-color:#C3DDDB;}
.colorm {background-color:#58A09E; color:white;}
.colort{background-color:#58A09E; padding:20px; color:white; font-weight:bold;}
.colorn{background-color:transparent;}
</style>
<body>
<h3 style="color:#BD3337 !important;"> WARNING!!!</h3>
<p>There were errors during auto forwarding removal check</p>
<p>Please check the errors and act accordingly</p>
<table>
"@
$ErrorEmailDown = @"
</table>
</body>
"@
$ErrorEmail = $ErrorEmailUp + $ErrorEmailResult + $ErrorEmailDown
send-mailmessage `
-To $To `
-Subject "AutoForwarding Removal Report $(Get-Date -format dd/MM/yyyy) - WARNING" `
-Body $ErrorEmail `
-BodyAsHtml `
-Priority high `
-UseSsl `
-Port 587 `
-SmtpServer 'smtp.office365.com' `
-From $From `
-Credential $EmailCredentials
}
Leave a Reply