Who changed that email address policy? Who dismounted that database? Who granted that person access to the CEO’s mailbox?

As an Exchange administrator those are all the type of questions you could be asked quite regularly, especially if you work in a large IT team with many administrators making changes on a daily basis.

Fortunately, ever since Exchange Server 2010 we’ve been able to answer those questions using administrator audit logging. Admin audit logging captures all changes made my administrators using the Exchange management tools (PowerShell cmdlets, or the Exchange Admin Center). Only commands that make changes are logged, for example Remove-Mailbox, whereas commands that do not cause changes are not logged, such as Get-Mailbox.

Configuring Administrator Audit Logging

Admin audit logging has the following default configuration.

  • Admin audit logging is enabled.
  • 90 days of log retention.
  • All cmdlets that can make modifications are audited.
  • All parameters of the above cmdlets are logged.
  • Test cmdlets (such as Test-MAPIConnectivity) are not logged.
  • Log level of “none”, which doesn’t mean nothing is logged, it just logs details of the command that was run, who ran it, and which object they modified. The other option is “verbose” which also logs the old and new properties of the object that were modified by the command.

Admin audit logging can be disabled, or the config modified to limit the cmdlets or parameters that are audited, or to modify the log retention period. For this reason you should limit the ability of administrators in your organization to modify the admin audit log settings. By default this right is granted to members of Organization Management and Records Management. I recommend you review your RBAC role group membership to ensure that only the most trusted administrators are members of those groups.

Note that any changes made to the admin audit log config are logged in the admin audit logs, regardless of whether admin audit logging is enabled or disabled. So in theory you should see evidence of any tampering that has occurred.

Searching Administrator Audit Logs

Admin audit logs are reasonably simple to search using the Exchange management shell. There’s a few different approaches you can take:

  • Search for a specific cmdlet or cmdlets
  • Search within a specific date range
  • Search for actions taken by a specific administrator
  • Search for actions taken against a specific object

You can also combine the above by using multiple parameters in your search.

Let’s take a look at a simple example – someone has granted the user Alex Heyne access to the CEO Alannah Shaw’s mailbox. We know this is done using the Add-MailboxPermission cmdlet, so we can use the –Cmdlets parameter for Search-AdminAuditLog to run the search.

[PS] C:\>Search-AdminAuditLog -Cmdlets Add-MailboxPermission


RunspaceId         : f6553abe-9d57-40bc-8e43-dc919bea2b50
ObjectModified     : exchange2013demo.com/ExchangeUsers/Alannah.Shaw
CmdletName         : Add-MailboxPermission
CmdletParameters   : {User, AccessRights, Identity}
ModifiedProperties : {}
Caller             : exchange2013demo.com/Users/Administrator
ExternalAccess     : False
Succeeded          : True
Error              :
RunDate            : 22/09/2015 4:35:33 PM
OriginatingServer  : SYDEX2 (15.00.1076.011)
Identity           : AAMkADI1NGQyZjhiLTFkYTAtNDhmYy05OTBiLTU4MGZlODY0MDQ3NgBGAAAAAAAkqZy/nl4jSa4VBIka73bMBwCEoBRTwPA6QK
                     t9HgzDn/p6AAAAAAEYAACEoBRTwPA6QKt9HgzDn/p6AACUBtrhAAA=
IsValid            : True
ObjectState        : New

Another approach for the same scenario would be to look for modifications to the object “Alannah.Shaw” by using the -ObjectIds parameter. In this example it gives us exactly the same result, but you can imagine that other modifications may have been made to the same object and that multiple log entries would appear in many real world environments.

[PS] C:\>Search-AdminAuditLog -ObjectIds Alannah.Shaw


