Following PowerShell Module provides basic functionality of working with Windows Event Logs.
While you can use the script in a standard way by downloading it from GitHub, putting it in right places and getting it to run…there is much simpler way. Since the script was published to PowerShell Gallery you can simply install the module and run it from anywhere. Just use Install-Module PSEventViewer.
Install-Module -Name PSEventViewer
If you ever need to update it…
Update-Module -Name PSEventViewer
That's a very fair question… why would I use PSEventViewer (Get-Events) instead of simply relying on Get-WinEvent that comes built-in. Well PSEventViewer is actually a wrapper around Get-WinEvent. But it has at least 3 more features you get for free that are better then original. That is… runspaces, splitting Event ID's into chunks, and converting XML data into variables. The first option gives you parallel reading of event logs (think how it impacts your search over 2,5,10 servers if you do them one by one). Second option overcomes Windows limit which is a limit of 22 event id's that can be asked with one query (you get empty results on 23 and more). Third option gives you much easier reading of additional, hidden data. Think how hard it is to get data from Message…
If you're browsing for events via Event Viewer it's a pretty obvious one. Administrator did clear Security Log. But how would you do it via PowerShell?
Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 1102 } -ComputerName 'AD1' | Format-List *
So you get all the output, almost like you get it when using Event Viewer. Where is the problem? All that text regarding Who/When is stored as one text, ‘Message.' This text changes from event to event, and parsing gets tricky. This is where the Get-Events (PSEventViewer) function comes to play.
Import-Module PSEventViewer -Force Get-Events -LogName 'Security' -Id 1102 -ComputerName 'AD1' | Format-List *
Notice this the difference? All the values you cared about that were stored as Message, are now also stored as variables on the Event. Nifty ha?
Basic functionality of this module is ability to quickly work thru events.
Import-Module PSEventViewer -Force Clear-Host # Define dates $DateFrom = (get-date).AddHours(-11) $DateTo = (get-date).AddHours(1) $IDRequiringSplitOver23 = 1102, 5136, 5137, 5141, 4364, 4647, 4672, 4727, 4730, 4731, 4734, 4759, 4760, 4754, 4758, 4728, 4729, 4732, 4733, 4756, 4757, 4761, 4762, 4725, 4722, 4725, 4767, 4723, 4724, 4726, 4740, 4720, 4738 $IDNotRequiringSplit = 1102, 5136, 5137, 5141, 4364, 4647, 4672, 4727, 4730, 4731, 4734, 4759, 4760, 4754, 4758, 4728, 4729, 4732, 4733, 4756 $ID = 916 $TestServers = 'AD1.ad.evotec.xyz' Get-Events -DateFrom $DateFrom -DateTo $DateTo -EventId $id -LogType 'Application' -Verbose -maxevents 5 # | fl * Get-Events -DateFrom $DateFrom -DateTo $DateTo -EventId 916 -LogType 'Application' -MaxEvents 10 -Verbose Get-Events -EventId 916 -LogType 'Application' -MaxEvents 10 -Verbose Get-Events -Id $ID -LogName 'Security' -DateFrom $DateFrom -DateTo $DateTo -Verbose $TestEvents0 = Get-Events -DateFrom $DateFrom -DateTo $DateTo -EventId $id -LogType 'Application' -Verbose -Maxevents 5 -Oldest $TestEvents0 | Select-Object Computer, TimeCreated, Id, LevelDisplayName, Message | Format-Table -AutoSize $TestEvents1 = Get-Events -Machine $TestServers -Id $IDNotRequiringSplit -LogName 'Security' -DateFrom $DateFrom -DateTo $DateTo -Verbose $TestEvents1 | Select-Object Computer, TimeCreated, Id, LevelDisplayName, Message | Format-Table -AutoSize $TestEvents2 = Get-Events -Machine $TestServers -Id $IDRequiringSplitOver23 -LogName 'Security' -DateFrom $DateFrom -DateTo $DateTo -Verbose $TestEvents2 | Select-Object Computer, TimeCreated, Id, LevelDisplayName, Message | Format-Table -AutoSize $ID = 4768 #, 4722, 4723, 4724, 4725, 4726, 4738, 4740, 4767 $TestEvents3 = Get-Events -Machine $TestServers -Id $ID -LogName 'Security' -MaxEvents 2000 -Verbose # -DisableParallel $TestEvents3 | Select-Object Computer, TimeCreated, Id, LevelDisplayName, Message | Format-Table -AutoSize
For the verification process of how module handles different type of events following code was used
Import-Module PSEventViewer -Force Clear-Host Write-Color 'Start processing events - Tests for expected output' -Color Red # #, 4722, 4723, 4724, 4725, 4726, 4738, 4740, 4767 $TestServers = 'AD1.ad.evotec.xyz' $ID = 104 $TestEvents1 = Get-Events -Machine $TestServers -Id $ID -LogName 'System' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 16384 $TestEvents2 = Get-Events -Machine $TestServers -Id $ID -LogName 'Application' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 4634 $TestEvents3 = Get-Events -Machine $TestServers -Id $ID -LogName 'Security' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 4688 $TestEvents4 = Get-Events -Machine $TestServers -Id $ID -LogName 'Security' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 105 $TestEvents5 = Get-Events -Machine $TestServers -Id $ID -LogName 'Application' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 7036 $TestEvents6 = Get-Events -Machine $TestServers -Id $ID -LogName 'System' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 32 $TestEvents7 = Get-Events -Machine $TestServers -Id $ID -LogName 'System' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 1014 $TestEvents8 = Get-Events -Machine $TestServers -Id $ID -LogName 'System' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 8198 $TestEvents9 = Get-Events -Machine $TestServers -Id $ID -LogName 'Application' -MaxEvents 1 #-DisableParallel #-Verbose $ID = 10154 $TestEvents10 = Get-Events -Machine $TestServers -Id $ID -LogName 'System' -MaxEvents 1 #-DisableParallel #-Verbose Write-Color 'Jump 1' -Color Green $TestEvents1 | fl Channel, BackupPath, SubjectDomainName, SubjectUserName Write-Color 'Jump 2' -Color Yellow $TestEvents2 | fl NoNameA0, NoNameA1 Write-Color 'Jump 3' -Color Green $TestEvents3 | fl TargetUserName, TargetDomainName, TargetUserSid Write-Color 'Jump 4' -Color Green $TestEvents4 | fl Computer, SubjectUserSid, NewProcessName, ParentProcessName Write-Color 'Jump 5' -Color Green $TestEvents5 | fl NoNameA0, NoNameA1, NoNameA2 Write-Color 'Jump 6' -Color Green $TestEvents6 | fl param1, param2 Write-Color 'Jump 7' -Color Green $TestEvents7 | fl NoNameB1, NoNameB2 Write-Color 'Jump 8' -Color Green $TestEvents8 | fl QueryName, AddressLength Write-Color 'Jump 9' -Color Green $TestEvents9 | fl NoNameA0, NoNameA1 Write-Color 'Jump 10' -Color Green $TestEvents10 | fl spn1, spn2 Write-Color 'End processing events - Tests for expected output' -Color Red
All the use cases and comparison with Get-WinEvent and Get-EventLog are provided as part of this large article I wrote recently. Make sure you read it for a full overview. Also if you want to know when updates are out, or changes occur I would suggest monitoring project on GitHub as changes happen there first. This project is highly connected to PSWinReporting and new features are added when that project demands it.