Cmdlet Extension Agents Part 2: Postconfiguring Mailboxes

Cmdlet Extension Agents Part 1: Automatic archive creation

Almost a year ago, I posted an article in which I tried to show the power of Cmdlet Extension Agents in Exchange 2010, or more specifically, the Scripting Agent. Unfortunately, the Cmdlet Extension Agents are often overlooked or ignored, despite customers having requirements to customize things immediately after creating a mailbox. Therefor, I decided to write another article on this topic, hoping people take up using Scripting Agents.

Now while you can also put all sorts of post-configuration tasks in provisioning scripts, using the Scripting Agent when possible has a big bonus, because those additional actions not only run when you run the cmdlet directly from the Exchange Management Shell but also when you run them indirectly by using the Exchange Management Console.

So, as this follow up of the previous article, in which I explained what the CmdLet Extension Agents are and how to utilize the Scripting Agent to automate tasks, I’ll show you another example of a Scripting Agent and quickly walk you through it, so you can experiment with it (first in a lab of course) and tune it to your own requirements.

In this example, we’ll disable ActiveSync and configure SingleItemRecovery when creating a new user with a mailbox or mailbox-enabling an existing user. Therefor, the cmdlets we’re going to customize are New-Mailbox and Enable-Mailbox.

Open up Notepad and create a file \bin\CmdletExtensionAgents\ScriptingAgentConfig.xml located in Env:ExchangeInstallPath, e.g. C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents, using the following contents:

Note: If you’ve already got a ScriptingAgentConfig.xml file, you need to integrate the following content.

<?xml version="1.0" encoding="utf-8" ?>
 <Configuration version="1.0">
 <Feature Name="Mailboxes" Cmdlets="New-Mailbox,Enable-Mailbox">
 <ApiCall Name="OnComplete">
   if($succeeded) {
     $Name= $provisioningHandler.UserSpecifiedParameters["Name"]
     Set-Mailbox $Name -SingleItemRecoveryEnabled $true
     Set-CASMailbox $Name -ActiveSyncEnabled $false
   }
 </ApiCall>
 </Feature>
 </Configuration>

As you can see, you’re not limited to 1 action or related cmdlets (*-Mailbox). A small explanation:

  • The Cmdlets specified in this feature extension dictates which cmdlets will be extended, in this case New-Mailbox and Enable-Mailbox;
  • OnComplete dictates that our script will fire when the cmdlet has finished;
  • We check for OnComplete parameter $succeeded, only configuring the mailbox when the preceding events were successful;
  • $provisioningHandler.UserSpecifiedParameters contains user provided parameters passed to the cmdlet. So, $provisioningHandler.UserSpecifiedParameters[“Name”] will return the value of –Name;
  • We set SingleItemRecovery to $true for the mailbox specified by $Name;
  • We disable ActiveSync client access for this mailbox as well.

As mentioned in part 1, distribute this XML file to all your Exchange servers in the local CmdletExtensionAgents folder. When you haven’t already enabled the Scripting Agent, do so by running the following cmdlet:

Enable-CmdletExtensionAgent “Scripting Agent”

Now, when we create a new mailbox or mailbox-enable an existing user:

image

.. you’ll see the SingleItemRecovery has been enabled and ActiveSync has been disabled for this mailbox by the scripting agent:

image

I recommend you start checking out the Scripting Agent if you haven’t already done so. You can use these examples as a starting point and work from there. More information on the Scripting Agent, alternative APIs etc. can be found here.

