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.
Hello Jeffrey, I caught your webcast this month and it was quite good.
I must have gotten the sample code from the same place as the original poster because long query times let me to search for an answer, and that brought me to this post.
One thing that is still not working for me is how to display the final results in some format that is somewhat more readible that the default format for time. I know this is a simple format command, but I’ve tried a few things with no luck, can you perhaps comment on that?
You need to use an expression that calls the ConvertToDateTime script method of the Event log object:
$B | Select @{name="Generated";Expression={$_.ConvertToDateTime($_.TimeGenerated)}},@
{name="Written";Expression={$_.ConvertToDateTime($_.TimeWritten)}},EventCode,Message |format-table
If you need anything else or have more questions, please followup in the PowerShell forum at Scripting Answers.com.
Jeff
PS For anyone copying and pasting, you’ll need to make sure any quotes are straight quotes and not curly quotes.
Hi,
I was browsing as to why it took long time in powershell to get remote event log info unlike vbscript. Came across this webpage and tried your code.
It was very fast.
I have set this up as scheduled task and the output gets written to a text file. But i am having problems in displaying the output
In the code i have:
#$out | Select-object EventCode, TimeWritten
$out | Select @{name=”Written”;Expression={$_.ConvertToDateTime($_.TimeWritten)}},EventCode |format-table
Write-Output “Results: $out”
Write-Output “———————————–”
I don’t get the contents of $out in my text file. I also tried – Write-Output “Event Code $out.EventCode”. But didn’t help.
What am i missing in the code.
Can you guide me in this.
Thanks,
Natalie.
I don’t see where you are creating a text file. If you can, please post your problem in the PowerShell forum at ScriptingAnswers.com. It will be easier for me and others to help you out.