• Home
  • Topics
    • Office 365
    • Teams
    • SharePoint Online
    • Exchange 2019
    • Exchange 2016
    • Exchange 2013
    • Hybrid
    • Certificates
    • PowerShell
    • Migration
    • Security
    • Azure
  • Blog
  • Podcast
  • Webinars
  • Books
  • About
  • Videos
    • Interview Videos
    • How To Guide Videos
  • Subscribe
    • Facebook
    • Twitter
    • RSS
    • YouTube

Practical 365

You are here: Home / Exchange Server / Get-MailboxAuditLoggingReport.ps1 – PowerShell Script to Generate a Report of Mailbox Audit Log Entries

Get-MailboxAuditLoggingReport.ps1 – PowerShell Script to Generate a Report of Mailbox Audit Log Entries

February 12, 2015 by Paul Cunningham 49 Comments

In Exchange Server environments where mailbox audit logging is used there may be a need to regularly generate reports of mailbox audit log data. I’ve written a PowerShell script, Get-MailboxAuditLoggingReport.ps1 to perform this task.

Although mailbox audit log reports can be created in the Exchange Admin Center the interface is not as fast to use as PowerShell, and it can’t be scheduled to run automatically for regular reports like a script can.

This script will generate a report of the mailbox audit log entries for a specified mailbox, for a period of time (the last 24 hours by default), and save the full results to CSV as well as a summary of the data to a HTML file. The script can also be used to send the results via email with the CSV data attached.

mailbox-audit-log-report-example

This script is available on the TechNet Script Gallery and Github. Comments are welcome below. If you find a bug please consider raising it as an issue on Github.

Exchange Server Auditing, Exchange 2010, Exchange 2013, Mailbox Audit Logging, PowerShell, Scripts

