Improved Remote WMI Event Log Queries

I responded to a comment about querying remote event logs using WMI.  The issue is performance, especially when filtering.  The commenter was using code like this:

$d=get-date
$BeginDate=[System.Management.ManagementDateTimeConverter]::ToDMTFDateTime($d.AddDays(-7))
$B = get-wmiobject –class win32_ntlogevent –computerName $FQDNservername -credential $Credentials | Where-object { $_.logfile -eq “system” -and ($_.eventcode –eq “20048” -and $_.TimeWritten -ge $BeginDate) } | select-object Logfile,EventCode,TimeGenerated,TimeWritten,Message

I tried it out while running a network trace and it took a long time to complete.  Lots of WMI information coming across the wire. Then I realized it is slow because the the Get-WMIObject cmdlet has to complete first, then it has to send the results to the Where-Object cmdlet.  The better approach is to use a WMI query so the results are filtered in place.  Here’s my revised code, that also includes a technique to indicate how long the process took:

$start=Get-Date
$d=Get-Date
$computer=”dc01”
$BeginDate=[System.Management.ManagementDateTimeConverter]::ToDMTFDateTime($d.AddDays(-7))
$B = get-wmiobject -query “Select Logfile,Eventcode,TimeGenerated,TimeWritten,Message from win32_ntlogevent where logfile=’System’ AND eventcode=’7036’ AND TimeWritten >=’$BeginDate’” -computername $computer
$end=Get-Date
$Runtime=$end-$start
$B | Select TimeGenerated,TimeWritten,EventCode,Message |format-table
write-host $b.count “records”
write-host “Runtime: ” $runtime.hours “hrs” $runtime.minutes “min” $runtime.seconds “sec” $runtime.milliseconds “ms”

Now the query completes in a fraction of the time.

del.icio.us tags: , , ,