PowerShell: Event viewer statistics
Introduction
The Powerscript below is a modular script that offers following functions:
- display the event log properties
- analyse number of events per category
- analyse number of events per severity
- overview of error events with source, severity and sample message
- detailed list of last event per eventID
You can configure the script:
- choice of event logs
- history length (period of events to report on)
- enable/disable logging
- enable/disable result export to file
Gallery
You can download the script at: https://gallery.technet.microsoft.com/Powershell-Event-log-ab0ded45
Code
cls
#Do you want to enable transcript for logging all output to file? $enableLogging = $TRUE $ExportEnabled = $FALSE
# logging # if you need detailed logging for troubleshooting this script, you can enable the transcript # get the script location path and use it as default location for storing logs and results $log = $MyInvocation.MyCommand.Definition -replace 'ps1','log' $resultPath = $PSScriptRoot + '\' Push-Location $resultPath
if ($enableLogging) { Start-Transcript -Path $log -ErrorAction SilentlyContinue Write-Host "Logging enabled..." Write-Host
Write-Host "Powershell version" $PSVersionTable.PSVersion $Host.Version (Get-Host).Version Write-host }
# Initialisation # Source: http://www.computerperformance.co.uk/powershell/powershell_get_winevent.htm # As of 2104, there is a PowerShell bug in cultures such as "en-GB" or "en-DE", # which prevents the display of the properties: 'LevelDisplayName' and 'Message'; here is a work-around $currentCulture = [System.Threading.Thread]::CurrentThread.CurrentCulture
# Configuration # selected Event log sources # limit the feedback only to the following logs $EventLogList = 'System','Application','Setup','Forefront Identity Manager','Forefront Identity Manager Management Agent'
#for FIM Health Check the Security log has less signification value and is skipped #add it to the eventlog list when you need it #,'Security'
# if the event logs are containing too much data, # powershell might not be able to load all due to memory limits
# return X week to collect logs ## startdate = ((Get-Date).AddDays(-7)) ## $startdate = ((Get-Date).AddDays(-14))
#collect x month of logs ## $startdate = ((Get-Date).AddMonths(-1))
#collect x years of logs $startdate = ((Get-Date).AddYears(-1))
## Background info # We only need the non-informational event # Verbose 5 # Warning 3 # Error 2 # Critical 1
# Informational and LogAlways is discarded
#Informational 4 #LogAlways 0
Write-host "Event logs list" Write-host "---------------" $Eventloglist
#Displaying the log settings for the selected Event log list
Write-Host Write-Host "Event Log Properties" Write-Host "--------------------"
$Count = 0 $Activity = "Checking log properties" foreach ($eventlog in $EventLogList) { $count += 1 $pct = ($Count / $EventLogList.Count * 100) Write-Progress -Activity $Activity -Status $EventLog -PercentComplete $pct
#get all evenlogs from the list and display their properties
$export = Get-WinEvent -ListLog $eventlog | Select-Object -Property LogName,LogFilePath,LogType,RecordCount,MaximumSizeInBytes,FileSize,LastWriteTime,LastAccessTime,IsLogFull,Logmode #display $export
#prep export $exportfile = $resultPath + "_props"+$eventlog + ".csv.txt" if ($exportEnabled) { $export | Export-Csv $exportfile -NoTypeInformation }
#if you want all properties of the logs, replace the named attribute list with * #Get-WinEvent -ListLog $eventlog | Select-Object -Property *
}
$allEvents = New-Object System.Collections.Hashtable
$Count = 0 $Activity = "Checking log detaills" foreach ($eventlog in $EventLogList) { $Count += 1 $pct = ($Count / $EventLogList.Count * 100) $status = $EventLog + " (" + $Count + "/" + $EventLogList.Count +")" Write-Progress -Activity $Activity -Status $status -PercentComplete $pct write-host $count"." $eventlog
[System.Threading.Thread]::CurrentThread.CurrentCulture = New-Object "System.Globalization.CultureInfo" "en-US" #if ($eventlog -eq 'System'){[System.Threading.Thread]::CurrentThread.CurrentCulture = $currentCulture}
# query the event log # store the data in a hashtable, to avoid new queries $allEvents = $Null $allEvents = Get-WinEvent -FilterHashtable @{logname=$eventlog;StartTime=$startdate;level=0,1,2,3,4,5} -ErrorAction SilentlyContinue #DEBUG if ($eventlog -eq "Application") { $allevents}
if ($allEvents.count -eq 0) { $message = "No events for " + $eventlog + "log since "+ $startdate + "." Write-Host $message Write-Host # no data to process, skip processing for current loop Continue }
# Group by event type write-host write-host "Group by Event type" write-host "-------------------"
#display all events grouped by type and sorted by count $export = $allEvents | Group-Object -Property {$_.LevelDisplayName} -NoElement | Sort-Object Count -Descending #display $export | Format-Table -AutoSize
#prep export $exportfile = $resultPath + "_EventNameStats" + $eventlog + ".csv.txt" if ($exportEnabled) {$export | Select-Object -Property Count,Name |Export-Csv $exportfile}
#detailed statistics for non-information events write-host write-host "Statistics by Event ID" write-host "----------------------"
#For events detailed reporting we're only interested in error events #not interested in informational events (level 0 and 4) $evtStats = $allEvents | where -Property level -Notin -Value 0,4 | Group-Object id | Sort-Object Count -Descending $allevents = $Null
#display stats in table format $export = $evtStats | Select-Object Count,Name #display #$export | Format-Table -AutoSize $export
#prep export $exportfile = $resultPath + "_EventIDStats"+ $eventlog + ".csv.txt" if ($exportEnabled) {$export | Export-Csv $exportfile -NoTypeInformation}
# evtStats has number and ID attribute # other attributes must be added: # - errortype name # - Source # - errortype name
[System.Collections.ArrayList]$results = @()
# for each event id in the event statistics # display the most recent event $Activity = "Looking up last event occurrence..."
$i= 0 foreach ($item in $evtStats) { $i += 1 $pct = ($i / $evtStats.Count * 100) $eventID = $item.Name $status = "EventID: "+ $item.Name Write-Progress -Activity $Activity -Status $status -PercentComplete $pct
$customobj = "" | select Count,ErrorID,ErrorType,Source,Message $customobj.Count = $item.Count $customobj.ErrorID = $item.Name
#get most recent event from the eventID $id = $item.Name.ToInt32($Null)
[System.Threading.Thread]::CurrentThread.CurrentCulture = New-Object "System.Globalization.CultureInfo" "en-US" $lastevent = get-winevent -FilterHashtable @{LogName=$eventlog;Id=$id} -MaxEvents 1 -ErrorAction SilentlyContinue
#depending on local settings, query might fail, if it fails reset to local culture if ($lastevent.LevelDisplayName.Length -eq 0) { [System.Threading.Thread]::CurrentThread.CurrentCulture = $currentCulture $lastevent = get-winevent -FilterHashtable @{LogName=$eventlog;Id=$id} -MaxEvents 1 }
$customobj.ErrorType = $lastevent.LevelDisplayName $customobj.Source = $lastevent.ProviderName $customobj.Message = $lastevent.Message
#prep EventID export $exportfile = $resultPath + $eventlog +'_EventID_' + $customobj.ErrorID + ".csv.txt" if ($exportEnabled) { $customobj | Export-Csv $exportfile -NoTypeInformation }
$results += $customobj }
#Latest even details per event write-host "Latest event details per event" write-host "-----------------------------"
#display with format $results | Format-Table -AutoSize
if ($exportEnabled) { $exportfile = $resultPath + "_lastEvents_short_" + $eventlog + ".txt" $results| Format-Table -AutoSize | out-file $exportfile $exportfile = $resultPath + "_lastEvents_detail_" + $eventlog + ".txt" $results | out-file $exportfile }
}
write-host write-host "Script Completed." write-host
# disable transcripting if ($enableLogging) {Stop-Transcript -WarningAction Ignore -ErrorAction SilentlyContinue}
Pop-Location |
Usage
Before you start
- validate your script execution policy
- copy the script to a separate folder where you can execute the script
- validate the script parameters
Script configuration parameters
- $enableLogging
- $TRUE = create a transcript of the script during run (does not work in ISE)
- $FALSE = do not create a verbose log
- $ExportEnabled
- $FALSE = do not export the result to file
- $TRUE = export the results, statistics and event details to file
- $EventLogList
- Default: 'System','Application','Setup','Forefront Identity Manager','Forefront Identity Manager Management Agent'
- $startdate
- Defines from which point in time the event logs must be analysed
- HINT: on a system with a large size of event logs, it's advised to limit the history to x days or x weeks. A large volume event log will impact the usage of script memory.
Credits
A great thanks to Ed Wilson, the Scripting guy for helping out with troubleshooting on the output and display formats.
References
- Use FilterHashTable to Filter Event Log with PowerShell
- Create a Transcript of Commands from the Windows PowerShell ISE
- PowerTip: Check What PowerShell Does When Error Occurs
- Provide Progress for Your Script with a PowerShell Cmdlet
- PowerTip: Create a Transcript of Commands in PowerShell
Useful resources
The Scripting guy forum: The Official Scripting Guys Forum!
The Script Scripting guy repository on Gallery: here.