So I’ve been working on some stuff lately with Event Log Forwarding and Auditing in general and have come to realize the goodness of using Xpath filtering… you know that “XML” tab you never look at when filtering your event logs Smile

image

There are other great blog articles such as http://blogs.technet.com/b/askds/archive/2011/09/26/advanced-xml-filtering-in-the-windows-event-viewer.aspx that go into detail on how to use this functionality.  Unfortunately they don’t seem to address very well what happens when I need to filter on a more complex field such as say “Accesses” in the following event 4656

image

You would think you could just go to the XML data of the event and find the appropriate data and paste it in my filter, i.e. on the XML view of the event I’m interested in the AccessList data

image

so my xpath filter might look like this…

<QueryList>
           <Query Id="0" Path="Security">
              <Select Path="Security">
                 *[EventData[Data[@Name='AccessList'] and (Data='">%%1538 %%4432 %%4435 %%4436')]]
                </Select>
           </Query>
< /QueryList>

Unfortunately that does not work as there are Carriage Returns and New Lines buried in that data field that are not showing up when you view the XML of the data.  There was a good forum post with an answer to this at http://social.technet.microsoft.com/Forums/windowsserver/en-US/bd136cf0-fb9e-48a1-ae2f-3cd4290ab973/issue-with-custom-build-xml-query-in-event-viewer?forum=winserverpowershell which gives some powershell on how to locate those new lines and tabs however it’s kind of a manual process and tedious so I decided to try to throw that concept into a script with a little more logic to help me more easily find the right text to throw in my Xpath filters.

The following is what I came up with…

#Script to export properly formatted text from an audit event xml field to use in an xpath event log filter
#Useful for direct filtering of event logs or in creation of xpath filters for event log forwarding subscriptions
 
#Define following variables to do the search/conversion of the xml field you need
$logname = "Security"
$eventid = "4656"
 
#Getting the first event in event log that matches variables defined above
$evt = Get-WinEvent -FilterHashtable @{LogName=$logname;Id=$eventid} -MaxEvents 1
[xml]$evtx = $evt.ToXml()
foreach ($dataobj in $evtx.Event.EventData.Data)
    {
    if ($dataobj.Name -EQ "AccessList")
        {
            $dataobjstring = $dataobj."#text".ToString()
            $dataobjtext = $dataobjstring.ToCharArray()
            foreach ($character in $dataobjtext)
                {
                $decchar = [Byte[]][Char[]]$character
                #Finding and replacing Carriage Return/New Line symobls with HTML code
                if ($decchar -eq 10) {Write-Host "&#xD;&#xA;" -NoNewline}
                #Finding and replacing Tabs with HTML code
                elseif ($decchar -eq 9) {Write-Host "&#x09;" -NoNewline}
                #Write all other characters to the line as is
                else {Write-Host $character -NoNewline}
                }
        }
    }

Basically you put in the logname and the eventid you are interested in or maybe add some more fields possibly and add them to the filterhashtable.  It will get the latest event in your log that matches this (need to run as admin btw to query Security log) and will parse through and find the new lines and tabs and replace them with the appropriate characters.  In my example here my Xpath filter changed from

This (No Worky)

<QueryList>
           <Query Id="0" Path="Security">
              <Select Path="Security">
                 *[EventData[Data[@Name='AccessList'] and (Data='">%%1538 %%4432 %%4435 %%4436')]]
                </Select>
           </Query>
< /QueryList>

To This (Works)

<QueryList>
           <Query Id="0" Path="Security">
              <Select Path="Security">
                  *[EventData[Data[@Name='AccessList'] and (Data='%%1538&#xD;&#xA;&#x09;&#x09;&#x09;&#x09;%%4432&#xD;&#xA;&#x09;&#x09;&#x09;&#x09;%%4435&#xD;&#xA;&#x09;&#x09;&#x09;&#x09;%%4436&#xD;&#xA;&#x09;&#x09;&#x09;&#x09;')]]
                </Select>
           </Query>
< /QueryList>

Hopefully this helps someone else out as well Smile enjoy.