In this latest instalment to MSPFE, Kostas Nomikos demonstrates the flexibility of the Exchange Scripting Agent. This is a sample to show how the Scripting Agent can be used with a custom event log. Please note that this is not intended to replace Exchange Admin Audit Logging or Mailbox Audit Logging. This can enhance those in-box features to meet customer specific requests.
Exchange is an extremely versatile collaborative platform. As such it is a repository that will contain confidential information in the form of email. If I asked you what are the most critical mailboxes in an organization, what would you say? Typically this is the C-level (CEO, CFO, COO). These mailboxes are the most important since they contain business-critical information, such as details about the strategy of the company and sensitive projects. These mailboxes require our close attention. When we care about something, should we not monitor it closely?
Let’s see how we can generate custom event log entries which track permission changes on the mailboxes we care most about. To do that, we will have to use the Exchange scripting agent, please review the documentation provided there.
In this blog post, our goal is to generate an event in Event Viewer every time we assign Full Access permission to a predefined list of critical mailboxes.
First things first, we need the code:
Scripting Agent Code
Please copy the below:
<?xml version="1.0" encoding="utf-8" ?>
This script is provided AS IS without warranty of any kind. It is strongly recommended that you test it in a lab environment before moving into production.
<Feature Name="EventWrite" Cmdlets="Add-MailboxPermission">
$GrantedPermissionUser = $provisioningHandler.UserSpecifiedParameters["User"]
$identity = Get-Mailbox $provisioningHandler.UserSpecifiedParameters["Identity"]
$Alias = (Get-Mailbox "$identity").alias
$AccessRights = $provisioningHandler.UserSpecifiedParameters["AccessRights"]
if ($AccessRights -eq "FullAccess")
if ( @("CEO_Alias","CFO_Alias","COO_Alias") -like $alias)
write-eventlog -logname Application -source MailboxAudit -eventID 100 -entrytype Error -message "$GrantedPermissionUser was given Full Mailbox Access to $identity's Mailbox."
Enabling Exchange Scripting Agent
It’s not too hard to understand what the script does. Every time we run the Add-MailboxPermission cmdlet, it compares the alias of the user on which we are changing mailbox permissions with every one of the three aliases of the top level managers. This is the contents of the array: [@("CEO_Alias","CFO_Alias","COO_Alias")]. If the condition is true, the script generates an error in Event Viewer. The scripting agent (and the script behind it) is consulted every time an Exchange cmdlet runs. It will only perform work if the command being executed is within the scope of the scripting agent configuration. It just writes an event only when we run the Add-MailboxPermission cmdlet and when the if-condition is true.
For the Scripting Agent to use this script, we need to create an xml file, named ScriptingAgentConfig.xml, paste the script and copy the file in the <installation path>\V15\Bin\CmdletExtensionAgents folder on every Exchange server in the organization and also on all servers which have management tools installed. Please bear in mind that every time you change the configuration file (the ScriptingAgentConfig.xml) you must update it on every Exchange server. Exchange does not have a feature to replicate this file, you must do that.
Then, we need to register the custom event source “MailboxAudit” that is used by the script (again on every Exchange server):
New-EventLog -LogName Application -Source MailboxAudit
We are almost done. The last step is just to enable the Scripting Agent with the following cmdlet:
Enable-CmdletExtensionAgent "Scripting Agent"
Next time someone changes the mailbox permissions of your manager, an error is written in Event Viewer:
Now that you have the event, you can use a monitoring software, like SCOM to gather these events and alert to the security officer when necessary.
The script is tested on Exchange 2013 but it should run on Exchange 2010 too.
Please test this sample code thoroughly prior to implementing or executing in production.
This Sample Code is provided for the purpose of illustration only and is not intended to be used in a production environment. THIS SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. We grant You a nonexclusive, royalty-free right to use and modify the Sample Code and to reproduce and distribute the object code form of the Sample Code, provided that You agree: (i) to not use Our name, logo, or trademarks to market Your software product in which the Sample Code is embedded; (ii) to include a valid copyright notice on Your software product in which the Sample Code is embedded; and (iii) to indemnify, hold harmless, and defend Us and Our suppliers from and against any claims or lawsuits, including attorneys’ fees, that arise or result from the use or distribution of the Sample Code."
"This sample script is not supported under any Microsoft standard support program or service. The sample script is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages"
Published by MSPFE Editor Rhoderick Milne who is totally out of witty ripostes….