RunspaceId         : f6553abe-9d57-40bc-8e43-dc919bea2b50
ObjectModified     : exchange2013demo.com/ExchangeUsers/Alannah.Shaw
CmdletName         : Add-MailboxPermission
CmdletParameters   : {User, AccessRights, Identity}
ModifiedProperties : {}
Caller             : exchange2013demo.com/Users/Administrator
ExternalAccess     : False
Succeeded          : True
Error              :
RunDate            : 22/09/2015 4:35:33 PM
OriginatingServer  : SYDEX2 (15.00.1076.011)
Identity           : AAMkADI1NGQyZjhiLTFkYTAtNDhmYy05OTBiLTU4MGZlODY0MDQ3NgBGAAAAAAAkqZy/nl4jSa4VBIka73bMBwCEoBRTwPA6QK
                     t9HgzDn/p6AAAAAAEYAACEoBRTwPA6QKt9HgzDn/p6AACUBtrhAAA=
IsValid            : True
ObjectState        : New

Searches can be limited to specific date ranges. Here’s how to search for modifications made by “Administrator” in the last 30 days.

[PS] C:\>Search-AdminAuditLog -UserIds Administrator -StartDate (Get-Date).AddDays(-30)

A lot of results were returned, so I haven’t displayed them. But let’s say that I wanted to know just the object IDs that “Administrator” had modified in the last 30 days.

[PS] C:\>$logentries = Search-AdminAuditLog -UserIds Administrator -StartDate (Get-Date).AddDays(-30)

[PS] C:\>$logentries.ObjectModified
SYDEX2
SYDEX2mapi (Default Web Site)
SYDEX2OAB (Default Web Site)
SYDEX2EWS (Default Web Site)
SYDEX2Microsoft-Server-ActiveSync (Default Web Site)
SYDEX2ecp (Default Web Site)
SYDEX2owa (Default Web Site)
SYDEX2Rpc (Default Web Site)
SYDEX1
SYDEX1mapi (Default Web Site)
SYDEX1OAB (Default Web Site)
SYDEX1EWS (Default Web Site)
SYDEX1Microsoft-Server-ActiveSync (Default Web Site)
SYDEX1ecp (Default Web Site)
SYDEX1owa (Default Web Site)
SYDEX1Rpc (Default Web Site)
SYDEX2
SYDEX2mapi (Default Web Site)
SYDEX2OAB (Default Web Site)
SYDEX2EWS (Default Web Site)
SYDEX2Microsoft-Server-ActiveSync (Default Web Site)
SYDEX2ecp (Default Web Site)
SYDEX2owa (Default Web Site)
DB04MELEX1
SYDEX2Rpc (Default Web Site)
SYDEX1
SYDEX1mapi (Default Web Site)
SYDEX1OAB (Default Web Site)
SYDEX1EWS (Default Web Site)
SYDEX1Microsoft-Server-ActiveSync (Default Web Site)
SYDEX1ecp (Default Web Site)
SYDEX1owa (Default Web Site)
SYDEX1Rpc (Default Web Site)
DB03MELEX1
SYDEX2owa (Default Web Site)
SYDEX1
SYDEX1mapi (Default Web Site)
SYDEX1OAB (Default Web Site)
SYDEX1EWS (Default Web Site)
SYDEX1Microsoft-Server-ActiveSync (Default Web Site)
SYDEX1ecp (Default Web Site)
DB01MELEX1
DB04MELEX1
DB03MELEX1
DB02MELEX1
DB01MELEX1
MELEX2
MELEX1
SYDEX2
SYDEX1

Looks like “Administrator” has been messing with virtual directories and databases. Let’s make it even more useful and look at the time stamp, cmdlet, and objects modified by “Administrator” in the last 30 days.

[PS] C:\>$logentries | Select RunDate,CmdletName,CmdletParameters,ObjectModified

