Blog Post

Exchange Team Blog
4 MIN READ

Finding Transport Rule Size

The_Exchange_Team's avatar
Feb 24, 2022

Update: We have now released the get-etrlimits PowerShell cmdlet.  This new cmdlet incorporates many of the functionalities mentioned below, but with added ease and simplicity.

For additional related information you can also check our new blog post Finding Transport Rule Size Part 2 – Regex Limit.

EDIT 1/3/2023:
Recently we’ve enhanced “Get-TransportRule” cmdlet to return rule size and regex sizes. So, there is no need to create custom scripts anymore. To find the size of the Transport Rule and to determine the character limit for regular expressions (sometimes called regex) used in a Transport rule, you can use: Get-TransportRule cmdlet from Exchange Online Powershell.
Get-TransportRule “Name of the Rule” | FL Size,RegexSize

A question we sometimes hear from Exchange Online admins is “How can I determine the size of an Exchange Transport Rule (ETR)?” Sounds like a pretty easy question, but unfortunately there is no out of the box method to determine transport rule size. Until now, the answer has been elusive.

Why is knowing the size of an ETR important? Because the maximum size of an individual transport rule in Exchange Online is 8KB. Although it’s not easy to reach that limit, it might happen if the rule contains too many values. If it does, you get the following error:

For this reason, you might want to monitor the size of your rules and avoid being blocked unexpectedly if you add conditions. But before we start, let’s understand some basic concepts around Transport Rules.

Transport Rule Basic Concepts

When you create an ETR, Exchange Server or Exchange Online create an object in Active Directory (AD) under the CN=TransportVersioned container as an msExchTransportRule class. This object contains several attributes related to the rule, but the one that we’ll focus on is msExchTransportRuleXml. This is a string attribute in XML format that contains all the information about the rule (the name, conditions, actions, exceptions, etc.).

Understanding the msExchTransportRuleXml attribute is essential as the Exchange code relies on the length of this attribute to check the size of rule. A very simple mechanism, don’t you think? And indeed, it is if msExchTransportRuleXml is accessible. If you run Exchange Server, you can get the size of this attribute using the Get-ADObject cmdlet. As you probably can guess, the Get-ADObject cmdlet won’t work in Exchange Online. But there are other options; such as a script!

Although there is no way to manipulate msExchTransportRuleXml directly using Exchange Online PowerShell, there is a cmdlet that can help us: Export-TransportRuleCollection

Using a Script

To build your own script, start by assigning the ETR name you want to retrieve to a variable:

$ruleName = "Your ETR here"

Next, use Export-TransportRuleCollection with -Format InternalXML to export all ETRs found in AD to XML.

$file = Export-TransportRuleCollection -Format InternalXML

If you check the FileData property on the XML file containing the ETR export, you’ll see measurements in bytes, which means that you need to decode the FileData from byte array to string and cast it to XMLDocument:

[xml]$xml = [System.Text.Encoding]::UTF8.GetString($file.FileData)

Now you should be able to parse the XML. All rules were added, so you need to filter for the ETR you want:

$null = ($xml.SelectNodes("//rule")).Where({$_.name -notmatch "$ruleName"}) | % {$_.ParentNode.RemoveChild($_)}

Another thing to clean up in the XML is the “Id” attribute. The msExchTransportRuleXml string doesn’t have an Id attribute, so even though Export-TransportRuleCollection method adds it, you should remove it to align with msExchTransportRuleXml.

$xml.rules.rule.RemoveAttribute("id")

The last thing to do is the conversion from XML to string:

[string]$node = $xml.rules.rule.OuterXml

And now, you can check the length of the node variable to see the size of your rule:

$node.Length

The output is in bytes; the following example shows a rule at the limit of 8192 bytes.

Here is the full script:

$ruleName = "Your ETR here"
$file = Export-TransportRuleCollection -Format InternalXML
[xml]$xml = [System.Text.Encoding]::UTF8.GetString($file.FileData)
$null = ($xml.SelectNodes("//rule")).Where({$_.name -notmatch "$ruleName"}) | % {$_.ParentNode.RemoveChild($_)}
$xml.rules.rule.RemoveAttribute("id")
[string]$node = $xml.rules.rule.OuterXml
$node.Length

You can also use the following cmdlets to show all ETR size descending by the length in bytes:

($xml = ([xml][System.Text.Encoding]::UTF8.GetString((Export-TransportRuleCollection -Format InternalXML).FileData))).SelectNodes("//rule").RemoveAttribute("id")
$xml.rules.rule | %{ [pscustomobject]@{Name = $_.Name; LengthInBytes = $_.OuterXml.Length} } | Sort LengthInBytes -Descending

You can use following script in Exchange Server to retrieve the value directly from the msExchTransportRuleXml attribute:

$ruleName = "Your ETR here"
$rule = Get-TransportRule -Identity $ruleName
$obj = Get-ADObject -SearchBase $rule.DistinguishedName -lDAPFilter "(CN=$ruleName)" -Properties "msExchTransportRuleXml"
$obj.msExchTransportRuleXml.Length

Remember that the limit is not adjustable in Exchange Online. If you have large ETRs, we encourage you to check their size and reduce their length as much as possible, and to remove ETRs after they are no longer needed. These actions might help reduce your mail flow latency.

We hope that these details on how to retrieve the size of an ETR improve your Exchange Online and Exchange Server experience. Feel free to use the Comments section to ask questions or provide suggestions!

Thanks to Arindam Thokder, Alex Hudish, Keith Schottland and Nino Bilic for their review of this post.

Denis Vilaça Signorelli
Service Engineer

Updated Aug 01, 2023
Version 5.0
  • momurray's avatar
    momurray
    Brass Contributor

    Great post thanks! 

    I know inbox rules also have similar limits expressed in KB. I always wondered how to get inbox rules total size for a mailbox. I don't think there is an easy way to get that info. That would be a fantastic article! 🙂

  • momurray Thank you for your feedback! You’re right, inbox rules are limited to 256 KB total for all rules, but the difference here is where it is stored, while ETR are stored in AD the Inbox Rules are stored in the user’s mailbox as MAPI property. For that reason, it’s quite complicated to retrieve the rule size, but it should be possible through MFCMAPI to find the total rules' size.

     

    In the Inbox folder there is a property called 0x3fff0003 (PR_Rules_Size). That should represent the inbox rule total size. I’m not sure if this property is updated when you update an existing rule, but I’m sure that it’s updated when you create a new one. If you want to test it, just reduce the rule quota to the minimum allowed (32KB) and create many rules monitoring the PR_Rules_Size property. It should block you as soon as you reach 32,768KB

  • Thank you for your post. Is there any way to extend ETR Rule limit without purchasing 3rd party solution for Exchange On Premise? Namely for information classification to work correctly, one needs to insert multiple lines in message header (msip_labels). Is there any way to achieve that? Regex will not help here as I am not searching for the match within the header, but rather inserting additional header information needed by another MS tool. These lines cannot be implemented due to size restriction. If size cannot be increased, is it possible to trigger a custom action in ETR (e.g. run a script from the server)?

    Thanks for your input.

       

  • hatsikidee's avatar
    hatsikidee
    Brass Contributor

    Denis_SignorelliI have a similar question like Aleksander. We're using Exchange Online and we use a text file with 5000 mail domains to route mail to a certain connector. (these are healthcare suppliers that are all connected to the same WAN network. We have a partner connector between Exchange Online and a mail server on this network)

    Because of the 8 KB limit of the ETR, we now need to create (and update) 37 transport rules. Just for this action alone. Is there a way you can help us?

     

Share