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.
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.
thanks a lot Paul, this is a very helpfull script
Hi Paul,
Seems i cant get the email to send, running in 365, it mentions the Send-MailMessage cmdlet is obsolete can we get around this?
Thanks
Mark
To use Send-MailMessage with Exchange Online, your account needs to be enabled for SMTP AUTH. But you should move away from Send-MailMessage anyway… https://practical365.com/upgrade-powershell-scripts-sendmailmessage/
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.
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 ?
Pingback: download
Pingback: Cloud Computing
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.
The Real Person!
The Real Person!
I don’t, sorry.
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 😉
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
The Real Person!
The Real Person!
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.
Could we do this against a group possibly this way as well?
The Real Person!
The Real Person!
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.
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
The Real Person!
The Real Person!
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.
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.
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
}
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
Hi Paul, any chance you have the same for Admin Audit logs?
Would be very handy to schedule both of these weeklymonthly.
Thanks
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
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.
Do you have a version of this for Exchange Online?
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
Hello,
Can we generte an xml report?? thanks in advance
I’m gettting results, but the subject is not showing.
how can i get the subject of the email in the log?
The Real Person!
The Real Person!
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?
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!
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
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.
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.
The Real Person!
The Real Person!
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.
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
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.
The Real Person!
The Real Person!
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.
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
The Real Person!
The Real Person!
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
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.
The Real Person!
The Real Person!
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.
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.
The Real Person!
The Real Person!
How do you know they definitely have audit entries? What are you basing that on? Manual searches? Folder statistics?
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 !!
The Real Person!
The Real Person!
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.
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)}
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.
The Real Person!
The Real Person!
Not sure what you mean… the script relies on Exchange cmdlets so it won’t work if the cmdlets aren’t available.
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.
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????
The Real Person!
The Real Person!
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/
Paul – I’m seeing the same results (no audit log entries found). We have the settings in place for Admin, Delegate, and Owner auditing.
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.”
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