One of the key operational aspects to maintaining a sound environment is to document and understand how it is configured. This becomes more and more important with added complexity and also as time goes by. As the solution is in production for an increasing amount of time, the implementing staff may transition out of role or leave the organisation. They may have even been external consultants and never part of your internal team. To help understand the environment, and to plan changes the original build and architecture documents need to be retained and ideally updated as the system is updated.
If not, then you will run into unexpected situations. This was one of them.
The below is a reproduction of a customer environment so we were able to share screenshots etc. to illustrate the issue.
When attempting to install an additional Exchange 2016 server, the standard setup routine was used:
Setup.exe /IAcceptExchangeServerLicenseTerms /Mode:Install /Roles:Mailbox
Zooming in to make the text easier to read:
For the search engines, the full error text:
The following error was generated when "$error.Clear();
" was run:
"Microsoft.Exchange.Provisioning.ProvisioningBrokerException: Provisioning layer initialization failed: '"Scripting Agent initialization failed:
"File is not found: 'C:\Program Files\Microsoft\Exchange Server\V15\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'.""' --->
Microsoft.Exchange.Provisioning.ProvisioningException: "Scripting Agent initialization failed: "File is not found: 'C:\Program
Files\Microsoft\Exchange Server\V15\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'."" ---> System.IO.FileNotFoundException: "File is not found:
'C:\Program Files\Microsoft\Exchange Server\V15\Bin\CmdletExtensionAgents\ScriptingAgentConfig.xml'."
at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentConfiguration.Initialize(String xmlConfigPath)
at Microsoft.Exchange.ProvisioningAgent.ScriptingAgentConfiguration..ctor(String xmlConfigPath)
--- End of inner exception stack trace ---
If we look at the local file system, there is no Scripting Agent config file. Only the sample file exists with a .sample file extension.
Was the scripting agent enabled previously? Yes it was.
We can see this by running
Get-CmdletExtensionAgent | Select Name, Enabled
Note that the Scripting Agent is enabled, the below is an example from Exchange 2010 but it is pretty much the same on newer versions....
If we look on an Exchange 2013 server, as expected there is a valid Scripting Agent config file.
We have two main options:
- Disable Scripting Agent
- Copy configuration file over from existing server
Which one to choose? It really depends on if the scripting agent is actually used or was intended to be used. In multiple cases, I've see the feature enabled but never actually integrated to extend cmdlet behaviour. How can you tell? Read your build & operational documentation, But chances are that was never created or updated. The second option is to examine the config file on every server to determine if there are any valid configurations that are actually in use. If the files are all different, then that tells me that the feature was not really rolled out and results are already inconsistent as these files all have to be the same.
Disable Scripting Agent
This is the quicker option, so let's get it out the way.
Disable-CmdletExtensionAgent "Scripting Agent"
Copy Configuration File
Ideally we know that the Scripting Agent is in use, before launching Exchange setup . This lets us pre-create the directory structure, and copying the configuration file before starting Exchange setup.
Adjust the path to suit, and use your favourite tool to create the folder. In the example below, we can go old skool.
MKDIR "C:\Program Files\Microsoft\Exchange Server\V15\Bin\CmdletExtensionAgents"
Then we can copy our XML file into the location.
Re-Run Exchange Setup
Now that all of the prerequisites have been met, a valid Scripting Agent file is present or the Scripting Agent was disabled we can re-run Exchange setup.
Note that setup now completes successfully.