Thursday, February 22, 2007

Remote WMI

Problem: I want to create an application (for God knows what reason) that shows the Event Log-entries for today. How can I do that ?

There are 2 ways the read the event log: one in very few lines and easy code, but not so quick, another one that’s a bit more complicated, but quick.

The easy way:

Dim objLogs() As EventLog
Dim objEntry As EventLogEntry
Dim objLog As EventLog

'this uses local machine
'you can pass machine name to constructor
'to use a different machine
objLogs = EventLog.GetEventLogs()

For Each objLog In objLogs
Debug.WriteLine(objLog.LogDisplayName & " event log")
For Each objEntry In objLog.Entries
With objEntry
Debug.WriteLine("Source: " & .Source & " Time: " & .TimeGenerated.ToString & " Message: " & .Message)
End With
Next
Next



Now, while this is a perfectly good way to read the event log, you’ll notice that it is slooow. It goes through the ENTIRE eventlog, while in this case it only needs to go through the messages of this day.

The second method solves this problem. You can query the eventlog on a very sql-way. Take a look at this code sample .


Imports System
Imports System.Management
Imports System.Diagnostics

Public Class testClass
Public Sub testWQL()
Dim options As New ConnectionOptions
options.Username = "aUsername"
options.Password = "aPassword"

Dim strQuery As String = ""
strQuery = "SELECT TimeGenerated, Message, SourceName, User FROM Win32_NTLogEvent"
strQuery &= " WHERE "
strQuery &= " TimeGenerated='" & ManagementDateTimeConverter.ToDmtfDateTime(Now()) & "'"

Dim scope As New ManagementScope("\\myServer\root\cimv2", options)
Dim searcher As New ManagementObjectSearcher(scope, _
New SelectQuery(strQuery))

Dim result As ManagementObjectCollection = searcher.Get

Dim item As ManagementObject

For Each item In result
Try
Debug.WriteLine(item("message").ToString & " " & item("TimeGenerated").ToString)
Catch ex As Exception
End Try
Next
End Sub
End Class

Some things might need some explaining:

- first of all, you need to define a user/pass combination that you want to use to connect to the server (or any other pc).
- Then, you have to design your query. For more details on the types of query, take a look at these pages :

http://www.databasejournal.com/features/mssql/article.php/3550481

http://www.databasejournal.com/features/mssql/article.php/3552621

- After that, connect to your server, in this syntax. The root\cimV2 is a global collection WMI objects that Microsoft provides. More details are found on MSDN. But I guess that 80% of what you want to monitor/use, is in this collection.
- Execute the query and traverse the results.


My preferred way is the second, because of the speed and efficiency that it gives.

Hope this helps ! ;-)


Gr, K

No comments: