The SetRoutingOverride method was first introduced in Exchange Server 2007 as a supported method for using within Transport Agents. Transport Agents were previously known in prior versions of Exchange, notably Exchange 2000 and Exchange 2003, as SMTP Event Sinks. Although prior to Exchange 2007 we could natively choose different outbound routing using SMTP connectors and deny permissions if we wanted to - however it was a pain to setup and required a registry key to be set for Deliver Restrictions to work.
The SetRoutingOverride method was introduced to allow alternative delivery of sent email to alternate locations. For example we can use Scoped Send Connectors, which allow different outbound mail flow logistics in different AD sites, or we can deploy alternate gateways separate to Exchange that can handle this logic on our behalf.
So let's have a look at what we currently can do without a custom transport agent.
Use a third party gateway that can support the desired outbound logic
This will have a single Send Connector for general outbound mail delivery to a third party appliance. In this example the third party appliance is on-premise.
Use multiple AD sites
(even if they are within the same physical location) and incur the costs of this solution and utilise Scoped Send Connectors. The use of Stretched DAGs in this example is not a requirement, but invokes a higher level of resilience. Users in AD SITE 1 will utilise the outbound connector for general internet mail there, whilst users in AD SITE 2 will use the Scoped Send Connector valid for that AD site.
So what does SetRoutingOverride allow us to do? Well basically we create multiple Send Connectors. That's it. Each Send Connector has a dummy address space and your custom Transport Agent monitors all mailflow and for outbound messages that matches the trigger and then activates the routing override to push the mail to a specific address space. This in turn is matched to a Send Connector to a specific MTA, mail hygene platform or even directly for outbound routing and delivery to the external recipient.
Whilst this blog post will not show you how to code the actual custom transport agent (hey I'm not a developer – check the MSDN documentation and code examples) there are many ways to make this work. For example, should all logic sit within the actual transport agent? Should the custom transport agent have a config file local to the Exchange Server in question? Should the custom transport agent on all Exchange Servers look to a specific network based configuration file or indeed pull their configuration in remotely for a complete seamless and automated update of it? This is all up to you and how you need to make it work.
I will however show you examples of how to configure and monitor Exchange to prepare your environment for this.
The best way to explain this routing override method is to take the source 'From' address, and then push any mail for that down to a specific connector. It doesn't specify a connector but rather an 'override' address space to push the message to. So we create a Send Connector that just so happens to have the address space in question.
All mail sent from "contoso.com" addresses = "override" and send to "foo.foo"
All mail sent from "tailspintoys.com" addresses = "overrisde" and sent to "foo2.foo"
This doesn't rewrite the email at all or modify the headers, it simply tells the Transport service to deliver the email via a specific Send Connector because it matches the address space of "foo.foo". It's better to use a mythical address space that will never exist so as to never get into a situation where it becomes a real destination domain!
Let's take a look at what this means:
When a "contoso" user sends a mail that message is routed through to the preffered external smarthost for delivery:
When a "tailspintoys" user sends a mail that message is routed through to the preffered external smarthost for delivery:
So let's take a look at a real world example.
I have an Exchange 2013 combined role server, and two possible outbound paths to trusted premium AS/AV providers. MimeCast and Symantec.Cloud. I will check the configuration of the Send Connectors using Get-SendConnector
One for MimeCast
One for Symantec.Cloud
I will enable my install my custom transport agent and ensure it is enabled. You install your agent using the Install-TransportAgent cmdlet, you can enable or disable it, or change its priority using the Set-TransportAgent cmdlet. We will check to ensure the agent is installed and enabled using Get-TransportAgent.
Get-TransportAgent will show you all installed agents – including agents available out of the box like the text messaging agents and the free Malware Agent based on Microsoft Forefront that ships with Exchange 2013.
At this point I have set the custom transport agent to push all mail to Symantec.Cloud. Let's send a message and then check the headers.
Now I'll modify the custom transport agent to push the email through MimeCast. The custom transport agent I am using picked up the routing override from a text file local to the server.
Let's modify it.
Browsing to \\Exchange Server\TransportRoles\agents\ I will modify the config file. I now specified that for all users with the 'from' address matching "2013POA.co.uk" to now override the routing and push to "mimecast.sbr". It will now match this against a Send Connector.
I'll restart the Transport Service:
And then resend my message.
Let's check the the message headers now:
We can see it was sent outbound via the MimeCast Send Connector.
So that's it. Whilst this post doesn't cover the development of a transport agent dll to modify transport behaviour, we can see how the SetRoutingOverride method works.
In this example the Transport Agent took its configuration from a local text file, but as said previously this can be developed many ways.
You can use this to create multiple Send Connectors for different organisations or units within your business, allowing your custom transport agent to then selectively choose which preferential outbound route is required.
Oliver Moazzezi - MVP Exchange Server