Comments

  1. Warren says

    September 26, 2021 at 1:07 pm

    Hello Paul

    Real fan of the site, you are the reason i have improved my mastery of all things server in the last 2 years, keep up the great articles.

    I have a quick Question does this report work of Office365 exchange online or is there perhaps an alternative script you could recommend based on a similar scenario below.

    The scenario is that we have a high priority mailbox with delegates assigned. Mails are sent by these delegates daily and the senior manager wants to keep a closer eye on who is sending these mails. We unfortunately cannot assign mail signatures to these mails due to company branding, internal policy and some concerns from the POPI act that have cropped up from legal. The tracking is critical for KPI’s for the assigned delegates as well as reviewing customer\Vendor interactions with the team.

    So its present a bit of a headache to try and find the right solution as the one method i found doesn’t supply date\time, mail subject and delegate who sent the mail over the last 24 hours. I would like to assist this manager but Ive struggled to setup something around this that will work, let alone autonomously.

    Would appreciate any advise you could offer or perhaps nudge me into the right direction with this as im eager to learn, rather than be spoon fed on issues.

    Reply
  2. SJ says

    September 26, 2019 at 9:50 pm

    Hi Paul,

    I would like to get a report for last two months. Is it possible to change the hours mentioned in the script. I did try to change the hours to 2000. It gives no audit logs. Whereas for last 36 hours, it shows the report.

    can you please advise ?

    Reply
  3. Nicolas Carson says

    March 15, 2018 at 1:46 am

    Do you have a modified version of this script that would work with exchange 2016 with the New-MailboxauditLogSearch command? I am trying to update this script now to the new command myself but if there is a new version already I would appreciate the help.

    Reply
    • Paul Cunningham says

      March 15, 2018 at 5:27 am

      I don’t, sorry.

      Reply
  4. barth says

    October 21, 2017 at 12:44 am

    Big thanks Paul.
    Yes, I’m using your script.
    I have been able to filter out what I need by piping your script to:
    “Where-Object {$_.FolderPathName -notlike “*\Drafts*” -and $_.operation -ne “SendAs” -and $_.operation -ne “Update” -and $_.Operation -ne “Create”}”

    Thanks once again and have a great weekend 😉

    Reply
  5. Gary Jackson says

    August 23, 2017 at 12:14 am

    I love this! How would we modify it so it could run against multiple mailboxes and and provide that in the report rather than having to run it many times with different users?

    Thanks again,
    Gary

    Reply
    • Paul Cunningham says

      August 23, 2017 at 9:47 am

      Yes. If you look into how to make the -Mailbox parameter take pipeline input, and using begin/process/end, you could process multiple mailboxes at once. Whether you output all that to a single report file or one file per mailbox I’ll leave up to you, as I’m not sure which would be best.

      Reply
      • Gary says

        August 24, 2017 at 1:13 am

        Could we do this against a group possibly this way as well?

        Reply
        • Paul Cunningham says

          August 24, 2017 at 7:43 am

          Almost anything is possible. Write some logic that expands the group membership into a list of mailboxes, then loops through the list to retrieve each mailbox’s audit log entries.

          Reply
          • barth says

            October 20, 2017 at 9:11 pm

            Thanks so much for the wonderful job. I’m trying to find a means to exclude the “\Drafts” folder in the log.
            This is because messages previously saved in the Draft folder and sent afterwards are considered as Delete operation

          • Paul Cunningham says

            October 20, 2017 at 9:48 pm

            The audit settings are mailbox-wide, so you can’t exclude a folder from audit logging. But in your reporting, whether you’re using my script or something else, you could just add some logic to exclude entries matching that folder.

  6. Yuksel BASTAN says

    May 3, 2017 at 7:58 pm

    hi @ all,
    theer is great work from Paul in this link :
    https://github.com/cunninghamp/Get-MailboxAuditLoggingReport.ps1

    but i have a question for this script. Is it possible to add a funtion that shows me the mail adres to whom our personal send the mail? i mean i want to add a line too for MailTo . I tryed ” $reportObj | Add-Member NoteProperty -Name “Mail To” -Value $entry.MailTo ” but didnt worked.

    foreach ($entry in $auditlogentries)
    {
    $reportObj = New-Object PSObject
    $reportObj | Add-Member NoteProperty -Name “Mailbox” -Value $entry.MailboxResolvedOwnerName
    $reportObj | Add-Member NoteProperty -Name “Mailbox UPN” -Value $entry.MailboxOwnerUPN
    $reportObj | Add-Member NoteProperty -Name “Timestamp” -Value $entry.LastAccessed
    $reportObj | Add-Member NoteProperty -Name “Accessed By” -Value $entry.LogonUserDisplayName
    $reportObj | Add-Member NoteProperty -Name “Operation” -Value $entry.Operation
    $reportObj | Add-Member NoteProperty -Name “Result” -Value $entry.OperationResult
    $reportObj | Add-Member NoteProperty -Name “Folder” -Value $entry.FolderPathName
    if ($entry.ItemSubject)
    {
    $reportObj | Add-Member NoteProperty -Name “Subject Lines” -Value $entry.ItemSubject
    }
    else
    {
    $reportObj | Add-Member NoteProperty -Name “Subject Lines” -Value $entry.SourceItemSubjectsList
    }

    $report += $reportObj
    }

    thank you very much.

    Reply
  7. Tariq says

    October 25, 2016 at 6:28 pm

    Hi

    can you plz verify the smtp setting, its with $ or without $ coz with dollor its giving errors.

    $smtpsettings = @{
    To = $MailTo
    From = $MailFrom
    Subject = $reportemailsubject
    SmtpServer = $MailServer
    }

    Reply
  8. Richard says

    September 5, 2016 at 9:24 pm

    Hi l have ran this before with no issues but now l receive the error below. I do not think i have ran this since updating to CU12. Anyone else come across this?

    Search-MailboxAuditLog : The Exchange Web Service endpoint for LegacyDn: /o=******** Exchange Organization/ou=Exchange
    Administrative Group (*************)/cn=Recipients/cn=4b622569157f4dac90322e6a92e, RecipientType: UserMailbox,
    RecipientTypeDetails: RoomMailbox, Selected Mailbox: Display Name: ******************, Mailbox Guid:
    7d1ebae6-35c7-4450-a5d3-916120726501, Database: 18b0b34b-70e0-4b11-907f-5436aaf41fa3, Location: ServerFqdn:
    ********.*********.***, ServerVersion: 1941996698, DatabaseName: ****************,
    HomePublicFolderDatabaseGuid: 00000000-0000-0000-0000-000000000000 could not be found.
    At C:Program FilesMicrosoftExchange ServerV15scriptsGet-MailboxAuditLoggingReport.ps1:139 char:20
    + $auditlogentries = Search-MailboxAuditLog -Identity $identity -LogonTypes Delega …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Search-MailboxAuditLog], FailedToFindEwsEndpointException
    + FullyQualifiedErrorId : [Server=************,RequestId=adde4884-a7e6-4561-ad6f-d22502055aea,TimeStamp=05/09/20
    16 10:51:50] [FailureCategory=Cmdlet-FailedToFindEwsEndpointException] 56002926,Microsoft.Exchange.Management.Syst
    emConfigurationTasks.SearchMailboxAuditLog

    Reply
  9. Rob says

    August 10, 2016 at 2:02 am

    Hi Paul, any chance you have the same for Admin Audit logs?
    Would be very handy to schedule both of these weeklymonthly.
    Thanks

    Reply
  10. Simon says

    June 16, 2016 at 2:53 am

    Hello, i use your script to check the access to a mailbox from a “delegate”
    First i use this command:
    Set-Mailbox -Identity “HD Settimo” -AuditDelegate Folderbind -AuditEnabled $true
    Then i run your script
    D:scriptGet-MailboxAuditLoggingReport.ps1 -mailbox “HD Settimo”
    The script run Well , but the result is not corret
    For example, i access with my user to a “help desk mailbox” (i have full access), but the result in AuditLogEntries.html is not correct

    I access at 18:34 but in the file the time recorded is 18:12.
    If i access again, and re.run the script the time remain 18:12

    Thanx for your help, best regards

    Simone

    Reply
  11. Wilbert says

    May 31, 2016 at 5:04 pm

    Is it possible to add the date of affected appointment?
    We have a lot of appointments with the same subject. Therefore it would be nice to know the date (and if possible start time) of the appointment that is changed.

    Reply
  12. Robert says

    April 23, 2016 at 3:10 am

    Do you have a version of this for Exchange Online?

    Reply
  13. Suzanne Bejsovec says

    April 16, 2016 at 2:11 am

    We enabled Owner audit for all actions. To get that to show in the reports I had to remove the ‘-LogonTypes Delegate’ from this line in your script:

    $auditlogentries = Search-MailboxAuditLog -Identity $identity -LogonTypes Delegate -StartDate (Get-Date).AddHours(-$hours) -ShowDetails

    Reply
  14. AMGHAR says

    March 15, 2016 at 12:37 am

    Hello,

    Can we generte an xml report?? thanks in advance

    Reply
  15. Ahmad says

    March 2, 2016 at 3:30 pm

    I’m gettting results, but the subject is not showing.
    how can i get the subject of the email in the log?

    Reply
    • Paul Cunningham says

      March 2, 2016 at 4:07 pm

      It works fine in my environments, so I’m not sure why it isn’t for you.

      What are the operations that aren’t showing subject lines?

      Reply
  16. kjstech says

    February 26, 2016 at 6:23 am

    Hmm, well if I specify the email server’s IP address it works. Problem solved. I was specifying the FQDN and when that didn’t work, just the server’s name.

    Now, can we make a simular powershell command that will output administrative auditing to an html / csv, that could be emailed? The users thing is great, but we don’t want to have to click compliance management > auditing > run the admin audit log report… every day.

    Thanks!

    Reply
  17. kjstech says

    February 26, 2016 at 6:10 am

    I’d like to put this in task scheduler to email a daily report to key IT and CIO users for auditing purposes. However I cannot get the email function to work. I can get it to generate the html and csv file on the C: drive of the Exchange server, but when I specify -SendEmail, -MailFrom, -MailTo and -MailServer switches, I get this error.

    Send-MailMessage : Service not available, closing transmission channel. The server response was: 4.3.2 Service not
    available
    At C:scriptsGet-MailboxAuditLoggingReport.ps1:199 char:6
    + Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([Sy …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpExcept
    ion
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

    Reply
  18. Paul says

    February 26, 2016 at 5:33 am

    Hi Paul,

    Great work, love the site it is massively useful. Can I run the audit script across all mailboxes or do you have specify a mailbox?

    Thanks,
    Paul.

    Reply
  19. Eissa says

    January 3, 2016 at 7:17 pm

    Hi Paul,

    Is there a way to exclude some logs,
    For example, if the mailbox accessed by specific user do not include it in the report.
    Am asking for that because we have a specific account which use for mailboxes archiving and in need to exclude this account form appearing in the logs.

    Reply
    • Paul Cunningham says

      January 4, 2016 at 12:32 pm

      If you’ve got service accounts that are frequently hitting mailboxes you can exclude those from mailbox audit logging.

      https://technet.microsoft.com/en-us/library/ff461934(v=exchg.150).aspx

      Otherwise you could modify the script with some logic to skip specific accounts to customize it for your specific needs.

      Reply
  20. Hisham Mezher says

    December 3, 2015 at 8:26 pm

    Good Day Paul,

    I first want to thank you for all the information and scripts you provide, love your work.

    regarding the Get-MailboxAuditLoggingReport.ps1 i want to know how can I schedule this to run for like 20 shared mailboxes each to be sent to the mailbox owner.

    Let us know please,

    Thanks a lot for your feedback.

    Regards;
    Hisham

    Reply
  21. Mario says

    October 15, 2015 at 9:39 pm

    Hello Paul,
    I want to run this Script on Exchange 2010.

    Is this Script only for Exchange 2013.

    The erreo Message is:
    Der Operator “<" will be not yet supported

    Thanks for help.

    Reply
    • Paul Cunningham says

      October 16, 2015 at 5:31 am

      It should work. If you tried to download the script from Github I’d say you accidentally got a bunch of HTML code from the Github website mixed in there.

      Reply
  22. Akshay says

    August 15, 2015 at 5:52 am

    HELLLLLLLLLLO PAUL

    FIRTS OF ALLL YOUR BLOGS ARE SAVIORS MANY TIMES WHEN M CLUE LESS; THANK YOU VERY MUCH FOR ALL YOUR WORK THAT YOU SHARE WITH US

    QUESTION:-
    i am trying to list all mailboxes which are on exchange 2013 i have a mix environment with 2007 … m sorry if m asking something very basic but m not able to figure out since i only know that they will have a different admin display version

    Reply
    • Paul Cunningham says

      August 15, 2015 at 2:09 pm

      On the 2013 server if you run Get-MailboxDatabase it should only return Exchange 2013 databases, So you can pipe that into Get-Mailbox to see just the Exchange 2013 mailboxes.

      Eg, Get-MailboxDatabase | Get-Mailbox

      Reply
  23. Lubos says

    July 2, 2015 at 6:50 pm

    Hello,

    Can you help me. I need to find out who created the mailbox on Exchange Server 2010. What is the appropriate command shell in power. Thanks for the help.

    Reply
    • Paul Cunningham says

      July 3, 2015 at 10:02 pm

      You’ll need to look at searching the Admin Audit Log, which is different to the Mailbox Audit Log, but easy to find information about.

      Reply
  24. Nino Iaccarino says

    May 12, 2015 at 8:04 am

    Hi, sorry about that.

    Basically, if I run the command and specify a user I know definitely has audit entries, no results are returned.

    When I ran it without specifying a user, I could see in the exported csv the same user but with the entries I was expecting.

    It seems when I specify a user in the command, it returns 0 results even if there are results.

    Reply
    • Paul Cunningham says

      May 12, 2015 at 9:52 am

      How do you know they definitely have audit entries? What are you basing that on? Manual searches? Folder statistics?

      Reply
  25. Nino Iaccarino says

    May 11, 2015 at 4:13 pm

    I am also not having much luck and I’m not sure what I am doing wrong ? I have enabled auditing on my account just to see some results, but I don’t get any. I should have at least something logged ? This is what my account looks like.

    AuditEnabled : True
    AuditLogAgeLimit : 90.00:00:00
    AuditAdmin : {Update, Move, MoveToDeletedItems, SoftDelete, HardDelete, FolderBind, SendAs, SendOnBehalf, Create}
    AuditDelegate : {Update, SoftDelete, HardDelete, SendAs, Create}
    AuditOwner : {Update, Move, MoveToDeletedItems, SoftDelete, HardDelete, Create}

    I ran the command without specifying a user, and I do get something output to the auditlogentries.html
    and the output does have some details about a particular user.

    Mailbox

    Mailbox UPN

    Timestamp

    Accessed By

    Operation

    Result

    Folder

    Subject Lines

    info ’emailaddress’ 11/05/2015 11:16:02 AM First Name Last Name SoftDelete Succeeded Inbox

    I then run the command against her, and then I get:

    [PS] C:scripts>.Get-MailboxAuditLoggingReport.ps1 -Mailbox ‘username’ -Hours 200
    Searching ‘username’ for last 200 hours.
    No audit log entries found.
    Finished.

    So, it looks as though Exchange is logging correctly (as auditing is enabled) but the command isn’t outputting the info :/

    Help !!

    Reply
    • Paul Cunningham says

      May 11, 2015 at 8:56 pm

      Specifying a mailbox is required, that switch should be mandatory. I’ll fix that in the script.

      Other than that, you’ve obfuscated too much for me to even begin to grasp what you’re seeing. The script only does the hard work of a normal audit log search, so you should go do some manual searches via PowerShell or the Exchange Admin Center to compare results.

      Reply
  26. Buch says

    March 15, 2015 at 8:17 pm

    Could you please add to script possibility to find audit log information for list of mailboxes and for all mailboxes, that have audit enabled, for example like that:
    Get-Mailbox -ResultSize unlimited | where {($_.AuditEnabled -eq $true)}

    Reply
  27. MS says

    February 27, 2015 at 9:25 pm

    Is there any specific reason why we are loading Microsoft.Exchange.Management.PowerShell.E2010 PSSnapin in Exchange 2010 environment? I remember reading article on blogs.technet.com about that not being needed.

    Thanks.

    Reply
    • Paul Cunningham says

      February 27, 2015 at 10:16 pm

      Not sure what you mean… the script relies on Exchange cmdlets so it won’t work if the cmdlets aren’t available.

      Reply
      • MS says

        February 27, 2015 at 11:10 pm

        You are first loading PSSnapin, and then dot sourcing RemoteExchange.ps1 … shouldn’t second action be enough to get all cmdlets for the script? I might not be too clear, but here is an article from blogs.technet.com that I mentioned. Link: http://blogs.technet.com/b/rmilne/archive/2015/01/28/directly-loading-exchange-2010-or-2013-snapin-is-not-supported.aspx

        Thanks.

        Reply
  28. Rocky says

    February 13, 2015 at 3:34 am

    I confirmed “AuditEnabled” is set to “True” on all my mailboxes in my Exchange 2013 Organization but when I run the script, it states that there is “No audit log entries found”.

    .Get-MailboxAuditLoggingReport.ps1 -Mailbox testuser -Hours 48 -SendEmail -MailFrom ExchangeAuditReport@crabel.com -MailTo testuser@crabel.com -MailServer mail

    I ran this on my Win8.1 box that has the Exchange 2013 management tools. I then tried to run the script on a CAS box and same result:

    Searching testuser for last 48 hours.
    No audit log entries found.
    Finished.

    Why wouldn’t there be any log entries found????

    Reply
    • Paul Cunningham says

      February 13, 2015 at 7:35 am

      Enabling audit logging is one step. But until a delegate has performed an operation that will generate some log data there’ll be nothing to find.

      You can read more about mailbox audit logging here:
      https://www.practical365.com/using-exchange-server-2013-mailbox-audit-logging/

      Reply
    • Markus says

      March 3, 2015 at 5:39 am

      Paul – I’m seeing the same results (no audit log entries found). We have the settings in place for Admin, Delegate, and Owner auditing.

      Reply
      • pradeep sharma says

        February 11, 2016 at 1:41 pm

        Markus i am also facing same issue. what you have done to fix this issue ? while running this PS file i am getting error message “File skipped because it was already present from “Microsoft.PowerShell”.” and then after command is getting finished with result “No audit log entries found.
        Finished.”

        Reply
        • Sid says

          April 28, 2016 at 12:32 am

          To all that keep seeing “No audit log entries found”:

          I too had the same issue. The script by default only checks for the LogonTypes of “Delegate”. In my case there was no activity done by a delegate and that’s why it kept showing up with “No audit log entries found”.

          So all you need to do is change the -LogonTypes parameter to “Owner” or “Admin”, whoever you are trying to audit. In my case it was Owner. This should be done in line 139 of the script:

          $auditlogentries = Search-MailboxAuditLog -Identity $identity -LogonTypes Owner -StartDate (Get-Date) .AddHours (-$hours) -ShowDetails

          Reply

Leave a Reply Cancel reply

You have to agree to the comment policy.

Recent Articles

  • Turn On MFA: Real-World Example of Fraud, Domain Stealing, and the Nearly Lost House Deposit
  • Changes in Microsoft 365 Apps Channels and Why You Should Care
  • A New Tool to Manage Exchange-related Attributes Without Exchange Server
  • Microsoft Launches Group Ownership Governance Policy
  • Making the Case for Identity Governance in Azure Active Directory

Copyright © 2022 Quadrotech Solutions AG · Disclosure · Privacy Policy
Alpenstrasse 15, 6304 Zug, Switzerland