RunDate                       CmdletName                    CmdletParameters              ObjectModified
-------                       ----------                    ----------------              --------------
27/08/2015 11:51:35 AM        Set-ClientAccessServer        {AutoDiscoverServiceIntern... SYDEX2
27/08/2015 11:51:33 AM        Set-MapiVirtualDirectory      {ExternalUrl, InternalUrl,... SYDEX2mapi (Default Web S...
27/08/2015 11:51:19 AM        Set-OabVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2OAB (Default Web Site)
27/08/2015 11:50:51 AM        Set-WebServicesVirtualDire... {ExternalUrl, InternalUrl,... SYDEX2EWS (Default Web Site)
27/08/2015 11:49:55 AM        Set-ActiveSyncVirtualDirec... {ExternalUrl, InternalUrl,... SYDEX2Microsoft-Server-Ac...
27/08/2015 11:48:56 AM        Set-EcpVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2ecp (Default Web Site)
27/08/2015 11:47:39 AM        Set-OwaVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2owa (Default Web Site)
27/08/2015 11:46:13 AM        Set-OutlookAnywhere           {DefaultAuthenticationMeth... SYDEX2Rpc (Default Web Site)
27/08/2015 11:46:02 AM        Set-ClientAccessServer        {AutoDiscoverServiceIntern... SYDEX1
27/08/2015 11:46:02 AM        Set-MapiVirtualDirectory      {ExternalUrl, InternalUrl,... SYDEX1mapi (Default Web S...
27/08/2015 11:46:01 AM        Set-OabVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1OAB (Default Web Site)
27/08/2015 11:45:59 AM        Set-WebServicesVirtualDire... {ExternalUrl, InternalUrl,... SYDEX1EWS (Default Web Site)
27/08/2015 11:45:57 AM        Set-ActiveSyncVirtualDirec... {ExternalUrl, InternalUrl,... SYDEX1Microsoft-Server-Ac...
27/08/2015 11:45:53 AM        Set-EcpVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1ecp (Default Web Site)
27/08/2015 11:45:47 AM        Set-OwaVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1owa (Default Web Site)
27/08/2015 11:45:40 AM        Set-OutlookAnywhere           {DefaultAuthenticationMeth... SYDEX1Rpc (Default Web Site)
27/08/2015 11:40:03 AM        Set-ClientAccessServer        {AutoDiscoverServiceIntern... SYDEX2
27/08/2015 11:40:01 AM        Set-MapiVirtualDirectory      {ExternalUrl, InternalUrl,... SYDEX2mapi (Default Web S...
27/08/2015 11:39:47 AM        Set-OabVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2OAB (Default Web Site)
27/08/2015 11:39:25 AM        Set-WebServicesVirtualDire... {ExternalUrl, InternalUrl,... SYDEX2EWS (Default Web Site)
27/08/2015 11:38:34 AM        Set-ActiveSyncVirtualDirec... {ExternalUrl, InternalUrl,... SYDEX2Microsoft-Server-Ac...
27/08/2015 11:37:34 AM        Set-EcpVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2ecp (Default Web Site)
27/08/2015 11:36:06 AM        Set-OwaVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2owa (Default Web Site)
27/08/2015 11:35:59 AM        Update-MailboxDatabaseCopy    {DeleteExistingFiles, Conf... DB04MELEX1
27/08/2015 11:34:38 AM        Set-OutlookAnywhere           {DefaultAuthenticationMeth... SYDEX2Rpc (Default Web Site)
27/08/2015 11:34:26 AM        Set-ClientAccessServer        {AutoDiscoverServiceIntern... SYDEX1
27/08/2015 11:34:25 AM        Set-MapiVirtualDirectory      {ExternalUrl, InternalUrl,... SYDEX1mapi (Default Web S...
27/08/2015 11:34:24 AM        Set-OabVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1OAB (Default Web Site)
27/08/2015 11:34:21 AM        Set-WebServicesVirtualDire... {ExternalUrl, InternalUrl,... SYDEX1EWS (Default Web Site)
27/08/2015 11:34:18 AM        Set-ActiveSyncVirtualDirec... {ExternalUrl, InternalUrl,... SYDEX1Microsoft-Server-Ac...
27/08/2015 11:34:12 AM        Set-EcpVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1ecp (Default Web Site)
27/08/2015 11:34:08 AM        Set-OwaVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1owa (Default Web Site)
27/08/2015 11:34:00 AM        Set-OutlookAnywhere           {DefaultAuthenticationMeth... SYDEX1Rpc (Default Web Site)
27/08/2015 11:27:33 AM        Update-MailboxDatabaseCopy    {DeleteExistingFiles, Conf... DB03MELEX1
27/08/2015 11:26:30 AM        Set-OwaVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX2owa (Default Web Site)
27/08/2015 11:25:14 AM        Set-ClientAccessServer        {AutoDiscoverServiceIntern... SYDEX1
27/08/2015 11:25:07 AM        Set-MapiVirtualDirectory      {ExternalUrl, InternalUrl,... SYDEX1mapi (Default Web S...
27/08/2015 11:25:04 AM        Set-OabVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1OAB (Default Web Site)
27/08/2015 11:25:02 AM        Set-WebServicesVirtualDire... {ExternalUrl, InternalUrl,... SYDEX1EWS (Default Web Site)
27/08/2015 11:24:59 AM        Set-ActiveSyncVirtualDirec... {ExternalUrl, InternalUrl,... SYDEX1Microsoft-Server-Ac...
27/08/2015 11:24:47 AM        Set-EcpVirtualDirectory       {ExternalUrl, InternalUrl,... SYDEX1ecp (Default Web Site)
27/08/2015 11:13:30 AM        Update-MailboxDatabaseCopy    {DeleteExistingFiles, Conf... DB01MELEX1
27/08/2015 10:42:12 AM        Suspend-MailboxDatabaseCopy   {Identity}                    DB04MELEX1
27/08/2015 10:42:11 AM        Suspend-MailboxDatabaseCopy   {Identity}                    DB03MELEX1
27/08/2015 10:42:11 AM        Suspend-MailboxDatabaseCopy   {Identity}                    DB02MELEX1
27/08/2015 10:42:09 AM        Suspend-MailboxDatabaseCopy   {Identity}                    DB01MELEX1
26/08/2015 12:10:24 PM        Set-ExchangeServer            {ProductKey, Identity}        MELEX2
26/08/2015 12:10:23 PM        Set-ExchangeServer            {ProductKey, Identity}        MELEX1
26/08/2015 12:10:22 PM        Set-ExchangeServer            {ProductKey, Identity}        SYDEX2
26/08/2015 12:10:11 PM        Set-ExchangeServer            {ProductKey, Identity}        SYDEX1

Summary

As you can see administrator audit logging contains a lot of valuable information to help you identify who has been making changes in your Exchange organization. You can also see why it is important to limit administrative rights to only the minimum that each IT team member needs to do their job.

About the Author

Paul Cunningham

Paul is a former Microsoft MVP for Office Apps and Services. He works as a consultant, writer, and trainer specializing in Office 365 and Exchange Server. Paul no longer writes for Practical365.com.

Comments

  1. Josue

    Same here, It does happen on Exchange Online though.

    1. Avatar photo
      Tony Redmond

      This is a very old article (2015). Today, we would use the Office 365 audit log (aka the unified log) to search for information, including Exchange Online admin actions. For example, here’s how to find all Set-Mailbox actions performed today. The identities returned in these records are a lot easier to deal with.

      Search-UnifiedAuditLog -Operations Set-Mailbox -StartDate 22-Apr-2021 -EndDate 23-apr-2021 -Formatted -ResultSize 1000 | ft creationdate, userids, operations

  2. Taner

    Hi;
    On your first example, how can you find the user is Alex by using identity field:
    Identity : AAMkADI1NGQyZjhiLTFkYTAtNDhmYy05OTBiLTU4MGZlODY0MDQ3NgBGAAAAAAAkqZy/nl4jSa4VBIka73bMBwCEoBRTwPA6QK
    t9HgzDn/p6AAAAAAEYAACEoBRTwPA6QKt9HgzDn/p6AACUBtrhAAA=

  3. Francesco

    Hi Paul
    i’ve got an Exchange 2016 CU18. I use search-adminauditlog to track what admin do. But result is partial or incomplete.
    What can i check to have the right report?
    i try to set-new or create and modify new send connector, but nothing trace in report admin search.
    Tx for your help.

  4. Allan Jimmy

    Hello Paul,

    Is there a way to find which sender we blocked in our HostedContentFilterPolicy in Exchange Online Protection

    Search-adminauditlog -cmdlets set-hostedcontentfilterpolicy -startdate -enddate | select objectmodified, caller, rundate

    Using the above command (even with FL), I cannot get to find which sending address was blocked. It shows us the policy that was modified but not the value

  5. Shawn

    I like this article very much. What about exporting this so it can be saved / emailed to auditor?

  6. Reza Ghazian

    Dear Paul

    I’m trying to create an automatic welcome message for new users . I ‘v done all the setting the same as in my experimental and operational environment . but it works well in my experimental enviroment that is exchange 2016 but i get an error in exchange 2013 which the event ID is 5000

    Log content:
    Cmdlet Name: Enable-Mailbox
    Object Modified: mapnagenerator.com/Domain Users/zzzz/Test
    Parameter: Identity = Test
    Parameter: Database = Mailbox Database 1613186978
    Caller: mapnagenerator.com/Domain Users/ICT Unit/Ghazian, Reza
    ExternalAccess: False
    Succeeded: True
    Run Date: 2018-09-24T12:15:12
    OriginatingServer: XERXES-2 (15.00.1210.002)

    Error:
    Microsoft.Exchange.Data.ApplicationLogic.AuditLogException: An error occurred while trying to access the audit log. For more details, see the inner exception. —> System.Net.WebException: The request failed with an empty response.
    at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
    at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

  7. Honey19

    Is it possible to check when a specific mailbox audit logging was enabled?

  8. Dmitry Alferov

    Hello, Paul!
    Sometimes field “Caller” contains only value “********” (8 asterics).
    Who is it? How to identify that user?

      1. Rudolf

        Hi Paul,
        is there an answer? I can see the same in Exchange 2013 CU19

      2. Josue

        Same here, It does happen on Exchange Online though.

  9. Shelly

    Hello Paul, i have a customer, he only wants to export the admin audit report from the GUI. However, he received below errors: “we apologize for the inconvenience. An unexpected error occurred while your search request was being processed”. We tried to perform new-mailboxreportrequest for that systemmailbox, issue persists. Could you give us some guideline for this? thank you.

  10. Dave Medlicott

    Hi Paul,

    I am a CSP and so have a large number of tenants to turn Audit logging on for. Is it possible to turn Audit logging on via PowerShell?

    Thanks
    Dave

    1. Avatar photo
      Paul Cunningham

      It’s already enabled by default. If you want to adjust the config you can do it with the Set-AdminAuditLogConfig cmdlet.

  11. Roberto Oliveira

    Thank you a lot for all your Exchange articles, Paul!
    On searching the audit log, if one suspects a rogue admin may be granting access to user mailboxes, is there a way to read who the rights are being granted to?
    In your case, above, you say someone “granted the user Alex Heyne access to the CEO Alannah Shaw’s mailbox”. If Alex Heyne logged in as user “administrator”, did that, read what he needed, then again as “administrator” removed that access, the ‘caller’, as in your example, would be administrator. How would we find out who administrator granted access to?
    Thanks!

    1. Avatar photo
      Paul Cunningham

      It’s stored in the ModifiedProperties, but not visible in the default PS output.

      (Search-AdminAuditLog -Cmdlets Add-MailboxPermission).ModifiedProperties

      ^^^ should show it. Play around with that until you get the full results you’re interested in.

  12. Ed Kummel

    Thank you Paul for all your contributions. I use your stuff on a daily basis. We recently got the edict to implement auditing for admins and mailboxes. I’ve done all the necessary tasks and can download audit logs all day long….from the EMS.
    But, if I open a generic Powershell session (Powershell version 4.0), add the Exchange Powershell snapins and then run the Search-AdminAuditLog from there, we get a weird error that says:
    search-adminauditlog : The attempt to search the administrator audit log failed. Please try again later.
    Checking the Event Logs, I find the error in the MSExchange Management Event log.
    Microsoft.Exchange.Management.SystemConfigurationTasks.AdminAuditLogSearchException: The attempt to search the administrator audit log failed. Please try again later. —> Microsoft.Exchange.Data.ApplicationLogic.AuditLogAccessDeniedException: The requesting account doesn’t have permission to access the audit log. —> System.Web.Services.Protocols.SoapException: The requesting account does not have permission to serialize tokens.

    Every other Exchange command runs in this Powershell session *EXCEPT* those commands relating to Audit logs.
    I am also starting the Powershell session with a runas administrator. And if I do a “whoami”, it returns my organizational Administrator account.

    I’ve scoured the web for details on this, but the results are always talking about the EMS, not a generic Powershell session.

    Any ideas?

    1. Avatar photo
      Paul Cunningham

      It’s not supported or recommended to load the Exchange snapins into a regular PS console like that, except for specific scenarios under the guidance of MS Support. One of the reasons being that it bypasses RBAC. I suspect what you’re seeing is a symptom of that.

  13. theresa

    Noticed when Partners are set up to manage a tenant, new accounts, changes and disabled accounts do not show up in the audit log of the targeted tenant. By design, or bug?

  14. thoufeeq

    Hi,
    In Exchange 2016, the Search-AdminAuditLog returns UPN as caller which was Canonical Name in the previous versions of Exchange. Is there any way to get Canonical Name as Caller ?

  15. jerry

    How does one figure out which mailbox is assigned as the destination for the storage of the audit logs ?

    1. Avatar photo
      Paul Cunningham

      Audit logs are stored centrally, they’re stored in each mailbox.

      1. Yehuda Matan

        Hey Paul, what do you mean “logs are stored in each mailbox”?
        is there a way to import these logs into a 3rd party app for monitoring and alerting purposes?

        10x

  16. Eric

    Hi,
    Can someone please help me figure out how to get a more useful username out of the .CmdletParameters value. Currently when you run this command…

    (Search-AdminAuditLog –cmdlets Add-MailboxPermission).CmdletParameters

    It returns the following,

    Identity Lab Test 01
    AccessRights FullAccess
    InheritanceType All
    User NAMPR06A002Eric 577832002717381

    The “User” is who I granted full access to. How am I supposed to make sense of that data? Anyone know how to get it to return samaccountname or something?

    -Eric

  17. Jason Meyer

    Excellent article as always. I’m trying to determine why some admin events are not showing up in my Admin Log. Like simple mail enables, I’m finding that about 95% of them ARE showing up, and about 5% are not. So far haven’t found any differences in how the 5% are enabled.

  18. Scott Thompson

    Hello again Paul…I have been asked a couple of questions by one of our auditors and I am struggling to find any solid answers. I hope that you might be able to assist.

    1. Can anyone with access to the eDiscovery portal (via the RBAC) see ALL the previously created and stored searches regardless of who created them?

    2. What audit trails are available in eDiscovery. Can I retrieve reports about who created, modified, and deleted searches along with details such as search criteria and what was done with the results (run, previewed, exported, etc)?

    Thanks

    Scott

  19. Terrance Brennan

    Unfortunately, not everything done by an Admin is logged. If you open a Windows PowerShell window and load the Exchange module nothing is recorded in the audit logs. Only actions performed in the EMS are recorded.

    1. Avatar photo
      Paul Cunningham

      I can also just go into ADUC or ADSIEdit and make changes, and those won’t be logged by this feature.

      All part of a larger picture of auditing.

  20. Dinesh

    Hi, I set the AdminAuditLog for 120 days with below command

    Set-AdminAuditLogConfig -AdminAuditLogAgeLimit 120.00:00:00

    when i search the logs with help of below cmdlet, it was not showing more that 1 week logs.

    Search-AdminAuditLog -StartDate 07/05/2015 -EndDate 09/20/2015

    Could you help me on this.

    Thank you.

Leave a Reply