Creating an Exchange 2010 Transport Agent
Writing your own transport agent for Exchange Server 2010 is not complicated or an unsolvable task...
Exchange 2010 recently introduced a new feature called "cmdlet extension agents." These agents can be called when a cmdlet is running, and can also perform extra tasks as a part of the original cmdlet. A recent Microsoft article has great information on understanding the Cmdlet Extension Agents. You can see which cmdlet extension agents are available by running this command in the Exchange Management Console (EMC):
get-CmdletExtensionAgent | ft name
One of the most useful cmdlet extension agents is the "Scripting Agent." The “Scripting Agent” is a cmdlet extension agent that works based on a certain cmdlet being run, and executes code based on that as well. An example is to configure it to wait for the cmdlet "new-distributiongroup" to run, and then sending a test email to that newly created distribution group. Another benefit is that it will run for actions performed in both the Exchange Management Shell or the Exchange Management Console (or the Exchange Administration Center in Exchange 2013) as they all end up using the same PowerShell commands to perform their functions.
The best use I have found for it is when a new mailbox is created manually, you can set any number of settings or configurations automatically. You might want to disable ActiveSync for all newly created users, add them to your company's main distribution group - or both!
To use this feature, you'll first need to enable it. You can check to see the status with the following EMC command:
get-CmdletExtensionAgent | ft name, enabled
This will list each cmdlet extension agent, including the "Scripting Agent" we want. The Enabled column should say 'false', unless it was previously enabled by someone else. To enable, run the following command:
Enable-CmdletExtensionAgent "Scripting Agent"
This needs to be run on each Exchange server that you'll connect to for management purposes. No changes are required at the client side though.
If you re-run the previous command to check the status, it should have changed to 'True.' At this stage we've enabled a feature, however, there's nothing for it to do. The instructions it follows need to be in a file located in D:\Program Files\Microsoft\Exchange\v14\Bin\CmdletExtensionAgents\ (change the drive letter to wherever Exchange is installed) called ScriptingAgentConfig.xml. This file won't be there by default, but there will be a ScriptingAgentConfig.xml.sample file that shows you some examples of XML code with comments. I recommend starting with a blank ScriptingAgentConfig.xml file, and using the sample as a reference.
If you don't know XML code you should still be fine, as you can adjust other code as necessary. There's are a lot of examples available online if you search for them. Here's the simple one I'll be using:
<?xml version="1.0" encoding="utf-8" ?>
<Configuration version="1.0">
<Feature Name="MailboxProvisioning" Cmdlets="new-mailbox,enable-mailbox">
<ApiCall Name="OnComplete">
if($succeeded) {
start-sleep -s 5
$newmailbox = $provisioningHandler.UserSpecifiedParameters["Alias"]
Add-Mailboxpermission -identity $newmailbox -User "Exchange Mailbox Full Access" -AccessRights FullAccess -InheritanceType All
}
</ApiCall>
</Feature>
</Configuration>
So what is the meat of this XML doing? First, the Feature Name is just a name for this section of script. You will usually name it so that it's clear as to what the section is about, as it may perform several different functions. Here I've called it MailboxProvisioning.
The Cmdlets section specifies what cmdlets the code below will relate to. For my example, I want it to run if someone creates a new mailbox, but I've also included the enable-mailbox command. The command that gets used depends if the Active Directory account exists or not in which case I'm covering both scenarios.
Next is the ApiCall Name. There's only four options for this which are: ProvisionDefaultProperties, UpdateAffectedIConfigurable, Validate and OnComplete. I'm using OnComplete, as I want the script to run after the new-mailbox or enable-mailbox command has been completed. I can't set settings on a mailbox until after it's created.
The 'if' statement is checking that the cmdlet gave back a 'succeeded' result. If it failed, then there's no point in running the script.
Now the actual code runs. I'm starting with a "start-sleep -s 5" command as I found that it was running too quickly, and couldn't find the mailbox I'd just created without waiting a few seconds. This ensures that the mailbox is fully created before trying to make changes on it. After the sleep, I set a variable, $newmailbox. This variable gets set to the "Alias" parameter which has to be specified in both "new-mailbox" and "enable-mailbox" commands. I've seen a lot of similar scripts online that use the "Name" variable, however, this only works for a new-mailbox due to the Exchange Management Console not specifying the -name value when enabling a mailbox. Without providing a variable for the mailbox name, the rest of the script will be unable to run.
Finally we are up to the PowerShell command that I want to run. This is just a normal Add-Mailboxpermission command, that's using the Alias variable from above. It then sets FullAccess for the user "Exchange Mailbox Full Access" (which is actually a group).
That's it. While your XML might be a lot more complicated and detailed than the above, this is a good starting point. To test, you need to run one of the cmdlets specified (after restarting your console or shell window). The extra commands should run, and in the above example you would use the 'get-mailboxpermissoin' cmdlet to see if the user or group is now listed.
As you can see, the Scripting Agent is a powerful yet easy way of making sure that the settings are configured a certain way, and will hopefully save you time too.
Writing your own transport agent for Exchange Server 2010 is not complicated or an unsolvable task...
Understanding the details of user mailbox access is very important to knowing what is going on...