0

An EventLog was exported from a server to a file named Exported_ErrorLog.evtx.

I would like to

  • filter all entries created in 2023
  • group by Text <EventData><Data> (see xml below)
  • and count

I am able to read from file (see Learn Powershell - Get-WinEvent)

Get-WinEvent -Path 'C:\dev\powershell\EventLogs\Exported_ErrorLog.evtx'

But the command help from

Powershell_Get-WinEvent_fromFile

does not really help how i can access the entries underlying properties.

.NET Log Entry

For example one Entry looks like this

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
  <Provider Name=".NET Runtime" /> 
  <EventID Qualifiers="0">1000</EventID> 
  <Level>2</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2023-01-16T21:53:35.0432325Z" /> 
  <EventRecordID>7198</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>our.puny.server.dotcombubble</Computer> 
  <Security /> 
</System>
<EventData>
  <Data>
   Category: Microsoft.EntityFrameworkCore.Database.Command 
   EventId: 20102 
   SpanId: d212092536b29df0 
   TraceId: b6c16c00e29da216e66009bc80c78c2d 
   ParentId: 0000000000000000 
   RequestId: 8000023a-0001-fd00-b63f-84710c7967bb 
   RequestPath: /User/Login 
   ActionId: f65f32b4-7dff-4c5d-8463-4f350cae7583 
   ActionName: /User/Login Failed executing DbCommand (16ms) 
       [Parameters=[@__user_UserId_0= ... FROM [dbo].[myTbl] AS [c] 
                    WHERE [c].[userId] = @__user_UserId_0
  </Data> 
</EventData>
  </Event>

Application Error Log Entry

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
  <Provider Name="Application Error" /> 
  <EventID Qualifiers="0">1000</EventID> 
  <Level>2</Level> 
  <Task>100</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2023-01-18T07:59:41.3126855Z" /> 
  <EventRecordID>7461</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>our.puny.server.dotcombubble</Computer> 
  <Security /> 
</System>
<EventData>
  <Data>w3wp.exe</Data> 
  <Data>10.0.17763.1</Data> 
  <Data>cfdb13d8</Data> 
  <Data>KERNELBASE.dll</Data> 
  <Data>10.0.17763.3650</Data> 
  <Data>62549bf9</Data> 
  <Data>e0434352</Data> 
  <Data>0000000000034859</Data> 
  <Data>530</Data> 
  <Data>01d92b12c51b52c6</Data> 
  <Data>c:\windows\system32\inetsrv\w3wp.exe</Data> 
  <Data>C:\WINDOWS\System32\KERNELBASE.dll</Data> 
  <Data>ef0199e6-4724-4996-ad46-69cf5db0f138</Data> 
  <Data /> 
  <Data /> 
</EventData>
</Event>

Questions

It seems to me that the cmd-let documentation is brief.

  • Provides .Net better documented libraries to read event logs?
  • How can i access the properties <EventData><Data> of each log entry?
  • How to group all entries with the same <EventData><Data>?
  • How can the result from Get-WinEvent -Path ... be piped to another command?

Edit / Update: Attempts

With the help of mikes answers below i wrote this script

$filter = @{     
    ID        = 1000, 1003
    startTime = [datetime]"1/1/2023"
    path      = "C:\dev\powershell\EventLogs\Exported_ErrorLog.evtx"
} 

$Events = Get-WinEvent -FilterHashtable $filter

$CustomEventObjects = foreach ($event in $Events) {
    $xmlevent = [xml]$event.toxml()

    [pscustomobject]@{
        TimeCreated    = $event.TimeCreated
        EventRecordID  = $event.RecordId
        Message        = $event.Message
    }
}
$CustomEventObjects

I assume that $event is related to System.Diagnostics.Eventing.Reader.EventLogRecord and EventRecord

The script above results in this output

EventLog

Two things are unclear

  • Why is the message truncated and how can it be fixed?
  • How to use $xmlevent to acces any properties
surfmuggle
  • 5,527
  • 7
  • 48
  • 77

1 Answers1

0

This appears to be a PowerShell question, though you also have a c# tag, so hopefully this is what you're looking for. I also don't have enough SO reputation to comment, so apologies if this answer is premature.

Events have a toxml method which makes this possible:

$event.toxml()

You could continue to work with the XML directly, or convert it to a PS Object, which is what I've done ([xml]$event.toxml()). You can swap out your event data values as appropriate.

$filter = @{     
    ID        = 1000, 1003
    startTime = [datetime]"1/1/2023"
    path      = "C:\tmp\SavedEvents.evtx"
} 
    
$Events = Get-WinEvent -FilterHashtable $filter
    
$CustomEventObjects = foreach ($event in $events) {
    $xmlevent = [xml]$event.toxml()
    
    [pscustomobject]@{
        TimeCreated = $event.TimeCreated
        RequestPath = ($xmlevent.Event.EventData.Data | Where-Object name -eq RequestPath).'#text'
        ActionName  = ($xmlevent.Event.EventData.Data | Where-Object name -eq ActionName).'#text'
        ActionId    = ($xmlevent.Event.EventData.Data | Where-Object name -eq ActionId).'#text'
    }
}

#possible outputs, but you can take it from here:
$CustomEventObjects | Group-Object RequestPath
$CustomEventObjects | Group-Object ActionName
$CustomEventObjects | Group-Object ActionId

EDIT 25Jan2023 - replaced my example attributes with 3 from your actual event.

  • This output is returned `Count Name` and `Group` and `{@{TimeCreated=24.01.2023 12:04:32; ExceptionCode=; PackageFullName=}, @{Tim…` – surfmuggle Jan 24 '23 at 18:36
  • PackageFullName and ExceptionCode were examples, since I don't have an event log with your events. Update as appropriate for your given event. Additionally, if you don't want to use toxml, see this article to manually map the xml template: https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/how-to-list-xml-elements-in-eventdata – mike crowley Jan 24 '23 at 18:58
  • What i do not understand is how to put the pieces together. Using your `$filter` in this command `Get-WinEvent -FilterHashtable $filter | Format-List -Property *` returns among others `RecordId`, `ProviderName`, `Message`. It seems that `Message` contains the values from the xml nodes `....` . Inside `[pscustomobject]@{ ... }` i added `Message = $event.Message`. This looks good but the Message is truncated. See update in my question. – surfmuggle Jan 24 '23 at 22:44
  • Where I used ExceptionCode and PackageFullName, use valid fields from your event, such as RequestPath. Note that its twice per line, like in my example. Also, in your edited question, you're not referencing $xmlevent at all anymore. This is where your fields are. – mike crowley Jan 25 '23 at 05:59
  • I tried `Task = $xmlevent.Task` and `Task = $xmlevent.System.Task` and other properties from the provided `XML` above. But wihout success. Using just `$xmlevent` returns `document` – surfmuggle Jan 25 '23 at 08:01
  • The "message" attribute is text. You can parse out this string if you want, but its cleaner to use the `toxml()` method. In PowerShell, strings are truncated unless you expand the values, but this is a topic somewhat beyond the scope of event log parsing. My example uses both the basic event properties as well as XML data, that is why the `pscustomobject` includes keys for both `$event` and `$xmlevent`. – mike crowley Jan 25 '23 at 15:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251389/discussion-between-mike-crowley-and-surfmuggle). – mike crowley Jan 25 '23 at 15:30