HOW TO:Rewrite the To address in Transport Agents on a Hub Server

Have you ever tried sending a mail to someone and it end up with someone else! Beware there could be a Transport Agent that's doing this:-).

I ran into an issue where I needed to rewrite the address the mail was being sent to. Not going into too much as to why somebody would want to do this,  I wrote a Transport Agent that would do the needful.

The below sample C# code written in Visual Studio 2005 changes the To address of the mail that is being sent out. There is no conditional logic as of now and the code assumes that there is only one recipient.

 using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Microsoft.Exchange.Data.Mime;
using Microsoft.Exchange.Data.Transport;
using Microsoft.Exchange.Data.Transport.Email;
using Microsoft.Exchange.Data.Transport.Routing;

namespace Samples.Agents.MyRoutingAgent
{
    public class MyRoutingAgentFactory :RoutingAgentFactory
    {
        public override RoutingAgent CreateAgent(SmtpServer server)
        {
            return new MyRoutingAgent();
        }
    }

    public class MyRoutingAgent : RoutingAgent 
    {
        private object fileLock = new object();  

        public MyRoutingAgent()
        {
            base.OnSubmittedMessage += new SubmittedMessageEventHandler(MyRoutingAgent_OnSubmittedMessage);
        }

        void MyRoutingAgent_OnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs e)
        {
            lock (fileLock)
            {
                try
                {
                    string logDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Log";
                    string logFile = logDir + @"\log.txt";

                    if (!Directory.Exists(logDir))
                    {
                        Directory.CreateDirectory(logDir);
                    }
                    
                    if (!File.Exists(logFile))
                    {
                        File.CreateText(logFile).Close();
                    }

                    using (StreamWriter logWriter = File.AppendText(logFile))
                    {
                        logWriter.Write(Environment.NewLine + "-------------------------------------------------------------------------------" + Environment.NewLine);

                        //Alter the P1 headers.The P1 address is used for routing.
                        for(int intCounter=e.MailItem.Recipients.Count-1;intCounter>=0; intCounter--)
                        {
                            logWriter.WriteLine("Original Recipient:" + e.MailItem.Recipients[intCounter].OriginalRecipient);

                            if (e.MailItem.Recipients[intCounter].Address.IsValid)
                            {
                                e.MailItem.Recipients.Remove(e.MailItem.Recipients[intCounter]);

                                if (e.MailItem.Recipients.CanAdd)
                                {
                                    e.MailItem.Recipients.Add(new RoutingAddress("administrator@mycompany.com"));
                                }
                            }
                        }

                        //Alter the P2 headers so that the mail displays the correct recipient display Name
                        EmailRecipientCollection erToRecipientCollection;
                        erToRecipientCollection = e.MailItem.Message.To;

                        logWriter.Write(Environment.NewLine + "-------------------------------------------------------------------------------" + Environment.NewLine);
                        foreach (EmailRecipient rec in erToRecipientCollection)
                        {
                            logWriter.WriteLine("Original Display Name:" + rec.DisplayName);
                            logWriter.WriteLine("Original SMTP address:" + rec.SmtpAddress);

                            rec.DisplayName = "Administrator";
                            rec.SmtpAddress = "administrator@mycompany.com";

                            logWriter.WriteLine("Changed to <Administrator>administrator@mycompany.com");

                            }
                        }
                        logWriter.Write(Environment.NewLine + "-------------------------------------------------------------------------------" + Environment.NewLine);

                        logWriter.Flush();
                    }
                }
                catch (System.IO.IOException ex)
                {
                    Debug.WriteLine(ex.ToString());
                }
            }
            return;
        }

    }
}

It is IMPORTANT that you change both the P1 and the P2 headers for this to work correctly. To build the Agent successfully you will need to add references to Microsoft.Exchange.Data.Transport and the Microsoft.Exchange.Data.Common namespaces. These dll's can be found in the Program Files\Microsoft\Exchange Server\Public folder.

To Install/Uninstall the Agent on the Hub Server I have created script files that do the job for me(makes life easier).

Install.PS1

 #Copy the agent Dll to the C:\MyAgent folder.
$EXDIR="C:\MyAgent"
Net Stop MSExchangeTransport

Write-Output "Registering agent"
Install-TransportAgent -Name "My Routing Agent Sample" -AssemblyPath $EXDIR\RoutingAgent.dll -TransportAgentFactory Samples.Agents.MyRoutingAgent.MyRoutingAgentFactory

Write-Output "Enabling agent"
Enable-TransportAgent -Identity "My Routing Agent Sample"
Get-TransportAgent -Identity "My Routing Agent Sample"

Net Start MSExchangeTransport

Write-Output "Install Complete. Please exit the Exchange Management Shell."

UnInstall.PS1

  $EXDIR="C:\MyAgent"<br>Net Stop MSExchangeTransport<br>Write-Output "Disabling Agent..."<br>Disable-TransportAgent -Identity "My Routing Agent Sample" -Confirm:$false<br>Write-Output "Uninstalling Agent.."<br>Uninstall-TransportAgent -Identity "My Routing Agent Sample" -Confirm:$false<br>Net Start MsExchangeTransport<br>Write-Output "Uninstall Complete." 


Need more information on Transport Agents?

Transport Agents

https://msdn.microsoft.com/en-us/library/aa579185.aspx

Enjoy!