There are three different ways to configure new Exchange user mailboxes after these have been created.
- The classic manual administrator approach (keeps your job safe, but is it fun?)
- The workflow based approach with some kind of IDM workflow solution (keeps the IDM consultant’s job safe)
- The scripting agent approach by extending the Exchange cmdlets (keeps your job safe, is fun, keeps you in control, and get’s you more free time)
The Exchange cmdlet extension is controlled by a scripting agent configuration file and an organizational setting to enable/disable the scripting agent.
Preparation
A scripting agent configuration file sample (ScriptingAgentConfig.xml.sample) is located in
- $exinstallBinCmdletExtensionAgents
The sample needs to be renamed to ScriptingAgentConfig.xml, to be picked up by the PowerShell engine.
As always, a slight reminder: Test any modification in a test environment first, before you use the extension in a production environment.
After successful testing and deployment, you need to enable the scripting agent using
Enable-CmdletExtensionAgent "Scripting Agent"
Example
Even though you can extend mostly any Exchange cmdlet, this example covers the extension of the New-Mailbox and Enable-Mailbox cmdlets in a multi-domain and multi AD site environment.
This extension disables the following CAS mailbox settings after a new mailbox has been created:
- ActiveSync
- IMAP4
- POP3
- MAPI over HTTP
What does the example do?
- The extension is named MailboxProvisioning and handles the cmdlets New-Mailbox and Enable-Mailbox
- Is called on trigger OnComplete
- The extension code is called after the original cmdlet has finished
- Code is executed, if the original cmdlet was successfully finished
- Code is executed, if the mailbox created is not an archive
- A slight delay of 10 seconds ensures that domain controller activities have been finished
- Can be adjusted or even removed, depending on your environment
- Try to fetch at least one of three user parameters to identify the user mailbox
- Checking for Identity, Name, Alias
- Fetch a list of all domain controllers in the current AD site where the Exchange server is located
- Iterate through the list of domain controllers and try to fetch the new CAS mailbox
- If fetched, remember the domain controller’s FQDN
- Change the CAS mailbox settings as needed and use the remembered domain controller as DC to write to
If ($succeeded) { if (!($provisioningHandler.UserSpecifiedParameters.Archive -eq $true)) { # delay execution for 10 seconds, adjust as needed Start-Sleep -s 10 # validate parameters to use a not null parameter if ($null -ne $provisioningHandler.UserSpecifiedParameters["Identity"]) { $user = $provisioningHandler.UserSpecifiedParameters["Identity"].ToString() } } elseif ($null -ne $provisioningHandler.UserSpecifiedParameters["Name"]) { $user = $provisioningHandler.UserSpecifiedParameters["Name"].ToString() } else { $user = $provisioningHandler.UserSpecifiedParameters["Alias"].ToString() } # view entire forest in a multi domain environment Set-AdServerSettings -ViewEntireForest:$true # fetch domain controllers in AD site $server = Get-ExchangeServer $env:computername $DCs = Get-DomainController | Where-Object { $_.adsite -eq $server.site } $CasMailbox = $null foreach ($d in $DCs) { while ($null -eq $CasMailbox) { # find a valid domain controller having the updated user object $CasMailbox = Get-CASMailbox $user -DomainController $d.dnshostname -ErrorAction SilentlyContinue # fetch DCs FQDN $WriteDC = $d.DnsHostName break } } try { # set CAS features as needed Set-CasMailbox $user -ActiveSyncEnabled:$false -ImapEnabled:$false -PopEnabled:$false -MapiHttpEnabled:$false -DomainController $WriteDC -ErrorAction SilentlyContinue } catch {} }
Notes
After adding the PowerShell code to the ScriptingAgentConfig.xml file, the file needs to be distributed across all Exchange servers. For distribution of the scripting agent configuration file, I personally recommend Paul Cunningham’s PowerShell script.
Be aware of the fact, that the scripting agent Xml is being validated using a strict schema validation. The scripting agent XML is case sensitive, as noted here.