Just can't get enough of IT

This blog is about mostly anything in IT. But the primary focuses are Microsoft Technologies like Exchange, Office 365, Azure and Cloud Security.

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 using 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 a organizational setting to enable/disable the scripting agent.


A scripting agent configuration file sample (ScriptingAgentConfig.xml.sample) is located in

  • $exinstall\Bin\CmdletExtensionAgents

The sample needs to be renamed to ScriptingAgentConfig.xml, to be picked up 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 succesfull testing and deployment, you need to enable the scripting agent using

Enable-CmdletExtensionAgent "Scripting Agent"


Even thought that 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?

  • 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 on 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


<?xml version="1.0" encoding="utf-8" ?>
  <Configuration version="1.0">
	<Feature Name="MailboxProvisioning" Cmdlets="New-Mailbox,Enable-Mailbox">
		<ApiCall Name="OnComplete">
			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 ($provisioningHandler.UserSpecifiedParameters["Identity"] -ne $null) {
						$user = $provisioningHandler.UserSpecifiedParameters["Identity"].ToString()
					elseif ($provisioningHandler.UserSpecifiedParameters["Name"] -ne $null) {
						$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 | ?{$_.adsite -eq $}
					$CasMailbox = $null
					foreach($d in $DCs) {
						while($CasMailbox -eq $null) {
							# 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
					try {
						# set CAS features as needed
						Set-CasMailbox $user -ActiveSyncEnabled:$false -ImapEnabled:$false -PopEnabled:$false -MapiHttpEnabled:$false -DomainController $WriteDC -ErrorAction SilentlyContinue
					catch {}


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.


Read More »

The community script Update-CASMailbox simplifies the process for enabling or disabling protocols for Exchange mailbox access. Active Directory security groups are used to enable or disable a protocol for the group members.


Your Active Directory contains a security group named Exchange_POP_enabled which contains all mailbox users requiring POP3 access to be enabled.

You can use the following command to have POP3 enabled for all members of the given security group.

.\Update-CAS-Mailbox.ps1 -POP -FeatureEnabled $true -GroupName Exchange_POP_enabled

The script does not disable the POP3 for all non-members, as this might not be required as all new mailboxes have POP3 disabled anyway. If there is such a requirement, just let me know.

The following protocols are currently supported:

  • POP
  • IMAP
  • Outlook on the Web (OWA)
  • ActiveSync



You need assistance with your Exchange Server setup? You have questions about your Exchange Server infrastructure and going hybrid with Office 365? You are interested in what Exchange Server 2016 has to offer for your environment?

Contact me at
Follow at

Read More »
On April 22, 2016
0 Comment

The PowerShell script Get-Diskspace.ps1 uses a pretty basic inline CSS approach to generate a more nicely html email from a PowerShell output.

You can use the following description for your own PowerShell script.

First a new html block is configured and the inline CSS is embedded into the head tag.

# Some CSS to get a pretty report
# Variable containing the inline CSS and the full html head tag
$head = @'
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "">
<style type=”text/css”>
body {
    font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
h2{ clear: both; font-size: 100%;color:#354B5E; }
    clear: both;
    font-size: 75%;
    margin-left: 20px;
    margin-top: 30px;
    border-collapse: collapse;
    border: none;
    font: 10pt Verdana, Geneva, Arial, Helvetica, sans-serif;
    color: black;
    margin-bottom: 10px;
table td{
    font-size: 12px;
    padding-left: 0px;
    padding-right: 20px;
    text-align: left;
table th {
    font-size: 12px;
    font-weight: bold;
    padding-left: 0px;
    padding-right: 20px;
    text-align: left;

The recurring data content is added to a global varibale using the -Fragment attribute. This ensures that no full html document data is being created.

$global:Html += $wmi | ConvertTo-Html -Fragment -PreContent "<h2>Server $($ServerName)</h2>"

Before sending the html result the full body html is generated by combinding the html fragments and the manually defined html head.

[string]$Body = ConvertTo-Html -Body $global:Html -Title "Status" -Head $head

Send-Mail -From $MailFrom -To $MailTo -SmtpServer $MailServer -MessageBody $Body -Subject $ReportTitle  


Read More »

The new community script Get-Diskspace helps to fetch disk volume information from a single server or across multiple servers.

Currently the script supports a command line switch to gather disk volume information across all Exchange servers in your environment.

The following screenshot shows the command line output

Screenshot command line output

The following screenshot shows the html email

Screenshot html email

# Get disk information from computer MYSERVER
.\Get-Diskpace.ps1 -ComputerName MYSERVER

# Get disk information from computer MYSERVER in MB

.\Get-Diskpace.ps1 -ComputerName MYSERVER -Unit MB

# Get disk information from all Exchange servers and send html email

.\Get-Diskpace.ps1 -AllExchangeServer -SendMail -MailFrom -MailTo -MailServer





You need assistance with your Exchange Server setup? You have questions about your Exchange Server infrastructure and going hybrid? You are interested in what Exchange Server 2016 has to offer for your environment?

Contact me at
Follow at

Read More »
On April 16, 2016
0 Comment

Sometimes you need to know the version of the installed .NET Framework version quickly.

Simply use the following PowerShell one-liner:

(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' ).Release
DWORD Value Version
378389 .NET Framework 4.5
378675 .NET Framework 4.5.1 installed with Windows 8.1 or Windows Server 2012 R2
378758 .NET Framework 4.5.1 installed on Windows 8, Windows 7 SP1, or Windows Vista SP2
379893 .NET Framework 4.5.2
On Windows 10: 393295
All other OS: 393297
.NET Framework 4.6
On Windows 10 November Update: 394254
All other OS: 394271
.NET Framework 4.6.1
On Windows 10 Insider Build 14295: 394747
All other OS: 394748
.NET Framework 4.6.2 Preview




Read More »