The Search-AdminAuditLog cmdlet is part of the new administrator audit logging functionality in Exchange 2010 SP1. I used it to write a script that sends an HTML report via e-mail based on the changes made within the organization in the last 24 hours. The details of the command used to make each change include the cmdlet name, the parameters and their assigned values, the user who ran it, and the object that was modified. If you want to read up on administrator audit logging, there are some great posts on it here, and over here. I've also blogged about it a couple times, here and here.
Here is a screenshot of how the report looks:
You can create a scheduled task to run once every day and have the report sent as an HTML formatted message to a specified e-mail address. You just need to supply the recipient, sender and smtp server; here is an example running the script manually:
You can customize the script to limit the amount of information included in the report by modifying the parameters used with the Search-AdminAuditLog cmdlet. For example, you can modify the start and end time to use a shorter time window, or you can limit it to only report on certain cmdlets or user ids.
You can download a copy of the script here.






{ 2 trackbacks }
{ 34 comments… read them below or add one }
This is pretty cool.
Thanks man
Nice script. Thanks for making this.
My pleasure, thanks for the comment.
Great Script, would it be possible to create a similar one for mailboxauditLogSearch? The results in .xml file are kind of difficult to read.
Sure, I’ll try to post an example in the next week or two. Thanks for the comment.
Hi Mike, I don’t want to be a pain in the A. but maybe you could give me some instructions or tips how should such a script for mailboxauditLogsearch be composed?
Hey Robert…sorry for the delay. I was planning on doing a blog post on this but got busy and forgot about it. I’ll post an example here later tonight when I get some time.
Here’s a quick snippet that will generate a nice styled HTML report for delete operations in a mailbox. Obviously, this assumes that mailbox audit logging is enabled and configured. This example runs against just one mailbox, but you could modify it as needed:
$css = @" <style type="text/css"> table { border-spacing: 0px; border-collapse: collapse; background: #F9F5D7; border: 2px solid #000000; font-family:arial; } table td { text-align: left; border: 0px; border-bottom: 2px solid #000000; border-left: 2px solid #000000; padding: 0.1em 0.5em; font-family:arial; } table th { text-align: left; font-weight: bold; background-color: #AA0000; padding: 0.1em 0.5em; color: #FFFFFF; border: 2px solid #000000; font-family:arial; } </style> "@ Search-MailboxAuditLog -Identity administrator -ShowDetails | Where-Object {$_.Operation -like '*delete*'} | ForEach-Object { $operation = $_.Operation $mailbox = $_.MailboxResolvedOwnerName $deletedby = $_.LogonUserDisplayName $lastaccessed = $_.LastAccessed $_.SourceItems | ForEach-Object { New-Object PSObject -Property @{ Mailbox = $mailbox Subject = $_.SourceItemSubject.Trim() Folder = $_.SourceItemFolderPathName.Trim() Operation = $operation DeletedBy = $deletedby TimeDeleted = $lastaccessed } } } | ConvertTo-Html -Head $css | Out-File c:\report.htmlHi Mike, will you kindly send me instructions on how to install the Audut Log Report in HTML. I have downloded the script but cannot run it.
I receive the following error when I try and configure Augit Log Report for HTML:
The term ‘Search-AdminAuditLog’ is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\AuditLogReport.ps1:72 char:28
+ -Body (Search-AdminAuditLog <<<< -StartDate ((Get-Date).AddHours(-24)) -EndDate (Get-Date) | New-AuditLogReport) `
+ CategoryInfo : ObjectNotFound: (Search-AdminAuditLog:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Are you running the script from the Exchange Management Shell? Also, it could be permissions. If you are not in the Organization Management role group, you will not get this cmdlet. It can be assigned via the Audit Logs or View-Only Audit Logs roles.
I am running the script using the Exchange Management Shell. I have tried your suggestion and still no luck
Are you running SP1?
Hi Mike,
I would like to run the command in a scheduled task but its not working. It is allways asking me for a sender an acceptor and a smtp server and I have to enter them manually. It would be very kindful of you if you could post or send me an email with the correct command line, which I have to enter, for the scheduled task.
Did you try something like this?
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command “. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; c:\AuditLogReport.ps1 -To admin@adatum.com -From audit@adatum.com -SmtpServer adatum-ex1″
Hi Mike,
Thanks for your advice.
I ve used this command line : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command “. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; c:\scripts\AuditLogReport.ps1 -To administrator@contoso.com -From audit@contoso.com -SmtpServer ex01″
When I execute it in Powershell it is working, but if i copy the line into the sceduled task manager an error occurs (cmd box has red text in it and dissapears fast). The error occurs also, when I try to execute the command line via batch file.
Do you know why and how to fix this error?
Thanks in advance
Best Regards
Kevin
Try adding the -noexit switch with powershell.exe so it doesn’t close and you can see the error:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noexit -command “. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; c:\scripts\AuditLogReport.ps1 -To administrator@contoso.com -From audit@contoso.com -SmtpServer ex01″
Hi Mike,
thanks for the advice once more. I will try this tommorw. But I could you do me another favor please? I forgot to change the email adress and I dont want it to apper in the internet, so could you please delete the last posts in the next time= This would be very kindful of you.
Best Regards
Kevin
Fixed
Nice Script. Can you create one similar for Mailbox Audit Log Search? Not just to capture “delete” operations, but for everything that is being captured. Thanks so much.
Hello, Mike! Thanks for another very useful script.
I have little issue with it. We have some callers (users) names in Russian (Cyrillic) and in report they appears like bunch of question marks — something like that “?????? ???”
I tried to add “$OutputEncoding = [Console]::OutputEncoding” in script, but it doesn’t help. I also tried use function from here http://xaegr.wordpress.com/2007/01/24/decoder/ to decode $sb string, but with no luck (maybe I do it wrong?
Could you help me to modify script for correctly output of users with Russian names? Will be appreciate for any help.
Thank you in any case.
Regards,
Oleg.
Oh, Mike, sorry. It was much easier. I just add “-Encoding ([System.Text.Encoding]::UTF8)” parameter to Send-MailMessage. Thank you!
excellent tool…however I’m having a problem (not with the script itself though). thought I’d take a chance to see if any of the brains on here know why I’d be getting output like this from a search-adminauditlog cmdlet:
RunspaceId : ece86ee3-f54a-45e4-a345-84b38304aebe
ObjectModified :
CmdletName :
CmdletParameters : {}
ModifiedProperties : {}
Caller :
Succeeded :
Error :
RunDate :
OriginatingServer :
Identity : RgAAAAAO1CtMbGfSQoLkeS3KzlagBwA7s4MDL6ChRaDnSXf7iZrRAAAtzqh2AAA7s4MDL6ChRaDnSXf7iZrRAAAtzqh9AAAJ
IsValid : True
I seem to have auditing enabled…
RunspaceId : ece86ee3-f54a-45e4-a345-84b38304aebe
AdminAuditLogEnabled : True
TestCmdletLoggingEnabled : True
AdminAuditLogCmdlets : {*}
AdminAuditLogParameters : {*}
AdminAuditLogExcludedCmdlets : {}
AdminAuditLogAgeLimit : 90.00:00:00
AdminDisplayName :
ExchangeVersion : 0.10 (14.0.100.0)
Name : Admin Audit Log Settings
DistinguishedName : CN=Admin Audit Log Settings,CN=Global Settings,[edited out..]
Identity : Admin Audit Log Settings
Guid : 93b3b148-20bd-47a5-aec2-d0fabf25edf6
ObjectCategory : [edited out..]/Configuration/Schema/ms-Exch-Admin-Audit-Log-Config
ObjectClass : {top, msExchAdminAuditLogConfig}
WhenChanged : 9/12/2011 9:23:10 PM
WhenCreated : 2/17/2010 3:46:29 PM
WhenChangedUTC : 9/13/2011 2:23:10 AM
WhenCreatedUTC : 2/17/2010 9:46:29 PM
OrganizationId :
OriginatingServer : [edited out..]
IsValid : True
The script actually fails at this part:
[void]$sb.AppendLine(“$($AuditLogEntry.Caller.split(“/”)[-1])”)
[void]$sb.AppendLine(“$($AuditLogEntry.RunDate.ToString())”)
[void]$sb.AppendLine(“$($AuditLogEntry.Succeeded)”)
[void]$sb.AppendLine(“$($AuditLogEntry.cmdletname)”)
$cmdletparameters += $AuditLogEntry.cmdletparameters | %{
“$($_.name) : $($_.value)”
}
[void]$sb.AppendLine(“$cmdletparameters”)
[void]$sb.AppendLine(“$($AuditLogEntry.ObjectModified)”)
because all those values are “null” for me…not sure what I’m missing in my configuration.
Can you create one similar for Mailbox Audit Log Search? Not just to capture “delete” operations, but for everything that is being captured. Thanks so much.
This is a Great tool and very helpful. I’m trying to adapt the script to run on a Office 365 instance, unfortunately it is errorsing out with [Microsoft.Exchange.Management.SystemConfigurationTasks.AdminAuditLogEvent]. Would you know of a work around or another way to get access to the information?
Thank you in Advance
D
param(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
[Microsoft.Exchange.Management.SystemConfigurationTasks.AdminAuditLogEvent]
$AuditLogEntry
)
Hi Mike, great tool/script. i ran of couple of times very usefull in my enviroment, but currently i can not start it. i get following error message:
Suggestion [3,General]: The command AuditLogReport.ps1 was not found, but does exist in the current location. Windows Po
werShell doesn’t load commands from the current location by default. If you trust this command, instead type “.\AuditLog
Report.ps1″. See “get-help about_Command_Precedence” for more details.
but if i try to start only the AuditLogReport.ps1, then i can put in my details like from, to and smtp server:
PS D:\Scripts> .\AuditLogReport.ps1
cmdlet AuditLogReport.ps1 at command pipeline position 1
Supply values for the following parameters:
To: user@domain.com
From: user@domain.com
SmtpServer: mailserver.domain.com
any idea???
Try running it like this:
.\AuditLogReport.ps1 -To user@domain.com -From user@domain.com -SmtpServer mailserver.domain.com
Mike,
The script works great manually, but I i input the following into the schedule task and run it. Nothing happens. No email is being sent.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command “. ‘C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1′; Connect-ExchangeServer -auto; c:\AuditLogReport.ps1 -To me@server -From audit@server.com -SmtpServer smtp.server.com″
I did not change the email portion of the script so the email portion looks like this below. Am I suppose to be edditing it.
Send-MailMessage -To $To `
-From $From `
-Subject “Exchange Audit Log Report for $((get-date).ToShortDateString())” `
-Body (Search-AdminAuditLog -StartDate ((Get-Date).AddHours(-24)) -EndDate (Get-Date) | New-AuditLogReport) `
-SmtpServer $SmtpServer `
-BodyAsHtml
No need to edit the script, just use the parameters as you already have. Did you try the following?
“If you have User Account Control (UAC) enabled, you may need to enable the option to Run with highest privileges in the properties of the scheduled task. Also, you will probably want to enable the option to Run whether user is logged on or not in the properties of the scheduled task.”
Greeting All,
Please suggest, Is there any script to get the user’s mailbox audit instead of accessing the ECP.
I found that article, but little confused.
http://www.msexchange.org/articles_tutorials/exchange-server-2010/management-administration/using-powershell-simplify-mailbox-auditing-part1.html
your report does what i want but I need to load it into a SQL table. I know how to do the sql load, I just can’t figure out how to pull this data especially the cmdletparameter array.
Well, you’ll want to ditch most of the code then because the majority of it is for generating the html. If you want to post the code you have so far (or email it to me) I’ll help you work it out.
here is the code I am using
cd h:\powershell
. ./out-datatable.ps1
. ./write-datatable.ps1
. ./invoke-sqlcmd2.ps1
invoke-sqlcmd2 -serverinstance fwcdba01vd -InputFile “h:\powershell\Archive_ExchAdminAudit.sql”
$startdate = (Get-Date).AddDays(-1).ToString(‘MM-dd-yyyy’) +” 00:00:00.000″
$enddate = (Get-Date).AddDays(-1).ToString(‘MM-dd-yyyy’) +” 11:59:00.000″
$dt =Search-AdminAuditLog -StartDate $startdate -EndDate $enddate -ResultSize 250000 |Select-Object objectmodified,rundate,@{Name=”RunDateCNT”;Expression={ ($_.rundate).addhours(6)}}, cmdletname,cmdletparameters,modifiedproperties,caller,succeeded,error,originatingserver,identiyid,isvalid |out-datatable
write-datatable -serverinstance “fwcdba01vd” -database “Server_Security” -Tablename “ExchAdminAudit” -data $dt
the problem I am having is the cmdletparameters. the way I have it coded it comes back empty. I like the way yours works but can’t figure how to unload the array the way you did.