Managing Azure Active Directory Rights Management

Posted on Leave a commentPosted in 2013, aadrm, dirsync, encryption, IAmMEC, journal, journaling, licence, mcm, mcsm, MVP, Office 365, rms, transport agent

This article is the third in a series of posts looking at Microsoft’s new Rights Management product set. In the previous post we looked at turning on the feature in Office 365 and in this post we will look at how to manage the service in the cloud.

In this series of articles we will look at the following:

The items above will get lit up as the articles are released – so check back or leave a comment to the first post in the series and I will let you know when new content is added.

Once you have signed up for the Azure Active Directory Rights Management (AADRM) Service there are a few things that you need to manage. These are:

  • The service itself
  • Users who are allowed to create RMS protected content
  • Enable and configure Super User rights if required.

Managing AADRM

There is not a lot to do in the Office 365 admin web pages with regard to the management of the service apart from enabling it, which we covered in the previous post and disabling it. Disabling the service involves the same steps as enabling it – you just click the big deactivate button!

AADRM can be further managed with PowerShell though. There are lots of blog posts on connecting to Office 365 using PowerShell, and some of those include the cmdlets to connect to Exchange Online etc. as well. The code below adds to this, and loads the AADRM module and connects to AADRM service in the cloud.

$cred = Get-Credential

write-host "Username: " $cred.username

Connect-MsolService -Credential $cred

Write-Host "...connected to Office 365 Windows Azure Active Directory"

$s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $cred -Authentication Basic -AllowRedirection

$importresults = Import-PSSession $s -Verbose

Write-Host "...connected to Exchange Online"

Import-Module AADRM

Connect-AadrmService -Verbose -Credential $cred

If you save the above PowerShell code as a text file with a .ps1 extension then you can run the script and easily connect to Office 365 with the credentials you enter. Then connect to Exchange Online with the same set of credentials and finally to AADRM with, of course, the same credentials. This allows you to manages users, email and security from a single session.

To get the AADRM PowerShell module on your computer (so that Import-Module AADRM works) you need to download the Rights Management PowerShell administration module from and then install it.

To install you need to have already installed the Microsoft Online Services Sign-In Assistant 7.0 and PowerShell 2.0. The PowerShell config file needs some settings adding to it, though I found on my Windows 8 PC that these had already been done. See the instructions at for this change to the config file.

  1. Run a PowerShell session and load the module with
    1. Import-Module AADRM
    2. Connect-AadrmService -Verbose
  2. Login when prompted with a user with Global Admin rights in Office 365.
  3. Or, use the script above to do Office 365, Exchange Online and AADRM in a single console.
  4. Run Get-Aadrm to check that the service is enabled

Enabling Super User Rights

Super Users in RMS are accounts that have the ability to decrypt any content protected with that RMS system. You do not need Super User rights to use RMS, nor do you need anyone who has Super User rights to use the product. But there are times when it might be required. One example would be during a discovery or compliance process. At this time it might be required that someone is able to open any RMS protected document to look for hits on the compliance issue in question. Super User gives that right, but would be needed just for the duration of the task that requires these rights. Rights to be Super User would be granted as needed and very importantly removed as needed.

Another example for the use of Super User is when a process needs to see content in its unprotected form. The common use case for this is Exchange Server and its transport decryption process. In Exchange Server you have agents that run against each message looking for something and then acting if that something is found. For example you would not want an virus to bypass the built in AV features of Exchange Server 2013 by protecting it with RMS! Or if you had a disclaimer transport rule or agent, you would not want the disclaimer or DLP feature to not see the content and act upon it because the content was encrypted. The same goes for journaling and the ability to journal a clear text copy of the message as well as the encrypted one if you wish.

To do all this in Exchange Server, the RMS Super User feature needs to be enabled and we will come back in a later post on the specifics of doing that for Exchange, but first we need to enable it in AARMS and set the users who will be Super Users and then, when we are finished with whatever required Super User, we need to turn it off again.

The Rights Management super users group is a special group that has full control over all rights-protected content managed by the Rights Management service. Its members are granted full owner rights in all use licenses that are issued by the subscriber organization for which the super users group is configured. This means that members of this group can decrypt any rights-protected content file and remove rights-protection from it for content previously protected within that organization.

