Pro-Exchange,Lync & Office 365
Belgian Microsoft Unified Communications Professionals
Microsoft Exchange Server, Microsoft Lync Server & Office 365
Using the Scripting Agent to automate some basic “housekeeping” tasks

Introduction

Recently, Koen published an article about applying “housekeeping” retention policies to end-users.

Somewhere in the article, there was a specific line that drew my attention:

“… The policy will need to be applied to future mailboxes as well. Obviously I can request the service desk to update their user/mailbox creation procedures. However as an exchange admin I prefer to keep control. In other words we need something that we can run over and over again…”

One way of making sure that the policy is applied to every new mailbox, is to instruct the helpdesk/service desk to run a script every time a new user is created. However, this is still a manual intervention which leaves room for (human) error. I wanted to go a step further, and make sure that the policy is applied every time a new mailbox is created.

 

CMDlet extension agents

CMDlet extension agents are components in Exchange Server 2010 that are called whenever a cmdlet runs. They – literally – extend the functionality of an existing cmdlet and are available on any Exchange Server Role but the Edge Transport Server.
Only native Exchange 2010 cmdlets can ‘call’ these extension agents. This means that you cannot – directly – call upon these agents using a script you’ve written yourself. However; if your script contains a native Exchange 2010 cmdlet (e.g. New-Mailbox), that cmdlet will still be calling the cmdlet extension agent.

Exchange 2010 includes several built-in agents but I’m not going into detail about the different agents. Nonetheless, for a detailed overview, take a look here: http://technet.microsoft.com/en-us/library/dd335067.aspx

For this article, it is the scripting agent in particular that I’m interested in.

 

Scripting Agent

The scripting agent is a cmdlet extension agent that allows you to ‘add’ some of your own scripting during execution of an Exchange 2010 cmdlet. The scripting agent includes some API’s that an Exchange 2010 cmdlet can call whenever a script is configured to be run. In short: it allows you to run your own code: before, during or after an Exchange 2010 cmdlet is run.

If you’d like to have more information on the Scripting Agent, take a look here: http://technet.microsoft.com/en-us/library/dd297951.aspx

But instead of trying to explain everything into detail, let’s just use an example and everything will become clear.


Building on Koen’s example, I would like to achieve the following:

  • apply a retention policy named “Retention Policy 1” to new user mailboxes
  • exclude VIP-mailboxes and assign them a retention policy “Retention Policy VIP”

And of course, lazy admin as I am, I want these task to be executed automatically – without any user intervention.


Based on the requirements above, I could create a simple script like this: 

$policy = “Retention Policy 1”
$policy_vip = “Retention Policy VIP”

$mbx = get-mailbox | where{!$_.RetentionPolicy}
foreach($mb in $mbx){ 
  
# we assume that all VIP-users have a mailbox in the database “VIP”
   if($mb.database –eq “VIP”){
      Set-Mailbox –RetentionPolicy $policy_vip
   }
   else{
      Set-Mailbox –RetentionPolicy $policy
   }
}

Although this script can automatically assign a retention policy whenever it is run, someone still has to run it manually after a new user has been created. And that’s exactly what I’m trying to avoid Smile

 

Building the solution

Let’s see what happens when we put the Scripting Agent into action.

In the directory: “.\Program Files\Microsoft\Exchange Server\v14\Bin\CmdletExtensionAgents”, you will find a file called ScriptingAgentConfig.xml.sample. This file contains some samples on what you could do with the scripting agent:

image

Either rename the file to ScriptingAgentConfig.xml and alter it or create a new ScriptingAgentConfig.xml-file. I – personally – prefer creating a new (blank) file.

Copy-Paste the code below in the file:

<?xml version="1.0" encoding="utf-8" ?>
  <Configuration version="1.0">
  <Feature Name="MailboxProvisioning" Cmdlets="New-Mailbox">
  <ApiCall Name="OnComplete">
  If($succeeded) {
    $Name= $provisioningHandler.UserSpecifiedParameters["Name"]
    $retpolicy = "Retention Policy 1"
    $policy_vip = "Retention Policy VIP"
    if($provisioningHandler.UserSpecifiedParameters["RetentionPolicy"] -eq $null){
         if((get-mailbox $Name).database.name -eq "VIP"){
                Set-Mailbox -Identity $Name -RetentionPolicy $policy_vip
         }
         else{
             Set-Mailbox -Identity $Name -RetentionPolicy $retpolicy
         }
    }
  }
  </ApiCall>
  </Feature>
  </Configuration>

As you can see, we are using the onComplete-API which will make our code run after the new-mailbox cmdlet has been completed.

Let’s break down the script, and see what each part does:

  1. if($succeeded): will validate that the cmdlet ‘new-mailbox’ ran successfully
  2. $Name = $provisioningHandler.UserSpecifiedParameters["Name"]: assigns the value of the name-parameter that was provided with the new-mailbox cmdlet to the variable “$Name”
  3. if($provisioningHandler.UserSpecifiedParameters["RetentionPolicy"] -eq $null): we check whether a retention policy was already provided with the new-mailbox cmdlet. If so; no action will be taken.
  4. if((get-mailbox $Name).database.name -eq "VIP"): if the user’s mailbox is created in the VIP-database, assign “Retention Policy VIP”. Else, assign “Retention Policy 1”

After saving the file, we need to enable the Scripting Agent using the following cmdlet:

Enable-CmdletExtentionAgent “Scripting Agent”

image

You can verify it’s status running the following cmdlet:

Get-CmdletExtentionAgent “Scripting Agent” | fl Name,Enabled

image

Let’s create a mailbox and see what happens:

New-Mailbox –Name RetPol1 –Password (CovertTo-Securestring “P@ssw0rd” –AsPlainText –Force) –UserPrincipalName "RetPol1@domain.tld”

image

Now query for the user’s Retention Policy:

image

Magic! Even without specifying a Retention Policy, the user got the one I specified before assigned!

Now, let see what happens if we create the user in the VIP database:

image

This time the user got a different retention policy: “Retention Policy VIP”.

And what happens if we provide a retention policy with the new-mailbox cmdlet?

image

Exactly, the script will not change the retention policy (even though we created the user in the VIP database).

 

Conclusion

As you see, scripting agents are not that difficult to implement and offer you a wide range of possibilities in automating certain tasks.

Obviously, you could already provide a retention policy when executing the new-mailbox cmdlet using the –RetentionPolicy parameter. But that would still require you to enter that every single time, which leaves room for human error.

 

Extra Resources

By coincidence, not so long ago, another colleague (Michel de Rooij) also published an article about using CMDlet extension agents to automatically create an archive in a specific database whenever a new mailbox is created. I definitely recommend reading it through!


If you want to get to know more about the Scripting Agent, take a look at the following TechNet article:


Posted 08-31-2011 12:28 by Michael Van Horenbeeck