Solved

Using the Exchange Script Agent for non-Exchange scripts

Posted on 2016-10-07
3
51 Views
Last Modified: 2016-11-22
We have a single Exchange 2016 server (And single DC.)  We've been using the Scripting Agent for a few processes and recently wanted to add in the ability to set and create a user's home folder from it.  

We added in the powershell commands to do this, and run by themselves, work fine.

But when we create a mailbox, we get errors.  The home folders are on a separate server, so wondering if this is an ACL issue.  Not sure what account the scripting agent would run under (Local?)  

Here's our code -

<?xml version="1.0" encoding="utf-8" ?>
<Configuration version="1.0">
   <Feature Name="MailboxProvisioning" Cmdlets="New-Mailbox">
     <ApiCall Name="OnComplete">
       If($succeeded) {
         Import-Module ActiveDirectory
	 start-sleep -s 10
         $alias = $provisioningHandler.UserSpecifiedParameters["Alias"]
         set-aduser $alias -homedrive "P:" -HomeDirectory "\\file001\personal\$alias"
         new-item -path "\\file001\personal\$alias" -type directory -force
	 $permissions = get-acl "\\file001\personal\$alias"
         $userpermissions = New-Object System.Security.AccessControl.FileSystemAccessRule("domain\$alias","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
 	 $permissions.AddAccessRule($userpermissions)
	 Set-Acl "\\file001\personal\$alias" $permissions
      }
     </ApiCall>
   </Feature>
</Configuration>

Open in new window


At first, I received the below error -

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 'AclObject' because it is null.. ---> System.Management.Automation.ParameterBindingValidationException: Cannot bind argument to parameter 'AclObject' because it is null. at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate) at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext) at System.Management.Automation.Interpreter.ActionCallInstruction`6.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)

Open in new window


Thinking something was wrong with the permissions, I just removed them temporarily to try the other lines.  Another error -

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: Access to the path 'test2' is denied.. ---> System.UnauthorizedAccessException: Access to the path 'test2' is denied. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost) at System.IO.DirectoryInfo.CreateSubdirectoryHelper(String path, Object directorySecurity) at System.IO.DirectoryInfo.CreateSubdirectory(String path) at Microsoft.PowerShell.Commands.FileSystemProvider.CreateDirectory(String path, Boolean streamOutput) --- 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)

Open in new window


So that's why I'm thinking you either can't do this kind of stuff in the scripting agent or it's an ACL issue in terms of the account the scripting agent runs under (Which I can't find.)

I finally removed all of the lines pointing to the remote server and just left in the line to set the user's home folder and that also errored -

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: Insufficient access rights to perform the operation. ---> Microsoft.ActiveDirectory.Management.ADException: Insufficient access rights to perform the operation ---> System.ServiceModel.FaultException: The operation failed due to insufficient access rights. --- End of inner exception stack trace --- at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowExceptionForExtendedError(String extendedErrorMessage, Exception innerException) at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowExceptionForErrorCode(String message, String errorCode, String extendedErrorMessage, Exception innerException) at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowExceptionForFaultDetail(FaultDetail faultDetail, FaultException faultException) at Microsoft.ActiveDirectory.Management.AdwsConnection.ThrowException(AdwsFault adwsFault, FaultException faultException) at Microsoft.ActiveDirectory.Management.AdwsConnection.Modify(ADModifyRequest request) at Microsoft.ActiveDirectory.Management.ADWebServiceStoreAccess.Microsoft.ActiveDirectory.Management.IADSyncOperations.Modify(ADSessionHandle handle, ADModifyRequest request) at Microsoft.ActiveDirectory.Management.ADActiveObject.Update() at Microsoft.ActiveDirectory.Management.Commands.ADSetCmdletBase`3.SetFromIdentity(O identity) at Microsoft.ActiveDirectory.Management.Commands.ADSetCmdletBase`3.ADSetCmdletBaseProcessCSRoutine() at Microsoft.ActiveDirectory.Management.CmdletSubroutinePipeline.Invoke() at Microsoft.ActiveDirectory.Management.Commands.ADCmdletBase`1.ProcessRecord() --- 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) 
 

Open in new window


Suggestions?
0
Comment
Question by:dipersp
3 Comments
 
LVL 38

Accepted Solution

by:
Adam Brown earned 500 total points
ID: 41834182
The scripting agent would likely run in the context of the computer ($EXCHANGESERVER), so you would probably need to make sure the folder in question grants permissions to the Server's AD object at a minimum.
0
 
LVL 14

Expert Comment

by:Jason Crawford
ID: 41835770
Spacing is important.  Try this:

<?xml version="1.0" encoding="utf-8" ?>
 <Configuration version="1.0">
 <Feature Name="MailboxProvisioning" Cmdlets="New-Mailbox,Enable-Mailbox">
 <ApiCall Name="OnComplete">
   if($succeeded)    {
      Import-Module ActiveDirectory
      start-sleep -Seconds 10
      $alias = $provisioningHandler.UserSpecifiedParameters["Alias"]
      set-aduser $alias -homedrive "P:" -HomeDirectory "\\file001\personal\$alias"
      new-item -path "\\file001\personal\$alias" -type directory -force
      $permissions = get-acl "\\file001\personal\$alias"
      $userpermissions = New-Object System.Security.AccessControl.FileSystemAccessRule("domain\$alias","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
      $permissions.AddAccessRule($userpermissions)
      Set-Acl "\\file001\personal\$alias" $permissions
   }
 </ApiCall>
 </Feature>
 </Configuration>

Open in new window


Also, have you verified a one-liner script works with the scripting agent?  Something simple like enabling SingleItemRecovery just to get a base.
0
 
LVL 9

Author Closing Comment

by:dipersp
ID: 41898041
Haven't been able (Or willing) to mess with the permissions in this situation, so will need to find another way around.  Giving points to Adam as he is most likely correct.
0

Featured Post

Control application downtime with dependency maps

Visualize the interdependencies between application components better with Applications Manager's automated application discovery and dependency mapping feature. Resolve performance issues faster by quickly isolating problematic components.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

In this article, I am going to show you how to simulate a multi-site Lab environment on a single Hyper-V host. I use this method successfully in my own lab to simulate three fully routed global AD Sites on a Windows 10 Hyper-V host.
Find out what you should include to make the best professional email signature for your organization.
The basic steps you have just learned will be implemented in this video. The basic steps are shown to configure an Exchange DAG in a live working Exchange Server Environment and manage the same (Exchange Server 2010 Software is used in a Windows Ser…
To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now