Microsoft 365 – Exchange – Function to Get Transport Rule Properties using PowerShell
In this blog I will share one way to write a function to get all or specific properties of an Exchange Online transport (mail flow) rule using PowerShell. I will also show how a function can accept pipeline input “|”.
My blogs have relatively simple, and sometimes complex, examples and I’m hoping that you will be able to tailor them to your need or use them in your own scripts.
Introduction
On multiple occasions I needed to get selected properties of an Exchange Online transport rule. So, I decided to write a function and add it to my PowerShell library.
The goal of this blog is to show one way to accomplish a task. It is not to show how to write a perfect script, the perfect solution to a challenge or the perfect process to accomplish a task.
Prerequisites
- Install Azure PowerShell if you haven’t already. You can use Cloud Shell if you prefer to stay within Azure Portal.
- Install Install the EXO V2 module if you haven’t already. You can use Cloud Shell if you prefer to stay within Azure Portal.
PowerShell Cmdlets
- Connect-ExchangeOnline Used in the Exchange Online PowerShell V2 module to connect to Exchange Online PowerShell using modern authentication. This cmdlet works for MFA or non-MFA enabled accounts.
- Get-TransportRule Use to view transport rules (mail flow rules) in your organization.
Connect to Exchange Online
Use Connect-ExchangeOnline to connect to Exchange Online.
Get a transport (mail flow) rule properties
In its simplest form, Get-TransportRule:
1 2 3 4 5 |
$RuleName = "External Emails Notice" $Rule = Get-TransportRule $RuleName $Rule | Select * | Format-List # Or $Rule | Select ExceptIfSenderDomainIs, SentToMemberOf, FromScope |
Why a function is needed
- to connect to Exchange Online if a connection is not yet established.
- to stop and display a single line error message if the transport rule does not exist.
- to accept pipeline input.
- to add the code to a library to be loaded at PowerShell startup.
- other reasons that I already forgot.
Let us have fun and start writing our function.
Our Get-TransportRulePropertiesS function
Set up function parameters including pipeline input
The function will have two parameters: (1) transport rule name and (2) properties to be selected.
1 2 3 4 5 6 7 |
[CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Enter rule name")] [String] $RuleName, [Parameter(Mandatory=$true, ValueFromPipeline, HelpMessage="What part of the rule to update, e.g. From, ExceptIfSenderDomainIs, etc.")] [String] $Properties ) |
Next connect to Exchange Online if a connection is not established
1 2 3 |
$GetSessions = Get-PSSession | Select-Object -Property State, Name $IsConnected = (@($GetSessions) -like '@{State=Opened; Name=ExchangeOnlineInternalSession*').Count -gt 0 If ($IsConnected -ne "True") { Connect-ExchangeOnline } |
And display an error message if the transport rule does not exist then stop
1 2 3 4 5 |
$Rule = Get-TransportRule $RuleName -ErrorAction SilentlyContinue If ($Rule -eq $null) { Write-Host -ForegroundColor Red "`nRule [$RuleName] does not exist" Break } |
Finally, get the required properties
I used a string variable to store properties to selected to make it easy to use for pipeline and parameter input. You may like to choose a different approach in your function.
I also chose to display each property by itself. You may like to choose a different approach in your function.
1 2 3 4 5 6 |
$Properties = "ExceptIfSenderDomainIs,SentToMemberOf,FromScope" $PropertiesA = $Properties.Split(',') ForEach ($Property in $PropertiesA) { Write-Host "`n*** $Property" $Rule.($Property) | Sort-Object } |
Or get all properties
1 |
$Rule | Select * | Format-List |
Our complete amazing Get-TransportRulePropertiesS function
Putting all the pieces together produced a nice function. You can add Comment-based Help for a Function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
Function Get-TransportRulePropertiesS { [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Enter rule name")] [String] $RuleName, [Parameter(Mandatory=$true, ValueFromPipeline, HelpMessage="Properties to be selected")] [String] $Properties ) Begin { # Connect to Exchange Online if a connection is not established $GetSessions = Get-PSSession | Select-Object -Property State, Name $IsConnected = (@($GetSessions) -like '@{State=Opened; Name=ExchangeOnlineInternalSession*').Count -gt 0 If ($IsConnected -ne "True") { Connect-ExchangeOnline } # display an error message if the transport rule does not exist then stop $Rule = Get-TransportRule $RuleName -ErrorAction SilentlyContinue If ($Rule -eq $null) { Write-Host -ForegroundColor Red "`nRule [$RuleName] does not exist" Break } } # Begin Process { If ($Properties -eq "*") { # Get all properties $Rule | Select * | Format-List } Else { # Get the required properties $PropertiesA = $Properties.Split(',') ForEach ($Property in $PropertiesA) { Write-Host "`n*** $Property" $Rule.($Property) | Sort-Object } } } # Process End { } # End } # Get-TransportRulePropertiesS |
Putting our amazing function to work
The following examples show different usage of our amazing Get-TransportRulePropertiesS function.
1 2 3 4 5 6 7 |
Get-TransportRulePropertiesS -RuleName "Identify External Emails" -Properties "ExceptIfSenderDomainIs" Get-TransportRulePropertiesS -RuleName "Identify External Emails" -Properties "ExceptIfSenderDomainIs,SentToMemberOf,FromScope" Get-TransportRulePropertiesS -RuleName "Identify External Emails" -Properties * "SentToMemberOf,FromScope" | Get-TransportRulePropertiesS -RuleName "Identify External Emails" |
Conclusion
In this blog we explored writing a function to get Transport Rule properties using PowerShell. We connected to Exchange Online if there is no connection. We also displayed an error message if the transport rule does not exist.
Did you find this blog easy to follow and helpful to you? I would love to hear your feedback and suggestions. Let me know in the comments below. Happy PowerShelling.
Disclaimer
Purpose of the code contained in blog is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.
There's no comments