?
Solved

Using the Exchange Script Agent for non-Exchange scripts

Posted on 2016-10-07
3
Medium Priority
?
113 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
3 Comments
 
LVL 42

Accepted Solution

by:
Adam Brown earned 2000 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 16

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

Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

Question has a verified solution.

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

Here's a look at newsworthy articles and community happenings during the last month.
This process allows computer passwords to be managed and secured without using LAPS. This is an improvement on an existing process, enhanced to store password encrypted, instead of clear-text files within SQL
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.
Suggested Courses
Course of the Month14 days, 21 hours left to enroll

771 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