Parse wevtutil XML into a database?
Solution 1:
I'm doing exactly this in a script by way of PowerShell. The whole upload-to-database script is about 18K so I'm not going to repost the entire thing here (though I have the generic ideas here). Handling the XML is pretty simple.
The command to get the event data is what you already know.
wevtutil qe Security /r:$DC /q:"*[System[((EventID=$LogonID or EventID=$FLogonID or EventID=$LogoffID or EventID=$LockoutID) and TimeCreated[@SystemTime > '$LUFilterString'] and TimeCreated[@SystemTime < '$NowFilterString'] )]] " > $DC-events.xml
The variables in that should be clear. I'm tracking login, logout, and lockout events. Generating the "NowFilterString" in the funny format wevtutil requires:
$Now=get-date
$Msec=$now.Millisecond
$NowFilterString=$Now.AddSeconds(-1).AddMilliseconds(-$Msec).ToUniversalTime().ToString("O")
I'm truncating the milliseconds down to zero to better handle edge cases.
So now you have an XML file. Now what? To parse that XML file:
get-content ".\$DC-events.xml" | foreach {
$Event=[xml]$_
$DateTime=[datetime]$Event.event.System.TimeCreated.GetAttribute("SystemTime")
codecodecodecode
}
Accessing individual elements is done by:
foreach ($Data in $Event.event.EventData.get_childNodes()) {
if ($Data.Name -eq "TargetUserName") { $User=$Data."#text"}
elseif ($Data.Name -eq "IpAddress") {$IP=$Data."#text"}
}
Or another example
foreach ($Data in $Event.event.EventData.get_childNodes()) {
if ($Data.Name -eq "TargetUserName") {$User=$Data."#text"}
elseif ($Data.Name -eq "WorkstationName") {$MachineName=$Data."#text"}
elseif ($Data.Name -eq "IpAddress") {$IP=$Data."#text"}
# Ensure only failed logins to the right domain are processed:
elseif ($Data.Name -eq "TargetDomainName") {$Domain=$Data."#text"}
}
I hope this helps you figure out XML parsing. Since this is PowerShell, most of these are readily convertible to standard .NET calls.