Solved

Using the Exchange Script Agent for non-Exchange scripts

Posted on 2016-10-07
3
70 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 39

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 15

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

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

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

This article lists the top 5 free OST to PST Converter Tools. These tools save a lot of time for users when they want to convert OST to PST after their exchange server is no longer available or some other critical issue with exchange server or impor…
This article explains how to install and use the NTBackup utility that comes with Windows Server.
In this video we show how to create a mailbox database in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: First we need to log into the Exchange Admin Center. Navigate to the Servers >> Data…
This video demonstrates how to sync Microsoft Exchange Public Folders with smartphones using CodeTwo Exchange Sync and Exchange ActiveSync. To learn more about CodeTwo Exchange Sync and download the free trial, go to: http://www.codetwo.com/excha…

856 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