Criteria
- All Critical events
- All Error events
- All Warning events
- Major logs – Application, System, Security
- Create a report with all results
- Events reported – count of how many times event occurred
- Most recent occurrence of the event logged
Script
The script starts off by asking a few questions, it then queries the computers you’ve told it to look at and finally generate one report per server. The script as written will look at the Application, Security, System, Directory Service, Fire Replication Service and DNS logs. If the log does not exist, the script will skip that log.
<# .SYNOPSIS Analyzes server event logs for Error, Warning and Critical events. .DESCRIPTION Analyzes server event logs for Error, Warning and Critical events for mulptile servers and skps unneded log file types. .NOTES Version : 1.4 Change Log: : 1.4 - added log check, if log name is valid, proceed, otherwise ignore : 1.3 - added warning and critical events to the get-eventlog commands : 1.2 - Added support for multiple event logs other than thre standard 3 : 1.1 - Added support for couting events and last occured : 1.0 - Created script for with basic event log screening Wish list : Rights Required : Local admin on server Sched Task Req'd : No Exchange Version : 2013 Author : Damian Scoles Email/Blog/Twitter : Dedicated Blog : Disclaimer : You are on your own. This was not written by, support by, or endorsed by Microsoft. .LINK [TBD] .EXAMPLE .\EventLogs.ps1 .INPUTS None. You cannot pipe objects to this script. #> $servers = @() $allinfo = @() cls write-host "Where do you want to store the generated Event Log Reports? [c:\temp\] " -foregroundcolor cyan -nonewline $path = read-host write-host " " write-host "How many servers will need to have their Event Logs examined? " -foregroundcolor green -nonewline $num = read-host write-host " " $counter = 0 do { $SNo = $counter+1 $server = read-host "What is the name of server $SNo" $servers += ,@($server) $counter++ } while ($counter -ne $num) foreach ($line in $servers) { $server = [string]$line write-host " " write-host "Analyzing event logs for server $line" -ForegroundColor white write-host " " write-host "PROCESSING" -foregroundcolor yellow write-host " " # Get a list of Critical Events # Application Log $info = $null # Application Log $log = "application" $logcheck = get-winevent -ListLog $log -ComputerName $server -erroraction SilentlyContinue if ($logcheck -ne $null) { write-host "Application Log Analysis" -foregroundcolor cyan $events = get-eventlog -computername $line -logname $log | where {($_.entrytype -eq "error") -or ($_.entrytype -eq "warning") -or ($_.entrytype -eq "critical")} | sort-object eventid | group-object eventid $app = foreach ($line2 in $events) { $evt = $line2.name $Info2 = get-winevent -computername $server -FilterHashtable @{Logname=$log;ID=$evt} -MaxEvents 1 -erroraction silentlycontinue New-Object PSObject -Property @{ LastOccured = ($info2.timecreated).datetime Count = $line2.count Name = $info2.providername Event = $evt # message = $info.message } } if ($app -eq $null) { $Application = $app | ConvertTo-Html -Fragment -PreContent '<h2>Security Log</h2><BR>No critical events were found in the Application Log' } else { $Application = $app | ConvertTo-Html -Fragment -PreContent '<h2>Application Log</h2>' } } else { $Application = $null } # System Log $log = "system" $logcheck = get-winevent -ListLog $log -ComputerName $server -erroraction SilentlyContinue if ($logcheck -ne $null) { write-host "System Log Analysis" -foregroundcolor cyan $events = get-eventlog -computername $line -logname $log | where {($_.entrytype -eq "error") -or ($_.entrytype -eq "warning") -or ($_.entrytype -eq "critical")} | sort-object eventid | group-object eventid $sys = foreach ($line2 in $events) { $evt = $line2.name $Info2 = get-winevent -computername $server -FilterHashtable @{Logname=$log;ID=$evt} -MaxEvents 1 -erroraction silentlycontinue New-Object PSObject -Property @{ LastOccured = ($info2.timecreated).datetime Count = $line2.count Name = $info2.providername Event = $evt # message = $info.message } } if ($sys -eq $null) { $System = $sys | ConvertTo-Html -Fragment -PreContent '<h2>System Log</h2><BR>No critical events were found in the Systemn Log' } else { $System = $sys | ConvertTo-Html -Fragment -PreContent '<h2>System Log</h2>' } } else { $System = $null } # DNS Server $log = "DNS Server" $logcheck = get-winevent -ListLog $log -ComputerName $server -erroraction SilentlyContinue if ($logcheck -ne $null) { write-host "DNS Server Log Analysis" -foregroundcolor cyan $events = get-eventlog -computername $line -logname $log | where {($_.entrytype -eq "error") -or ($_.entrytype -eq "warning") -or ($_.entrytype -eq "critical")} | sort-object eventid | group-object eventid $dns = foreach ($line2 in $events) { $evt = $line2.name $Info2 = get-winevent -computername $server -FilterHashtable @{Logname=$log;ID=$evt} -MaxEvents 1 -erroraction silentlycontinue New-Object PSObject -Property @{ LastOccured = ($info2.timecreated).datetime Count = $line2.count Name = $info2.providername Event = $evt # message = $info.message } } if ($dns -eq $null) { $DNSlog = $dns | ConvertTo-Html -Fragment -PreContent '<h2>DNS Server Log</h2><BR>No critical events were found in the DNS Server Log' } else { $DNSlog = $dns | ConvertTo-Html -Fragment -PreContent '<h2>DNS Server Log</h2>' } } else { $DNSlog = $null } # File Replication Service $log = "File Replication Service" $logcheck = get-winevent -ListLog $log -ComputerName $server -erroraction SilentlyContinue if ($logcheck -ne $null) { write-host "FRS Log Analysis" -foregroundcolor cyan $events = get-eventlog -computername $line -logname $log | where {($_.entrytype -eq "error") -or ($_.entrytype -eq "warning") -or ($_.entrytype -eq "critical")} | sort-object eventid | group-object eventid $frs = foreach ($line2 in $events) { $evt = $line2.name $Info2 = get-winevent -computername $server -FilterHashtable @{Logname=$log;ID=$evt} -MaxEvents 1 -erroraction silentlycontinue New-Object PSObject -Property @{ LastOccured = ($info2.timecreated).datetime Count = $line2.count Name = $info2.providername Event = $evt # message = $info.message } } if ($frs -eq $null) { $FRSLog = $frs | ConvertTo-Html -Fragment -PreContent '<h2>File Replication Service Log</h2><BR>No critical events were found in the FRS Log' } else { $FRSLog = $frs | ConvertTo-Html -Fragment -PreContent '<h2>File Replication Service Log</h2>' } } else { $FRSlog = $null } # Security $log = "Security" $logcheck = get-winevent -ListLog $log -ComputerName $server -erroraction SilentlyContinue if ($logcheck -ne $null) { write-host "Security Log Analysis" -foregroundcolor cyan $events = get-eventlog -computername $line -logname $log | where {($_.entrytype -eq "error") -or ($_.entrytype -eq "warning") -or ($_.entrytype -eq "critical")} | sort-object eventid | group-object eventid $sec = foreach ($line2 in $events) { $evt = $line2.name $Info2 = get-winevent -computername $server -FilterHashtable @{Logname=$log;ID=$evt} -MaxEvents 1 -erroraction silentlycontinue New-Object PSObject -Property @{ LastOccured = ($info2.timecreated).datetime Count = $line2.count Name = $info2.providername Event = $evt # message = $info.message } } if ($sec -eq $null) { $Security = $sec | ConvertTo-Html -Fragment -PreContent '<h2>Security Log</h2><BR>No critical events were found in the Security Log' } else { $Security = $sec | ConvertTo-Html -Fragment -PreContent '<h2>Security Log</h2>' } } else { $Security = $null } # Directory Service $log = "Directory Service" $logcheck = get-winevent -ListLog $log -ComputerName $server -erroraction SilentlyContinue if ($logcheck -ne $null) { write-host "Directory Service Log Analysis" -foregroundcolor cyan $events = get-eventlog -computername $line -logname $log | where {($_.entrytype -eq "error") -or ($_.entrytype -eq "warning") -or ($_.entrytype -eq "critical")} | sort-object eventid | group-object eventid $dir = foreach ($line2 in $events) { $evt = $line2.name $Info2 = get-winevent -computername $server -FilterHashtable @{Logname=$log;ID=$evt} -MaxEvents 1 -erroraction silentlycontinue New-Object PSObject -Property @{ LastOccured = ($info2.timecreated).datetime Count = $line2.count Name = $info2.providername Event = $evt # message = $info.message } } if ($dir -eq $null) { $Directory = $dir | ConvertTo-Html -Fragment -PreContent '<h2>Security Log</h2><BR>No critical events were found in the Directory Service Log' } else { $Directory = $dir | ConvertTo-Html -Fragment -PreContent '<h2>Directory Service Log</h2>' } } else { $Directory = $null } # Format HTML $Header = @" <style> TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;} TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #FF0000;} TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;} .odd { background-color:#ffffff; } .even { background-color:#dddddd; } </style> <title> Critical Events Report for $server </title> "@ $Pre = "Critical Events Report in the Application Log for "+$line $name = $path+"CriticalEvents-"+$line+".html" # $allinfo | ConvertTo-HTML -Head $Header -PreContent $Pre | out-file $name # $info | ConvertTo-HTML -Head $Header -PreContent $Pre | out-file $name ConvertTo-HTML -head $header -Body "$application $system $DNSLog $FRSLog $Security $Directory" -Title "Critical Events in Event Logs Logs" | Out-File $name write-host "Generated an Event log report for " -nonewline write-host $line -foregroundcolor green $info = $null }
In Operation
The script process is relatively simple. Specify where you want to generate log files, how many servers to examine and the names of the servers. In the below example I am examining a lab server for testing purposes. However the script will process as many servers as you specify and generate one HTML results file per server processed.
Results
The results of the file are produced in the form of an HTML file. Notice the separation between Logs as well as a report on the Security log that no issues were found. The example below was from a lab based Exchange Server:
Further Information
With a slight modification, the script could even email this file to IT personnel or a consultant to review and look for problems in the environment.
Get-EventLog
Get-WinEvent