3

I have trying to analyze records from the Windows Security log and having a bit of difficulty getting specific values out of some of the logon/logoff events. Let's take a look at a specific example - here's the XML of one of the log entries.

<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
    <System>
        <Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-a5ba-3e3b0328c30d}'/>
        <EventID>4634</EventID>
        <Version>0</Version>
        <Level>0</Level>
        <Task>12545</Task>
        <Opcode>0</Opcode>
        <Keywords>0x8020000000000000</Keywords>
        <TimeCreated SystemTime='2011-08-16T17:15:38.702857400Z'/>
        <EventRecordID>107947</EventRecordID>
        <Correlation/>
        <Execution ProcessID='680' ThreadID='972'/>
        <Channel>Security</Channel>
        <Computer>SRV1.DOMAIN.LOCAL</Computer><Security/>
    </System>
    <EventData>
        <Data Name='TargetUserSid'>S-1-5-21-963414502-3093649508-813756320-3274</Data>
        <Data Name='TargetUserName'>billgates</Data>
        <Data Name='TargetDomainName'>MYDOMAIN</Data>
        <Data Name='TargetLogonId'>0x1c01acc</Data>
        <Data Name='LogonType'>10</Data>
    </EventData>
</Event>

How would I, for instance, go about extracting the 0x1c01acc stored in the Data node with the Name attribute equal to 'TargetLogonId'?

pk.
  • 6,413
  • 1
  • 41
  • 63

3 Answers3

5

Make sure your string is valid XML (ie add </Event> to the end of what you've posted above, and then cast that string as XML:

$xml = [xml]$yourStringHere

Then you can pull out the TargetLogonId like this:

$xml.Event.SelectSingleNode("//*[@Name='TargetLogonId']") | select -ExpandProperty '#text'

Thanks to Shay Levy and this post: http://social.technet.microsoft.com/Forums/en/ITCG/thread/5aa133b0-ea69-4348-9bac-d028ba895024

jbsmith
  • 1,291
  • 7
  • 13
  • Great, this works! I added the missing tag in the XML block in my question as well. I'm still not understanding XPaths entirely, so perhaps you can help me understand why this isn't working. $xmlEvent.SelectSingleNode("Event/EventData/Data[@Name='TargetLogonId']") or $xmlEvent.SelectSingleNode("Event/EventData/*[@Name='TargetLogonId']") – pk. Aug 23 '11 at 13:13
2

If you are given just the raw XML, you can load up the XML document. Since you posted an XML fragment, I'll assume that it was exported from the log and has a <Events> root tag. The tricky part is the namespace.

$xml = [xml](get-content "PathToXml.xml")
$xmlns = New-Object -TypeName System.Xml.XmlNamespaceManager -ArgumentList $xml.NameTable
$xmlns.AddNamespace("el", "http://schemas.microsoft.com/win/2004/08/events/event")
$value = $xml.SelectSingleNode("/Events/el:Event/el:EventData/el:Data[@Name = 'TargetLogonId']/text()", $xmlns).Value

The XML I used:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Events>
<Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
<System>
    <Provider Name='Microsoft-Windows-Security-Auditing' Guid='{54849625-5478-4994-a5ba-3e3b0328c30d}'/>
    <EventID>4634</EventID>
    <Version>0</Version>
    <Level>0</Level>
    <Task>12545</Task>
    <Opcode>0</Opcode>
    <Keywords>0x8020000000000000</Keywords>
    <TimeCreated SystemTime='2011-08-16T17:15:38.702857400Z'/>
    <EventRecordID>107947</EventRecordID>
    <Correlation/>
    <Execution ProcessID='680' ThreadID='972'/>
    <Channel>Security</Channel>
    <Computer>SRV1.DOMAIN.LOCAL</Computer><Security/>
</System>
<EventData>
    <Data Name='TargetUserSid'>S-1-5-21-963414502-3093649508-813756320-3274</Data>
    <Data Name='TargetUserName'>billgates</Data>
    <Data Name='TargetDomainName'>MYDOMAIN</Data>
    <Data Name='TargetLogonId'>0x1c01acc</Data>
    <Data Name='LogonType'>10</Data>
</EventData>
</Event>
</Events>
vcsjones
  • 712
  • 1
  • 8
  • 21
  • vcsjones, thanks for your response, it does indeed work. It covers some information that I want/need to understand, but I'm not getting it yet. Your initial assumption is a bit off. I'm using Get-WinEvent to return an EventLogRecord collection. I'm foreach'ing through them to grab data out. There is no root tag and I'm unsure as to how that changes your answer. When is it necessary to specify the namespace in the SelectSingleNode() method? Why can't I just say $xmlEvent.SelectSingleNode("Event/EventData/Data[@Name = 'TargetLogonId']/text()").Value – pk. Aug 23 '11 at 13:37
1

To get the XML for an event log entry:

Get-WInEvent ‹parameters to select the events› | Foreach-Object { $_.ToXml() }

Then use the techniques shown in the other answers to extract the specific <Data> value.

Richard
  • 5,309
  • 1
  • 22
  • 20