20 thoughts on “Cmdlet Extension Agents Part 2: Postconfiguring Mailboxes

  1. Pingback: Automatic archive creation – Cmdlet Extension Agents Part 1 | EighTwOne (821)

  2. Pingback: assign retention policies to mailboxes

  3. Hi Michel, thanks for the blog post.

    I’ve enabled the Scripting Agent. but I’m getting the below error when creating a new mailbox. The result is a new mailbox but ActiveSync is still enabled.

    Summary: 1 item(s). 1 succeeded, 0 failed.
    Elapsed time: 00:00:06

    EAS script
    Completed

    Warning:
    The cmdlet extension agent with the index 5 has thrown an exception in OnComplete(). The exception is: Microsoft.Exchange.Provisioning.ProvisioningException: ScriptingAgent: Exception thrown while invoking scriptlet for OnComplete API: Cannot bind argument to parameter ‘Identity’ because it is null.. —> System.Management.Automation.ParameterBindingValidationException: Cannot bind argument to parameter ‘Identity’ because it is null.
    at System.Management.Automation.ParameterBinderBase.ValidateNullOrEmptyArgument(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, Type argumentType, Object parameterValue, Boolean recurseIntoCollections)
    at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
    at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
    at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
    at System.Management.Automation.ParameterBinderController.BindPositionalParametersInSet(UInt32 validParameterSets, Dictionary`2 nextPositionalParameters, CommandParameterInternal argument, ParameterBindingFlags flags, ParameterBindingException& bindingException)
    at System.Management.Automation.ParameterBinderController.BindPositionalParameters(Collection`1 unboundArguments, UInt32 validParameterSets, UInt32 defaultParameterSet, Boolean ignoreArgumentsThatLookLikeParameters, ParameterBindingException& outgoingBindingException)
    at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
    at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
    at System.Management.Automation.CommandProcessor.BindCommandLineParameters(CommandParameterInternal[] parameters)
    at System.Management.Automation.CommandProcessor.Prepare(CommandParameterInternal[] parameters)
    at System.Management.Automation.CommandProcessorBase.DoPrepare(CommandParameterInternal[] parameters)
    at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
    at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
    — End of inner exception stack trace —
    at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentHandler.OnComplete(Boolean succeeded, Exception e)
    at Microsoft.Exchange.Provisioning.ProvisioningLayer.OnComplete(Task task, Boolean succeeded, Exception exception)

    Exchange Management Shell command completed:
    New-Mailbox -Name ‘EAS script’ -Alias ‘EASScript4’ -UserPrincipalName ‘EASScript4@sys228.local’ -SamAccountName ‘EASScript4’ -FirstName ‘EAS’ -Initials ” -LastName ‘script’ -Password ‘System.Security.SecureString’ -ResetPasswordOnNextLogon $false

    Elapsed Time: 00:00:06

    Like

  4. I’ve worked out what the problem is. The variable in your “ScriptingAgentConfig.xml” file changes from $alias to $name. When I changed the xml to be consistant and use $alias all the way through it worked.

    Thanks again for the blog it’s been a real help on a customer requirement I am currently working on.

    Rob

    Like

  5. Pingback: Apply Reviewer calendar permissions on new users

  6. Pingback: Exchange 2010 Scripting Agent – flaphead.com

  7. Hello Sir,

    Thanks for this blog, it’s excellent 🙂

    I followed your steps but encontered the following issue once I tried to Enable a mailbox of and existing user using EMS or EMC,
    When I use New-Mailbox cmd I don’t have any issue (and the POP,IMAP and ActiveSyn are disabled), the warning is just with the cmdlet “Enable-Mailbox” (doesn’t work)

    This is my code .xml code:
    if($succeeded) {
    $newmailbox = $provisioningHandler.UserSpecifiedParameters[“Name”]
    set-casmailbox $newmailbox -popenabled:$false -imapenabled:$false -activesyncenabled:$false
    }
    WARNING: The cmdlet extension agent with the index 5 has thrown an exception in OnComplete(). The exception is:
    Microsoft.Exchange.Provisioning.ProvisioningException: ScriptingAgent: Exception thrown while invoking scriptlet for
    OnComplete API: Cannot bind argument to parameter ‘Identity’ because it is null.. —>
    System.Management.Automation.ParameterBindingValidationException: Cannot bind argument to parameter ‘Identity’ because
    it is null.
    at System.Management.Automation.ParameterBinderBase.ValidateNullOrEmptyArgument(CommandParameterInternal parameter,
    CompiledCommandParameter parameterMetadata, Type argumentType, Object parameterValue, Boolean recurseIntoCollections)
    at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter,
    CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
    at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument,
    MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
    at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets,
    CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
    at System.Management.Automation.ParameterBinderController.BindPositionalParametersInSet(UInt32 validParameterSets,
    Dictionary`2 nextPositionalParameters, CommandParameterInternal argument, ParameterBindingFlags flags,
    ParameterBindingException& bindingException)
    at System.Management.Automation.ParameterBinderController.BindPositionalParameters(Collection`1 unboundArguments,
    UInt32 validParameterSets, UInt32 defaultParameterSet, Boolean ignoreArgumentsThatLookLikeParameters,
    ParameterBindingException& outgoingBindingException)
    at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1
    arguments)
    at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
    at System.Management.Automation.CommandProcessor.BindCommandLineParameters(CommandParameterInternal[] parameters)
    at System.Management.Automation.CommandProcessor.Prepare(CommandParameterInternal[] parameters)
    at System.Management.Automation.CommandProcessorBase.DoPrepare(CommandParameterInternal[] parameters)
    at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
    at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable
    errorResults, Boolean enumerate)
    — End of inner exception stack trace —
    at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentHandler.OnComplete(Boolean succeeded, Exception e)
    at Microsoft.Exchange.Provisioning.ProvisioningLayer.OnComplete(Task task, Boolean succeeded, Exception exception)
    Thanks a lot!!

    Like

  8. Hi Michel,
    When you run the enable-mailbox cmdlet does it work? the new-mailbox works fine but when I use the enable-mailbox with an existing ad account i receive the following error:
    VERBOSE: [08:27:45.477 GMT] Enable-Mailbox : Admin Audit Log: Entered Handler:OnComplete.
    VERBOSE: [08:27:45.492 GMT] Enable-Mailbox : Admin Audit Log: Exited Handler:OnComplete.
    WARNING: The cmdlet extension agent with the index 1 has thrown an exception in OnComplete(). The exception is:
    Microsoft.Exchange.Provisioning.ProvisioningException: ScriptingAgent: Exception thrown while invoking scriptlet for
    OnComplete API: An undefined executing user property is being used. Property Name :’executingUserid’.. —>
    Microsoft.Exchange.Configuration.Authorization.ExecutingUserPropertyNotFoundException: An undefined executing user
    property is being used. Property Name :’executingUserid’.

    Have you come across this any help much appreciated 🙂

    Like

  9. New-Mailbox always seems to work, but Enable-Mailbox always would fail. To fix this, I had to put in a delay to give the domain controllers time to replicate (I have two DC’s in this site). This adds a 10 second delay for the command to complete, but at least it works. Depending on your environment you might need to increase the delay. See below:

    if($succeeded)
    {
    Start-Sleep -S 10
    Set-CASMailbox $provisioningHandler.UserSpecifiedParameters[“Alias”] -ActiveSyncEnabled $false

    Like

  10. Pingback: Blocking Mixed Exchange 2013/2016 DAG | EighTwOne (821)

  11. Pingback: Setting Calendar permissions right after mailbox creation | Jaap Wesselius

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.