By default, the super users feature is not enabled and no groups or users are assigned membership to it. To turn on the feature run Enable-AadrmSuperUserFeature from the AADRM PowerShell console. The opposite cmdlets exists to turn the feature off again – Disable-AadrmSuperUserFeature!

Once it is enabled you can set Office 365 users as Super Users. To do this run Add-AadrmSuperUser –EmailAddress where the user is either a cloud only Office 365 account or one that you have pushed to Office 365 using DirSync from your on-premises Active Directory. You can add more than one user, each user is added as a separate running of the cmdlets.

To see your list of Super Users, run Get-AadrmSuperUser. To remove users either take them out one by one (Remove-AadrmSuperUser –EmailAddress or just turn off the Super User feature with Disable-AadrmSuperUserFeature.

Adding AADRM Licences to Users

Once you have AADRM activated you can give your users the rights to create protected content. This is done in the licencing page of the Office 365 web admin portal or via PowerShell. The steps for adding user licences in the shell are discussed at That article was written some time ago, so the following are the changes for AADRM:

  • The Service Plan for the AADRM SKU is RMS_S_ADHOC

Journal Alternative Mailbox and No Inbox Rules

Posted on 1 CommentPosted in 2013, compliance, exchange, exchange online, journal, journaling, mcm, mcsm, ndr, Office 365, rules, transport, transport agent

In the event of your journal mailbox going offline, any journal reports destined for these mailboxes will queue. After two days (though this time is the expiry time for messages in your Exchange organization, so may be different) the message will expire and an NDR sent to the sender of the journal report. The problem is that the journal report was not sent by anyone – the From address is <>. So no NDR is generated and the journal report is lost.

There is the JournalReportNdrTo property of TransportConfig that allows you to set who will receive these NDR’s.

Set-TransportConfig -JournalingReportNdrTo

Once this value is set this mailbox should be monitored occasionally and any NDR’s opened and the containing message (the journal report) resent so that it goes back to the (now working) journal mailbox.

In Exchange 2013 this NDR mailbox is never the subject of journaling nor do any inbox rules run against this mailbox – even if this mailbox is mentioned in a journal rule of if the mailbox has inbox rules associated with it. When you set this value in your Exchange 2013 organization you get the following warning:

WARNING: Any mail to JournalingReportNdrTo mailbox will not be journaled and it will not honor transport and mailbox rules settings. It is recommended to create a dedicated mailbox for JournalingReportNdrTo setting or set it to an external address.

Or if you set it in Exchange Control Panel then the following popup appears:


The warning also mentions that Transport Rules do not fire for this mailbox, but that is not what I have seen – though it might be that specific transport rules do not get actioned, but others do. Inbox rules and Journal Rules are not processed.

Therefore it is very important that you do not use a standard mailbox as the target for JournalReportNdrTo, as this mailbox will have all its outbound emails missing from any journal it should be stored it (and this would be a compliance issue) and the user will get bothered that their email rules in Outlook are not working.

The problem is that this is not the case in Exchange 2010, so if you have set the JournalReportNdrTo property in the past on a mailbox, and then migrated that mailbox to 2013 you will not be warned, but you will find that upon migration to 2013 your inbox rules stop working and if you look in the journal mailbox you will not find messages send from this mailbox. Therefore create a mailbox specifically for journal NDR’s before you migrate to Exchange 2013.

Creating a Simple Exchange Server Transport Agent

Posted on 5 CommentsPosted in 2007, 2010, 2013, agent, exchange, mcm, sdk, smtp, transport agent, visual studio

This blog post follows a session that I delivered at the MEC 2012 conference in Orlando. If you attended the conference the slides are available on for the rest of 2012.

Part of the transport agents session was writing a new transport agent, and the example agent was to do add a form of catch-all functionality. The example code below (which purposefully needs editing to work, as its designed to be a learning tool) takes an email in the form of where the final recipient is and the subject line is changed to read [tag] Original Subject. Therefore email addresses can be given out that are an adjusted form of your real address, and on receipt of the email the correct recipient address is determined in code (the value before the _ appended to the domain name) so that you do not need to add lots of aliases to your user account in Active Directory. The subject is then changed to indicate the email came from this alternative original address. For example, an email to would go to and have [linkedin] added to the start of the subject.

As this partial catch all transport agent needs access to the recipient information and the subject, the agent needs to be bound to OnEndOfHeaders or OnEndOfData in the SMTP stack. It could also be bound to OnSubmittedMessage as a routing agent (rather than an SMTP agent) but could not be bound to OnResolvedMessage as recipient resolution has already happened by this point.

Writing the Transport Agent

To create the transport agent you need Visual Studio – the basic version of Visual Studio are sufficient and you need to copy the two DLL’s from Program Files\Microsoft\Exchange Server\V14\Public (or the V15 folder for Exchange 2013) to a folder on your development machine. You need a copy of these DLL’s for every version/service pack/update rollup of Exchange that you will run your agent on, as the DLL’s might change between these versions, and if you have the wrong version you will not be able to install your agent on a new server or if the server is updated, the transport service will fail as it will not be able to load the agent.

In Visual Studio, create a .NET 2 or 3.5 Class Library (for Visual Basic if using the below code) for Exchange 2010 or .NET 4.0 Class Library for Exchange 2013. For the project name enter something descriptive for what you are going to create (rather then ClassLibrary1). For example MECDemoPartialCatchAll.


Copy and paste the following code into the class.vb file, replacing the template text.

   1: Imports System

   2: Imports System.Collections.Generic

   3: Imports System.Text

   4: Imports Microsoft.Exchange.Data.Transport

   5: Imports Microsoft.Exchange.Data.Transport.Smtp


   7: Namespace XXXXX REM Change This


   9:     NotInheritable Class YYYYYY REM Change This

  10:         Inherits SmtpReceiveAgentFactory


  12:         Public Overrides Function CreateAgent(ByVal server As SmtpServer) As SmtpReceiveAgent

  13:             Return New ZZZZZ REM Change This

  14:         End Function


  16:     End Class


  18:     Public Class ZZZZZ REM Change This

  19:         Inherits SmtpReceiveAgent


  21:         Private Sub MyEndOfDataHandler(ByVal source As ReceiveMessageEventSource, ByVal e As EndOfDataEventArgs) Handles Me REM Change This

  22:             ' Get and change the recipient from alias_tag to alias (only doing for 1 recipient for simplicity)

  23:             If e.MailItem.Recipients.Count = 1 And InStr(e.MailItem.Recipients.Item(0).Address, "_") > 1 Then

  24:                 Dim Recipient() As String = Split(e.MailItem.Recipients.Item(0).Address, "@", 2)

  25:                 Dim EmailAlias() As String = Split(Recipient(0), "_", 2)

  26:                 'EmailAlias(0) = alias to send email to

  27:                 'EmailAlias(1) = tag for subject line

  28:                 'Recipient(1) = domain


  30:                 ' The following line prepends [tag] to the subject of the message.

  31: REM Change This                 "[" + EmailAlias(1).ToString + "] " + e.MailItem.Message.Subject


  33:                 'the following drops the current recipient

  34:                 e.MailItem.Recipients.Remove(e.MailItem.Recipients.Item(0).Address)


  36:                 'the following adds the recipient back again, this time using the alias without the tag

  37:                 e.MailItem.Recipients.Add(New RoutingAddress(EmailAlias(0).ToString + "@" + Recipient(1).ToString))

  38:             End If

  39:         End Sub


  41:     End Class


  43: End Namespace

Download this code

The remaining steps on creating the agent will be to modify the lines above that are marked with REM statements and then to add the reference DLL’s you copied from your Exchange Server and finally build your DLL.

Visual Studio can tell you when your code contains errors before you build your code, but to do so you need to reference the DLL’s that you obtained from your Exchange Server earlier in this blog. To do this you need to have copied the two DLL’s to a unique folder on your computer. I use c:\temp\Agent Authoring\Dll\E14-SP2-RU4 to store the DLL’s from Exchange 2010, SP2, RU4. Then when RU5 is released, if the DLL’s have changed I will place them in an E14-SP2-RU5 folder and update the references in my project. If I keep using the same folder then Visual Studio does not refresh the DLL but uses an existing cached copy.

To add the DLL’s right-click the project name to the right of the Visual Studio window and choose Properties (or press Alt+Enter):


Change to the Reference’s tab and click Add > Browse to find and add these two DLL’s.


You should see the two DLL’s listed as well as the default references for DLL’s included in the class library template that you used in Visual Studio.

Back on the code, its time to make the changes. Each of the changes and why it is needed are detailed based on the line numbers above

Line 7 – Namespace

This value of the namespace for the transport agent. Standard conventions indicate that this should be your company name. Therefore in your code change XXXXX to C7Solutions

Line 9 – NotInheritable Class

This value, YYYYYY, is the class that you are creating. This class inherits all the functionality of the Microsoft.Exchange.Data.Transport.Smtp.SmtpReceiveAgentFactory class. For this partial catch-all agent, a good name would be PartialCatchAllFactory.

Line 13 and 18 – Public Class

The Public Class contains the code to execute when the agent is called. This class has a name (ZZZZZ in the sample code above) and should be given a name that represents what the code does. This name in this example can be PartialCatchAll and it needs to be used in Line 13 (inside the PartialCatchAllFactory code to indicate the code to call instead of SmtpReceiveAgentFactory. And of course it is needed on line 18 to name the actual block of code. The name to use for this example will be PartialCatchAll

Line 21 – Handler

This line is missing the end of the code. Its a line that says run the code in this subroutine if the OnEndOfData event is called. Change the end of the line to read Me.OnEndOfData. This value should be one of the suggestions in the drop down list if you have done everything correct so far:


This subroutine also returns e as a pointer to the email message (i.e. you can modify e.MailItem.DeliveryPriority and many other properties) and source as a reference to the SMTP connection (i.e. with source.Disconnect you would close the SMTP session).

In this code lines 34 and 37 change the recipient. Line 34 removes the first recipient and then line 37 adds a new recipient that matches the alias + the domain.

Line 31 – Modify Subject

Finally, this code is missing the start of line 31. You need to enter e.MailItem.Message.Subject =  at the start of the line so that they subject becomes [tag] + original subject.

Building the Transport Agent DLL

The Errors List at the bottom of the Visual Studio screen should be empty by now. So time to build the project. If you have not saved this project in Visual Studio, the DLL will be created in the %temp% directory, so best recommendation is to save the project before building the DLL.

To save the project click File >  Save All and enter a suitable name for the project.


The project name becomes the solution name by default and then click Save.

The final thing to check before you build the DLL is the Root namespace value. This should be set to the name of the class library and can be set during creation of the library. If you have written your library in VB.Net then you will need this value to register the DLL. If you used C# then you will not need this value. As we have used VB.Net above, we need to check the root namespace value. This can be found on the project properties page.


If your DLL is ready to release (i.e. you have build and tested it already) then choose Build > Configuration Manager menu. Change the Active solution configuration to Release and click Close. If you do not make this change then the DLL will be created in the project_name\bin\debug folder and its possible that Visual Studio does not compile all the optimizations to the code that it can. For production items that perform at as good a speed as you can write optimal code, you should change this to Release for the Configuration value. The DLL will be created in project_folder\bin\release.

To build your DLL (debug or release) select the Build > Build RootNamespaceValue menu. This will create a DLL in project_name\bin\debug or project_name\bin\release.  A working version for Exchange 2010 SP2, RU4 can be downloaded from here.

Installing the Transport Agent

Copy the DLL to all your Exchange Servers that have the hub transport role installed on them (or if this should only apply to emails inbound from the internet, then just the servers that are listed on your MX records or the first servers connected to for inbound emails). Place the file in a directory (say C:\C7Agents) and run the following five lines from Exchange Management Shell:

Install-TransportAgent -Name “C7PartialCatchAll” -AssemblyPath “C:\C7Agents\MECDemoPartialCatchAll.dll”
-TransportAgentFactory “MECDemoPartialCatchAll.C7Solutions.PartialCatchAllFactory”

Enable-TransportAgent “C7CatchAll”

Restart-Service MSExchangeTransport


# Recommend closing EMS window now

Note that this restarts the transport service (required) and IIS (which will effect OWA and other CAS roles on the same machine). Remote Powershell (an IIS resource) will lock the DLL open, and so if you need to delete the DLL after uninstalling it, you need to have reset IIS and closed the Powershell window.

Finally, send an email to where name is the part of your email address before the @ in Exchange and is your domain. The value in “value” will be added to the subject as [value]. You get get an email in this form you know your agent has worked.

Transport Agents and Exchange 2013

I’ve also written an additional blog post on the changes for Exchange Server 2013 and transport agents. This covers the things to consider that are different with regards to Exchange 2007/2010 and the new Exchange.