Last active
July 5, 2017 14:00
-
-
Save JustinGrote/33e3765dfcd40a0b2673 to your computer and use it in GitHub Desktop.
Expand-WinEvent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Expand-WinEvent { | |
<# | |
.SYNOPSIS | |
Configured EventLogRecords into EventLogExpandedRecords that are easier to parse | |
.DESCRIPTION | |
Convert eventRecords into a more parseable object format, including custom event properties | |
By expanding the Event XML data into individual properties, this makes WinEvents easier to work with and parse | |
.NOTES | |
Inspired by http://blogs.technet.com/b/ashleymcglone/archive/2013/08/28/powershell-get-winevent-xml-madness-getting-details-from-event-logs.aspx | |
.EXAMPLE | |
PS C:\> Get-Winevent -LogName Application | Expand-WinEvent | |
Takes all application logs and expands their properties. | |
#> | |
param ( | |
#Specifies an event generated by Get-WinEvent. WARNING: DOES NOT WORK WITH GET-EVENTLOG | |
[Parameter(Mandatory,ValueFromPipeline)] | |
[System.Diagnostics.Eventing.Reader.EventLogRecord]$EventLogRecord, | |
#If specified, outputs a hashtable of object properties rather than the object itself. Useful for creating a subtype. | |
[Switch]$OutHashTable | |
) | |
begin { | |
#Define the event type and default display properties | |
$CustomEventRecordType = "System.Diagnostics.Eventing.Reader.EventLogRecordExpanded" | |
Update-TypeData -TypeName $CustomEventRecordType -DefaultDisplayPropertySet TimeCreated,ID,ProviderName,TaskDisplayName -Force | |
} #Begin | |
process { | |
$EventLogRecord | foreach { | |
$EventProperties = [ordered]@{ | |
TimeCreated = $PSItem.TimeCreated | |
ID = $PSItem.ID | |
LevelDisplayName = $PSItem.LevelDisplayName | |
ProviderName = $PSItem.ProviderName | |
TaskDisplayName = if ($PSItem.TaskDisplayName) {$PSItem.TaskDisplayName} else {$null} | |
MachineName = $PSItem.MachineName | |
Message = $PSItem.Message | |
RawEvent = $PSItem | |
} | |
#Add all the attribute properties of the event object. This is dynamic and works for all events. | |
$i = 1 | |
([xml]$PSItem.toxml()).Event.EventData.Data | foreach { | |
#Skip in the event this is a classic log with no attribute properties | |
if ($PSItem) { | |
#If the data is unstructured, just create as "Property1","Property2", etc. | |
if ($PSItem -isnot [System.XML.XMLElement]){ | |
$PropertyName = "Property" + $i | |
$EventProperties.Add($PropertyName,$PSItem) | |
$i++ | |
} | |
else { | |
if ($EventProperties.Contains($PSItem.Name)) { | |
$PropertyName = "property" + $PSItem.Name | |
} else { $PropertyName = $PSItem.Name } | |
$EventProperties.Add($PropertyName,$PSItem."#text") | |
} | |
} #If ($PSItem) | |
} #ForEach | |
if ($OutHashTable) { | |
$EventProperties | |
} | |
else { | |
$result = [PSCustomObject]$EventProperties | |
#Assign custom type so it shows properly in Get-Member | |
$result.PSTypeNames.Insert(0,$customEventRecordType) | |
$result | |
} | |
} #ForEach | |
} #Process | |
} #Expand-WinEvent |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment