Summary: Learn how to use Windows PowerShell to filter remote event log entries in a Windows Vista computer.

Hey, Scripting Guy! Question  Hey, Scripting Guy! I thought your article yesterday was really great. It was interesting how a rather simple change could provide such a big gain in performance. The problem is that it does not appear to work on my Windows XP laptop. That laptop is really old, but it is running Windows PowerShell 2.0. So, I tried it on my Windows Vista desktop, and the command still did not work. I am beginning to wonder if you were having an off day yesterday. It might be understandable with all the stuff you were into last week. I just thought I would give you the benefit of the doubt.

—JJ

Hey, Scripting Guy! Answer Hello JJ,

Microsoft Scripting Guy, Ed Wilson here. You are right, last week was an incredible Windows PowerShell week, and I got to meet a huge number of awesome Microsoft MVPs, as well as a great group of Microsoft engineers. It was a long week, and (seemingly) an even longer flight, but I learned a lot, and I had a tremendous amount of fun. I appreciate your willingness to cut me some slack, but in this particular instance, such slack cutting is not warranted. You happen to be suffering from goofy cmdlet syndrome—luckily it is curable by upgrading to Windows 7 or Windows Server 2008 R2.

The Get-WinEvent cmdlet, although present on a Windows PowerShell 2.0 installation for Windows XP, does not work. In a way, this makes sense because of the changes in the Event Logs that took place in Windows Vista. The error message generated in Windows XP makes it clear that the Get-WinEvent cmdlet requires at least Windows Vista to run. The error message is shown here.

Image of error message

So far, so good. This sort of makes sense. But what about your problem with Windows Vista (incidentally, the same problem exists on Windows Server 2008)? In Windows Vista, the Get-WinEvent cmdlet is unable to use the FilterHashTable parameter; the other functionalities of the Get-WinEvent cmdlet work properly. This does not mean that all filters do not work, only the FilterHashTable filter. This is shown in the following image.

Image of error message

In Windows XP, you will need to use the Get-EventLog cmdlet. To maximize performance of the query use the source, InstanceID, After, Before, and EntryType parameters to filter information before returning it to the Windows PowerShell console.

Luckily, you can use an XML filter by supplying XML to the FilterXML parameter of the Get-WinEvent cmdlet. Windows Vista and Windows Server 2008 accept the an XML filter, as do Windows 7 and Windows Server 2008 R2. Because most IT pros do not relish the idea of hand crafting XML files, you can copy the XML code from the XML tab of the Filter Current Log tab from the Event Viewer. To produce the XML, right-click the appropriate event log in Event Viewer, and select the Filter Current Log task. On the Filter pane, choose the applicable parameters including the Event source, time constraint, and Event level. The filter pane is shown in the following image.

Image of filter pane

When the filter is created, the XML tab of the Filter Current Log pane shows the XML that is used to create the current filter. By highlighting the XML, and pressing Ctrl+C to copy it to the clipboard, the XML portion of the FilterXML parameter is generated. The XML tab is shown in the following graphic.

Image of XML tab

I like to place the XML into a non-expanding here-string. As seen here, this command will run against a remote computer.

$query = @'

<QueryList>

<Query Id="0" Path="Application">

<Select Path="Application">*[System[Provider[@Name='Microsoft-Windows-WMI'] and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]]</Select>

</Query>

</QueryList>

'@

Get-WinEvent -FilterXml $query -ComputerName vista

The command and the associated output appear in the following graphic.

Image of command output

The Get-WinEvent cmdlet does not accept an array of computer names for the computername parameter, but it is easy to use the Foreach statement to work through an array of computer names. This is illustrated in the DemoXMLFilterQueryArrayComputers.ps1 script shown here.

DemoXMLFilterQueryArrayComputers.ps1

$query = @'

<QueryList>

<Query Id="0" Path="Application">

<Select Path="Application">*[System[Provider[@Name='Microsoft-Windows-WMI'] and TimeCreated[timediff(@SystemTime) &lt;= 604800000]]]</Select>

</Query>

</QueryList>

'@

$aryComputers = "dc1","hyperv-box", "Vista"

foreach($computer in $aryComputers)

{ "Computer $computer`r`n"

Get-WinEvent -FilterXml $query -ComputerName $computer

}

When the script runs, the output that is shown in the following graphic appears in the Windows PowerShell ISE output pane.

Image of command output

JJ, that is all there is to using the Get-Winevent cmdlet on Windows Vista and Windows Server 2008. In addition, I hope I have explained why the cmdlet does not work on Windows XP. I hope you will check back tomorrow for more Windows PowerShell tips and tricks.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy