Powershell - Tail Windows Event Log? Is it possible?
I've done this on occasion:
$idx = (get-eventlog -LogName System -Newest 1).Indexwhile ($true){ start-sleep -Seconds 1 $idx2 = (Get-EventLog -LogName System -newest 1).index get-eventlog -logname system -newest ($idx2 - $idx) | sort index $idx = $idx2 }
Per MSDN docs:
Get-WinEvent
is designed to replace theGet-EventLog
cmdlet on computers running Windows Vista and later versions of Windows.Get-EventLog
gets events only in classic event logs.Get-EventLog
is retained in Windows PowerShell for backward compatibility.
And spurred on by my own need to tail a non-classic event log (would that be an event log nouveau perchance?) here is the wonderfully concise code of @mjolinor repurposed to use Get-WinEvent
:
Set-PSDebug -Strictfunction Get-WinEventTail($LogName, $ShowExisting=10) { if ($ShowExisting -gt 0) { $data = Get-WinEvent -provider $LogName -max $ShowExisting $data | sort RecordId $idx = $data[0].RecordId } else { $idx = (Get-WinEvent -provider $LogName -max 1).RecordId } while ($true) { start-sleep -Seconds 1 $idx2 = (Get-WinEvent -provider $LogName -max 1).RecordId if ($idx2 -gt $idx) { Get-WinEvent -provider $LogName -max ($idx2 - $idx) | sort RecordId } $idx = $idx2 # Any key to terminate; does NOT work in PowerShell ISE! if ($Host.UI.RawUI.KeyAvailable) { return; } }}
I added in a few bells and whistles for convenience:
- By default it shows the last 10 lines of the log initially, then concatenates new entries as they occur--you can adjust that to any number via the
ShowExisting
parameter. - It sorts records with oldest first (contrary to
Get-WinEvent
's default) due to the natural order that tail requires. - You can press any key to terminate (but not in PowerShellISE).
First, thank you Michael!
Slight refinement for my use case that includes showing the entire multi-line message value.
function Get-WinEventTail($Provider="JobRequestQueueConsumerBackgroundService", $ShowExisting=10) { $formatProperty = @{ expression={$_.TimeCreated}; label="TimeCreated"}, @{ expression={$_.Message}; label="Message"; width=100} if ($ShowExisting -gt 0) { $data = Get-WinEvent -ProviderName $Provider -max $ShowExisting if ($data) { $data | sort RecordId | Format-Table -Property $formatProperty -Wrap $idx = $data[0].RecordId } } else { $idx = (Get-WinEvent -ProviderName $Provider -max 1).RecordId } while ($true) { start-sleep -Seconds 1 $idx2 = (Get-WinEvent -ProviderName $Provider -max 1).RecordId if ($idx2 -gt $idx) { Get-WinEvent -ProviderName $Provider -max ($idx2 - $idx) | sort RecordId | Format-Table -Property $formatProperty -Wrap } $idx = $idx2 # Any key to terminate; does NOT work in PowerShell ISE! if ($Host.UI.RawUI.KeyAvailable) { return; } }}Get-WinEventTail
The -Wrap
option was necessary to show a multi-line message, otherwise ellipsis would truncate the message at the end of the first line. Setting the column width did NOT help.