A Powershell Cmdlet that gets events from event logs and event tracing log files on local and remote computers enhances them with details from their XML representation.
The Get-EnhancedWinEvent cmdlet gets events from event logs, including classic logs, such as the System and Application logs, and enhances them with details from their XML representation ... which for some reason often contains more detail, such as property names.
For example, the JSON representation of a logon event (ID 4624) from Get-WinEvent typically looks like this (note particularly the list of properties with no keys to identify what they actually are):
{
"Id": 4624,
"Version": 2,
"Qualifiers": null,
"Level": 0,
"Task": 12345,
"Opcode": 0,
"Keywords": -1234567890123456789,
"RecordId": 553564,
"ProviderName": "Microsoft-Windows-Security-Auditing",
"ProviderId": "<GUID>",
"LogName": "Security",
"ProcessId": 123,
"ThreadId": 4567,
"MachineName": "<HOSTNAME>",
"UserId": null,
"TimeCreated": "\/Date(12345678901234)\/",
"ActivityId": "<GUID>",
"RelatedActivityId": null,
"ContainerLog": "Security",
"MatchedQueryIds": [],
"Bookmark": {},
"LevelDisplayName": "Information",
"OpcodeDisplayName": "Info",
"TaskDisplayName": "Logon",
"KeywordsDisplayNames": ["Audit Success"],
"Properties": [{"Value": {"BinaryLength": 12,"AccountDomainSid": null,"Value": "S-1-5-18"}},{"Value": "<HOSTNAME>$"},{"Value": "WORKGROUP"},{"Value": 999},{"Value": {"BinaryLength": 12,"AccountDomainSid": null,"Value": "S-1-5-18"}},{"Value": "SYSTEM"},{"Value": "NT AUTHORITY"},{"Value": 999},{"Value": 5},{"Value": "Advapi "},{"Value": "Negotiate"},{"Value": "-"},{"Value": "00000000-0000-0000-0000-000000000000"},{"Value": "-"},{"Value": "-"},{"Value": 0},{"Value": 740},{"Value": "C:\\Windows\\System32\\services.exe"},{"Value": "-"},{"Value": "-"},{"Value": "%%1833"},{"Value": "-"},{"Value": "-"},{"Value": "-"},{"Value": "%%1843"},{"Value": 0},{"Value": "%%1842"}
],
"Message": "<LONG_UNSTRUCTURED_MESSAGE>"
}
The XML representation of that same event (via $event.ToXml()
) has the names of those properties, and some other interesting information as well. The JSON represntation of the enhanced version of this event adds the following "event" property built from the XML data:
{
"Event": {
"System": {
"TimeCreated": { "SystemTime": "2019-01-01T02:34:56.789012300Z" },
"Level": "0",
"Opcode": "0",
"Version": "2",
"Provider": {
"Guid": "<GUID>",
"ProviderName": "Microsoft-Windows-Security-Auditing"
},
"Security": {},
"Computer": "<HOSTNAME>",
"EventID": "4624",
"Channel": "Security",
"Task": "12544",
"Correlation": { "ActivityID": "<GUID>"},
"Execution": {
"ThreadID": "4567",
"ProcessID": "123"
},
"Keywords": "0x8020000000000000",
"EventRecordID": "553928"
},
"EventData": {
"KeyLength": "0",
"SubjectUserSid": "S-1-5-18",
"SubjectLogonId": "0x3e7",
"AuthenticationPackageName": "Negotiate",
"TargetOutboundUserName": "-",
"ImpersonationLevel": "%%1833",
"LogonProcessName": "Advapi ",
"TargetDomainName": "NT AUTHORITY",
"IpPort": "-",
"LmPackageName": "-",
"IpAddress": "-",
"SubjectDomainName": "WORKGROUP",
"ProcessName": "C:\\Windows\\System32\\services.exe",
"TransmittedServices": "-",
"ProcessId": "0x2e4",
"SubjectUserName": "<HOSTNAME>$",
"TargetOutboundDomainName": "-",
"TargetLogonId": "0x3e7",
"TargetUserName": "SYSTEM",
"RestrictedAdminMode": "-",
"LogonGuid": "{00000000-0000-0000-0000-000000000000}",
"LogonType": "5",
"TargetLinkedLogonId": "0x0",
"VirtualAccount": "%%1843",
"TargetUserSid": "S-1-5-18",
"ElevatedToken": "%%1842",
"WorkstationName": "-"
}
}
}
This is very helpful for use in things like log aggregation and forensics. The current version has all the XML-derived properties as strings, which is a minor limitation to be addressed in future releases. To be clear, sometimes the XML does not add much clarity, but even in those cases it is better to have the full picture of what the event contained.
The cmdlet gets data from event logs that are generated by the Windows Event Log technology introduced in Windows Vista. And, events in log files generated by Event Tracing for Windows (ETW). By default, this cmdlet returns event information in the order of newest to oldest.
You can get events from selected logs or from logs generated by selected event providers. And, you can combine events from multiple sources in a single command. This cmdlet allows you to filter events using XPath queries, structured XML queries, and hash table queries.
If you're not running PowerShell as an Administrator, you might see error messages that you cannot retrieve information about a log.
It outputs objects (hashtables) for each event, suitable for the Powershell pipeline and conversion to other formats such as JSON. It is a wrapper around Get-WinEvent and supports all the same parameters except -ListLog and -ListProvider.
Additional information and examples for Get-WinEvent, most of which apply to Get-EnhancedWinEvent, is available at from Microsoft.
PS C:\> Import-Module .\path\to\Get-EnhancedWinEvent.psm1
Import the module to get access to the Get-EnhancedWinEvent
cmdlet
PS C:\> Get-EnhancedWinEvent -Path ".\Application.evtx"
Gets all events from the provided Application.evtx file
PS C:\> Get-EnhancedWinEvent -Path ".\Security.evtx" -FilterXPath "*[System[EventID=4624]"
Gets all logon events (ID 4624) from the provided Security.evtx file.
PS C:\> Get-EnhancedWinEvent -Path ".\Security.evtx" -FilterXPath "*[System[EventID=4624]" -MaxEvents 25
Gets at most the newest 25 logon events (ID 4624) from the provided Security.evtx file.
PS C:\> Get-EnhancedWinEvent -Path ".\Security.evtx" -FilterXPath "*[System[EventID=4624]" -MaxEvents 25 | ConvertTo-Json -Depth 100 | Out-File ./security.json -Encoding utf8
Gets at most the newest 25 logon events (ID 4624) from the provided Security.evtx file, which is piped to ConvertTo-Json to get nice compressed, serialized output (-Depth is set to the max of 100 because the default is 2, leading to frustrating bugs).
This is then piped to a UTF-8 encoded file for use in other tools like filebeat or jq (the default is UTF-16 if you use the redirect operator (>)).
Specifies the name of the computer that this cmdlet gets events from the event logs. Type the NetBIOS name, an Internet Protocol (IP) address, or the fully qualified domain name (FQDN) of the computer. The default value is the local computer, localhost. This parameter accepts only one computer name at a time.
To get event logs from remote computers, configure the firewall port for the event log service to allow remote access.
This cmdlet does not rely on PowerShell remoting. You can use the ComputerName parameter even if your computer is not configured to run remote commands.
Specifies a user account that has permission to perform this action. The default value is the current user.
Type a user name, such as User01 or Domain01\User01. Or, enter a PSCredential object, such as one generated by the Get-Credential cmdlet. If you type a user name, you are prompted for a password. If you type only the parameter name, you are prompted for both a user name and a password.
Specifies a query in hash table format to select events from one or more event logs. The query contains a hash table with one or more key/value pairs.
Hash table queries have the following rules:
- Keys and values are case-insensitive.
- Wildcard characters are valid only in the values associated with the LogName and ProviderName keys.
- Each key can be listed only once in each hash table.
- The Path value takes paths to .etl, .evt, and .evtx log files.
- The LogName, Path, and ProviderName keys can be used in the same query.
- The UserID key can take a valid security identifier (SID) or a domain account name that can be used to construct a valid System.Security.Principal.NTAccount object.
- The Data value takes event data in an unnamed field. For example, events in classic event logs.
- The asterisk (*) key represents a named event data field.
- When this cmdlet cannot interpret a key/value pair, it interprets the key as a case-sensitive name for the event data in the event.
The valid key/value pairs are as follows:
- LogName (
String[]
) - ProviderName (
String[]
) - Path (
String[]
) - Keywords (
Long[]
) - ID (
Int32[]
) - Level (
Int32[]
) - StartTime (
DateTime
) - EndTime (
DateTime
) - UserID (
SID
) - Data (
String[]
) - (Asterisk) * (
String[]
)
Specifies an XPath query that this cmdlet select events from one or more logs.
For more information about the XPath language, see XPath Reference and the Selection Filters section of the Event Selection in the MSDN library.
Specifies a structured XML query that this cmdlet selects events from one or more event logs.
To generate a valid XML query, use the Create Custom View and Filter Current Log features in Windows Event Viewer. Use the items in the dialog box to create a query, and then click the XML tab to view the query in XML format. You can copy the XML from the XML tab into the value of the FilterXml parameter. For more information about the Event Viewer features, see Event Viewer Help.
Use an XML query to create a complex query that contains several XPath statements. The XML format also allows you to use a Suppress XML element that excludes events from the query. For more information about the XML schema for event log queries, see Query Schema and the XML Event Queries section of the Event Selection in the MSDN library.
Gets debug and analytic logs, in addition to other event logs. The Force parameter is required to get a debug or analytic log when the value of the name parameter includes wildcard characters.
By default, this cmdlet excludes these logs unless you specify the full name of a debug or analytic log.
Specifies the event logs that this cmdlet get events from. Enter the event log names in a comma-separated list. Wildcards are permitted. You can also pipe log names to this cmdlet.
Specifies the maximum number of events that are returned. Enter an integer such as 100. The default is to return all the events in the logs or files.
Indicate that this cmdlet gets the events in oldest-first order. By default, events are returned in newest-first order.
This parameter is required to get events from .etl and .evt files and from debug and analytic logs. In these files, events are recorded in oldest-first order, and the events can be returned only in oldest-first order.
Specifies the path to the event log files that this cmdlet get events from. Enter the paths to the log files in a comma-separated list, or use wildcard characters to create file path patterns.
This cmdlet supports files with the .evt, .evtx, and .etl file name extensions. You can include events from different files and file types in the same command.
Specifies, as a string array, the event log providers from which this cmdlet gets events. Enter the provider names in a comma-separated list, or use wildcard characters to create provider name patterns.
An event log provider is a program or service that writes events to the event log. It is not a PowerShell provider.
None, though future support is possible for System.String, System.Xml.XmlDocument and System.Collections.Hashtable. This is to match Get-WinEvent, which supports pipeline values for LogName (string), a FilterXML query, or a FilterHashtable query.
System.Collections.Hashtable objects
Get-EnhancedWinEvent, like Get-WinEvent, runs on Windows Vista, Windows Server 2008 R2, and later versions of Windows.
Get-EnhancedWinEvent, like Get-WinEvent, is not supported in Windows Pre-installation Environment (Windows PE).
Submit issues, contribute, and view the license at the github repo.
See the included LICENSE
file for license terms and NOTICE file for attribution.