Powershell-解析windows事件并提取xml数据信息

Powershell-解析windows事件并提取xml数据信息,powershell,events,Powershell,Events,关于这个问题,我需要你的帮助 背景: 我正在寻找一种基于id(例如:302)解析evt(或evtx)文件并提取事件xml字段中可用数据的方法 事件xml格式为: - <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> - <System> <Provider Name="MyProgr" /> <EventID Qua

关于这个问题,我需要你的帮助

背景:

我正在寻找一种基于id(例如:302)解析evt(或evtx)文件并提取事件xml字段中可用数据的方法

事件xml格式为:

- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="MyProgr" /> 
  <EventID Qualifiers="49154">302</EventID> 
  <Level>2</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2021-05-31T14:55:59.040708600Z" /> 
  <EventRecordID>772</EventRecordID> 
  <Channel>Application</Channel> 
  <Computer>Server.lan</Computer> 
  <Security /> 
  </System>
- <EventData>
  <Data>A text relating this event</Data> 
  </EventData>
  </Event>
你有什么好主意来满足我的需要吗

解决方案

$events = Get-WinEvent  -FilterHashTable @{LogName = "Application"; id=302} -MaxEvents 50 | where {$_.Message -like '*'}
foreach($event in $events){
"-"*50                        
            write-host "Date:" $event.TimeCreated
            write-host "Source:"$event.ProviderName
            $event.Message             
"-"*50
}

您需要将事件转换为
xml
,然后读取它:

Get-WinEvent -Path "C:\test.evtx" -Oldest | ConvertTo-Xml -as Stream -Depth 10 > "C:\test\test.xml"
[xml]$xml = Get-Content -Path "C:\test.xml"
现在,您可以轻松阅读并解析输出:

Write-Host "Event: $($xml.Event.System.EventID.'#text')"
Write-Host "The $(([Datetime]$xml.Event.System.TimeCreated.SystemTime).ToString("yyyy-MM-ddThh:mm:ss")) on $($xml.Event.System.Computer), $($xml.Event.System.Provider.Name) raise the following message:`n$($xml.Event.EventData.Data)"
输出:

Event: 302
The 2021-05-31T05:55:59 on Server.lan, MyProgr raise the following message: 
A text relating this event
Event: 302 

The 2021-05-31T14:55:59 on Server.lan, MyProgr raise the following message: 
A text relating this event

使用示例xml文件

对于下面的演示,这里是字符串,但在现实生活中,您可以使用

# Best use below method to load an XML from file, because it automatically detects the file encoding
$xml= New-Object System.XML.XMLDocument
$xml.Load("path\eventfile.evt")

对于您添加的问题,我建议使用Get WinEvent解析事件:

$filter = "*[System[EventID=302 and Provider[@Name='MyProgr']]]"
$result = Get-WinEvent -LogName Application -FilterXPath $filter | ForEach-Object {
    # convert the event to XML and grab the Event node
    $eventXml = ([xml]$_.ToXml()).Event
    # output the properties you need
    [PSCustomObject]@{
        EventID       = $eventXml.System.EventID.'#text'
        TimeCreated   = $eventXml.System.TimeCreated.SystemTime -replace '\.\d+.*$'
        Computer      = $eventXml.System.Computer
        Data          = $eventXml.EventData.Data
    }
}

# output on screen
$result | Format-Table -AutoSize

# save as CSV file if you like
$result | Export-Csv -Path 'path\to\MyProgr_Events_302.csv' -NoTypeInformation
或者使用此结果输出根据模板格式化的内容,同上:

# create an output template with 4 placeholders
# {0} --> The EventID
# {1} --> The TimeCreated SystemTime where everything after the dot is removed
# {2} --> The Computer name
# {3} --> The message
$out = @"
Event: {0} 

The {1} on {2}, MyProgr raise the following message: 
{3}
"@

$result | ForEach-Object {
    # for output, just fill in the placeholders
    $out -f $_.EventID,
            $_.TimeCreated,
            $_.Computer,
            $_.Data
}

谢谢你的回答

我找到了获取所需信息的方法

$events = Get-WinEvent  -FilterHashTable @{LogName = "Application"; id=302} -MaxEvents 50 | where {$_.Message -like '*'}
    foreach($event in $events){
    "-"*50                        
                write-host "Date:" $event.TimeCreated
                write-host "Source:"$event.ProviderName
                $event.Message             
    "-"*50
    }

你好,Shayky,谢谢你的回答,当我说它是xml格式时,它是evt的一部分。打开事件时,可以单击详细信息,然后查看xml格式。在我的例子中,我没有xmlfile@LEFBE哦,好的,看我的更新。你好,谢伊,谢谢你的快速回答。我刚刚测试了解决方案,发现了一个关于时间转换的错误,请参见下面的内容:无法转换类型«System.DateTime»中的值Null。
$xml.Event.System.TimeCreated.SystemTime
?这里是test.xml07/04/2020 15:07:14有一个
获取WinEvent
命令Hello Theo,感谢您提供此示例。我认为xml文件是问题所在,xml结构似乎与我可以进入事件、细节和xml视图的信息截然不同。在事件、细节和xml视图中,我在我的第一篇文章中提供了类似的信息,但在xml文件中,数据更混乱。可以获取302 ID的所有事件并将数据显示到EventData@LEFBE请看我编辑的答案
# create an output template with 4 placeholders
# {0} --> The EventID
# {1} --> The TimeCreated SystemTime where everything after the dot is removed
# {2} --> The Computer name
# {3} --> The message
$out = @"
Event: {0} 

The {1} on {2}, MyProgr raise the following message: 
{3}
"@

$result | ForEach-Object {
    # for output, just fill in the placeholders
    $out -f $_.EventID,
            $_.TimeCreated,
            $_.Computer,
            $_.Data
}
$events = Get-WinEvent  -FilterHashTable @{LogName = "Application"; id=302} -MaxEvents 50 | where {$_.Message -like '*'}
    foreach($event in $events){
    "-"*50                        
                write-host "Date:" $event.TimeCreated
                write-host "Source:"$event.ProviderName
                $event.Message             
    "-"*50
    }