Fix: ScriptingAgent error on Exchange 2016

I recently worked with a client to install a new Exchange 2016 server into an existing Exchange 2010 environment. The install was smooth and all tests were successful, however I faced a recurring warning whenever using the New-Mailbox cmdlet.

This error was present in both EAC and EMS (full error can be found at the bottom of this post):

While parts of the warning message occasionally changed, one thing remained consistent – “ScriptingAgent”.

By running Get-CmdletExtensionAgent, we are able to see that the Scripting Agent is currently enabled, an extension that is disabled by default.

Disable-CmdletExtensionAgent can be used to disable the Scripting Agent:

A few minutes after disabling the Scripting Agent, I was able to succesfully create a mailbox with no warnings.

All done? Not quite. Obviously the Scripting Agent was enabled intentionally, so it was time to do some digging to find out exactly how it was being used.

Navigating to C:\Program Files\Microsoft\Exchange Server\V14\Bin\CmdletExtensionAgents will take you to the Scripting Agent’s configuration file, ScriptingAgentConfig.xml:

Examining this file in a text editor quickly allowed me to determine that it was simply adding default calendar permissions to each new mailbox as soon as they are created.

If it were not for all mailboxes having already been migrated to Exchange Online, I would have replicated the Scripting Agent config file on the Exchange 2016 server (which currently has the default instead). This is a simple case of copying the file to the equivelent directory on the later server, C:\Program Files\Microsoft\Exchange Server\V15\Bin\CmdletExtensionAgents.

Since no new mailboxes are being created on-premises, I can simply leave the Scripting Agent disabled.

A full copy of one of the errors seen can be found below:

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: Exception calling "ExecuteNonQuery" with "0" argument(s): "ExecuteNonQuery requires an open and
available Connection. The connection's current state is closed.". ---> System.Management.Automation.MethodInvocationException: Exception calling "ExecuteNonQuery" with "0"
argument(s): "ExecuteNonQuery requires an open and available Connection. The connection's current state is closed." ---> System.InvalidOperationException: ExecuteNonQuery
requires an open and available Connection. The connection's current state is closed.
   at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache,
Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at CallSite.Target(Closure , CallSite , Object )
   --- End of inner exception stack trace ---
   at System.Management.Automation.ExceptionHandlingOps.ConvertToMethodInvocationException(Exception exception, Type typeToThrow, String methodName, Int32 numArgs, MemberInfo
   at CallSite.Target(Closure , CallSite , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   --- End of inner exception stack trace ---
   at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentHandler.OnComplete(Boolean succeeded, Exception e)
   at Microsoft.Exchange.Provisioning.ProvisioningLayer.OnCompleteImpl(Task task, Boolean succeeded, Exception exception)

Leave a comment