-
Notifications
You must be signed in to change notification settings - Fork 10
/
Expand-WinEvent.ps1
83 lines (69 loc) · 3.27 KB
/
Expand-WinEvent.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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