Exchange Audit Logging


Exchange Audit Logging

Exchange audit logging must be setup at the mailbox level and is outside the scope of this document. Please refer to help that is available from Microsoft for setting up Exchange Audit Logging.


To verify if you have Audit Logging enabled for some/all users, please use the following PowerShell command: Get-Mailbox | Format-List Audit*.  The output would look like this:

Setup Script

Setup the PowerShell Script

  1. Create a new file on the system called “C:\ExchangeAudit\Write-MailboxAuditLogEvents.ps1” and paste the contents of the script provided to you. You need to do this step so the system trusts the PowerShell script as locally created rather than download to the system.
  2. Create a new Event Source
    1. Open a PowerShell as Administrator
    2. Run the following command: New-EventLog -LogName Application -Source “Exchange Audit”

Setup Task Scheduler

Setup Task Scheduler

  1. Open Task Scheduler and “Create Basic Task..”
    1. Name "Exchange Audit Logging". Click Next.
    2. Select "When the Computer Starts". Click Next.
    3. Select "Start a program". Click Next.
    4. Program/Script "PowerShell"
      Add Arguments:
      -command "& C:\ExchangeAudit\Write-MailboxAuditLogEvents.ps1"
      Click Next.
    5.  Click “Open the Properties dialog for this task when I click Finish”. Click Finish.
    6. Verify/Set the following Properties settings
      General Tab:
             Click “Run whether user is logged on or not”
            Check “Run with highest privileges”
            Select “Configure For:” Windows Server 2012 R2
      Conditions Tab:
            All are checked
      Settings Tab:
           Check "Allow task to be run on demand"
           Check "If the running task does not end when requested, force it to stop"
           Select "Do not start a new instance"
      Click OK
    7. When the Properties Open, Select 'Triggers' Tab
      Edit the 'At startup' trigger
      Select 'Repeat Task every:' 1 hour
      Select 'Stop task if runs longer than' 30 minutes
    8. Verify Settings with the screen shots at the end of this document


Verify Setup

  1. Reboot system
  2. Verify Task was run at startup by checking the Task Scheduler
    1. Clock on Task Scheduler Library on left and Exchange Audit Logging should show Status of “Running”
  3. Verify Events are being written to the Event Log
    1. Open the Event Viewer and open the Application Events
    2. Verify that events with source 'Exchange Audit' are being written to the event



Get-MailboxAuditLoggingEvents.ps1 - Generate an Exchange Server mailbox audit logging report

This PowerShell script will generate Application Events for each Audit Log Entry for Each User

Results are output to Event Log - Application Events, "Exchange Audit" Source.
Source must be created prior to using this script.  Source can be created with the following command:
New-EventLog -LogName Application -Source "Exchange Audit"

How many hours in the past you want to query for. Default is 24 hours.

The mailbox to pull audit data for.  Default is all mailboxes

The Logontypes to pull data for.  Default is All: Delegate,Owner,Admin

.\Get-MailboxAuditLoggingReport.ps1 -Mailbox Payroll -Hours 48
Checks the Payroll mailbox for mailbox audit log entries from the last 48 hours.

.\Get-MailboxAuditLoggingReport.ps1 -Mailbox Payroll -hours 48 -SendEmail -MailFrom -MailTo -MailServer
Checks the Payroll mailbox for mailbox audit log entries from the last 48 hours
and sends the report email with the CSV file attached.

Originally Written by: Paul Cunningham
Find me on:
* My Blog:
* Twitter:
* LinkedIn:
* Github:
For more Exchange Server tips, tricks and news
check out Exchange Server Pro.
* Website:
* Twitter:
Modified by: Alex Hernandez
Change Log
V1.00, 12/02/2015 - Initial version.
V2.00, 12/10/2016 - Modified to support writing to Event Logs and query all mailboxes
#requires -version 2
param (
    [Parameter( Mandatory=$false)]
    [Parameter( Mandatory=$false)]
    [string]$LogonTypes = "Delegate,Owner,Admin",
    [Parameter( Mandatory=$false)]
    [int]$Hours = 48
# Variables
Write-Verbose "Variables"
$now = Get-Date                                         #Used for timestamps
$date = $now.ToShortDateString()                        #Short date format for email message subject
$localUtcOffset = [System.TimeZone]::CurrentTimeZone.GetUtcOffset([datetime]::Now).TotalHours
Write-Verbose $localUtcOffset
# Script
#Add Exchange 2010/2013 snapin if not already loaded in the PowerShell session
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"}))
        Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP
        #Snapin was not loaded
        Write-Warning $_.Exception.Message
    . $env:ExchangeInstallPath\bin\RemoteExchange.ps1
    Connect-ExchangeServer -auto -AllowClobber
$auditlogentries = @()
$mailboxes = @()
if ([string]::IsNullorEmpty($Mailbox)) {
    $mailboxlist = Get-Mailbox -ResultSize Unlimited
        foreach ($alias in $mailboxlist)
        $thisuser = Select-Object -InputObject $alias -Property Alias | %{$_.Alias}
        $mailboxes += $thisuser
else {
    $mailboxes += $mailbox
foreach ($thismailbox in $mailboxes)
    Write-Verbose $thismailbox
    $identity = (Get-Mailbox $thismailbox).Identity
    $auditlogentries = Search-MailboxAuditLog -Identity $identity -LogonTypes $logontypes -StartDate ($now).AddHours(-$hours) -ShowDetails
    if ($($auditlogentries.Count) -gt 0)
        foreach ($line in $auditlogentries)
            Write-Verbose $line
            $tmpitem = $line | Select-Object *
            $tmpline =  ([string]$tmpitem).trim("@","{","}") + $localUtcOffset
            Write-Verbose $tmpline
            Write-EventLog -LogName Application -Source "Exchange Audit" -EntryType Information -EventId 1 -Message $tmpline
$tmpitem = "This is a test event;"
$tmpline =  ([string]$tmpitem).trim("@","{","}") + "; localUtcOffset=" + $localUtcOffset
Write-Verbose $tmpline
Write-EventLog -LogName Application -Source "Exchange Audit" -EntryType Information -EventId 1 -Message $tmpline