Search code examples
xmlpowershellwindows-11event-viewer

How to convert Event Viewer data to XML for filtration and get rid of DocumentElement node error?


There was an answer posted here to one of my questions: https://stackoverflow.com/a/74994896/20682592

the code is this:

$a = Get-WinEvent @{ LogName='Security' } -maxevents 1
$xml = [xml]$a.toxml()


$xml.event.eventdata.data

what I want to do is to show all the events in the Security log with ID 5152 and then filter out the output of it based on filter origin value.

so I changed it to this:

$a = Get-WinEvent @{ LogName='Security'; Id=5152; }

$xml = [xml]$a.toxml()

$xml.event.eventdata.data | Where-Object {$_.FilterOrigin -ne "Stealth"}

but it doesn't work like I want, doesn't filter out events whose filterOrigin is Stealth and also gives me this error:

InvalidArgument: untitled:Untitled-3:3:1
Line |
   3 |  $xml = [xml]$a.toxml()
     |  ~~~~~~~~~~~~~~~~~~~~~~
     | Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "This document already has a 'DocumentElement' node."

enter image description here

the original answer posted in there also shows the same error if I remove -maxevents 1 which I need to do because I don't want to only see 1 event.

how can I make it work?

Update, using Theo comment, I managed to do this:

foreach ($event in (Get-WinEvent -FilterHashtable @{LogName='Security';ID=5152})) {
     $xml = [xml]$event.toxml(); 

     $xml.event.eventdata.data | Where-Object {$_.FilterOrigin -ne "Stealth" -or $_.FilterOrigin -ne "Unknown" } | ft -wrap

}

but it's not filtering out FilterOrigins Stealth and Unknown. what am i missing here?

enter image description here


Solution

  • Since you want the name/#text pairs to be an object instead, here's a way to convert it. I'm using the where-object form without the curly braces. The -notmatch regex expression pipe symbol means "or". This way you can treat all the data as one group.

    foreach ($event in Get-WinEvent -FilterHashtable @{LogName='Security'}) {
      $xml = [xml]$event.toxml();
      $xml.event.eventdata.data | 
      foreach { $hash = @{} } { $hash[$_.name] = $_.'#text' } { [pscustomobject]$hash } |
      Where FilterOrigin -notmatch 'stealth|unknown|query user|default' 
    }