Administrator Audit Log Reports in HTML Format – Exchange 2010 SP1

by Mike Pfeiffer on August 19, 2010

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:

[PS] C:\>.\AuditLogReport.ps1 -To admin@adatum.com -From audit@adatum.com -SmtpServer adatum-ex1

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.

Related Posts

{ 2 trackbacks }

Tweets that mention Administrator Audit Log Reports in HTML Format – Exchange 2010 SP1 -- Topsy.com
August 19, 2010 at 7:34 am
Audit log within Exchange 2010 « Doug G
May 26, 2011 at 4:04 pm

{ 34 comments… read them below or add one }

Chris September 27, 2010 at 8:33 am

This is pretty cool.

Reply

Mike Pfeiffer September 27, 2010 at 8:38 am

Thanks man :)

Reply

kunalee November 1, 2010 at 8:43 am

Nice script. Thanks for making this.

Reply

Mike Pfeiffer November 1, 2010 at 8:55 am

My pleasure, thanks for the comment.

Reply

Robert March 9, 2011 at 5:41 am

Great Script, would it be possible to create a similar one for mailboxauditLogSearch? The results in .xml file are kind of difficult to read.

Reply

Mike Pfeiffer March 9, 2011 at 7:36 am

Sure, I’ll try to post an example in the next week or two. Thanks for the comment.

Reply

Robert June 20, 2011 at 4:25 am

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?

Reply

Mike Pfeiffer June 22, 2011 at 7:34 am

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.

Reply

Mike Pfeiffer June 29, 2011 at 5:18 am

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.html

Hofney June 4, 2011 at 3:09 pm

Hi 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.

Reply

Hofney June 4, 2011 at 3:22 pm

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

Reply

Mike Pfeiffer June 7, 2011 at 9:49 am

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.

Reply

Hofney June 11, 2011 at 4:33 pm

I am running the script using the Exchange Management Shell. I have tried your suggestion and still no luck

Reply

Mike Pfeiffer June 22, 2011 at 7:41 am

Are you running SP1?

Reply

kev123 June 22, 2011 at 7:17 am

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.

Reply

Mike Pfeiffer June 22, 2011 at 7:37 am

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″

Reply

kev123 June 29, 2011 at 3:25 am

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

Reply

Mike Pfeiffer June 29, 2011 at 5:12 am

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″

Reply

kev123 June 29, 2011 at 12:21 pm

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

Reply

Mike Pfeiffer June 29, 2011 at 5:30 pm

Fixed :)

Reply

Khing July 15, 2011 at 11:56 am

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.

Reply

Oleg August 17, 2011 at 2:15 am

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.

Reply

Oleg August 17, 2011 at 2:26 am

Oh, Mike, sorry. It was much easier. I just add “-Encoding ([System.Text.Encoding]::UTF8)” parameter to Send-MailMessage. Thank you!

Reply

Joseph September 12, 2011 at 8:30 pm

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.

Reply

Calvin September 16, 2011 at 2:00 pm

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.

Reply

drewster November 10, 2011 at 8:15 am

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
)

Reply

jens November 28, 2011 at 5:37 am

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???

Reply

Mike Pfeiffer November 28, 2011 at 9:15 am

Try running it like this:

.\AuditLogReport.ps1 -To user@domain.com -From user@domain.com -SmtpServer mailserver.domain.com

Reply

Emile Harding November 30, 2011 at 2:24 pm

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

Reply

Mike Pfeiffer December 2, 2011 at 6:23 pm

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.”

Reply

Mano December 18, 2011 at 5:40 am

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

Reply

Russell Young January 11, 2012 at 9:51 am

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.

Reply

Mike Pfeiffer January 11, 2012 at 7:27 pm

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.

Reply

Russell Young January 12, 2012 at 3:08 pm

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.

Reply

Leave a Comment

Previous post:

Next post: