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.
The attempt to search the administrator audit log failed. Please try again later.
+ CategoryInfo : NotSpecified: (:) [Search-AdminAuditLog], AdminAuditLogSearchException
+ FullyQualifiedErrorId : [Server=EXSVRN1,RequestId=39b0a657-51c1-4c0f-b05b-a16796ca66f5,TimeStamp=10/05/2024 05:5
9:15] [FailureCategory=Cmdlet-AdminAuditLogSearchException] C9C326B,Microsoft.Exchange.Management.SystemConfigurat
ionTasks.SearchAdminAuditLog
+ PSComputerName : exsvrn1.amanabank.int
Microsoft has retired the admin log cmdlets from Exchange Online. You should use the Search-UnifiedAuditLog cmdlet to look for audit events.
Same here, It does happen on Exchange Online though.
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
More here: https://office365itpros.com/2020/10/08/search-office-365-audit-log-object-specific-events/
Hello Tony,
Thank you for the details.
I want to who made ‘Retention Policy’ changes on a mailbox. Unfortunately, MS doesn’t have the retention policy audits as they say.
I was hoping if you can help!
Which retention? Mailbox retention (Exchange legacy) or Microsoft 365 retention? Via direct assignment or All? Via static assignment or adaptive scope?
Hi;
On your first example, how can you find the user is Alex by using identity field:
Identity : AAMkADI1NGQyZjhiLTFkYTAtNDhmYy05OTBiLTU4MGZlODY0MDQ3NgBGAAAAAAAkqZy/nl4jSa4VBIka73bMBwCEoBRTwPA6QK
t9HgzDn/p6AAAAAAEYAACEoBRTwPA6QKt9HgzDn/p6AACUBtrhAAA=
Could yo get an answer or fidn a solution for this?
farukdemirel@gmail.com
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.
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
I like this article very much. What about exporting this so it can be saved / emailed to auditor?
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)
…
Is it possible to check when a specific mailbox audit logging was enabled?
Hello, Paul!
Sometimes field “Caller” contains only value “********” (8 asterics).
Who is it? How to identify that user?
Which version of Exchange?
Hi Paul,
is there an answer? I can see the same in Exchange 2013 CU19
Same here, It does happen on Exchange Online though.
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.
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
It’s already enabled by default. If you want to adjust the config you can do it with the Set-AdminAuditLogConfig cmdlet.
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!
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.
Roberto,
I couldn’t get Paul’s reply below to work, so after a good amount of searching I found the answer at: https://blogs.technet.microsoft.com/exchange/2015/06/15/parsing-the-admin-audit-logs-with-powershell/
Set your search to a variable then $Search.CmdletParameters
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?
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.
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?
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 ?
How does one figure out which mailbox is assigned as the destination for the storage of the audit logs ?
Audit logs are stored centrally, they’re stored in each mailbox.
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
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
Pingback: Exchange Best Practices: Admin Access to User Mailboxes
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.
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
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.
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.
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.
What was it set to before you changed it to 120 days?