In the first two segments of this series we explored ways of analyzing and archiving event logs with WSH. In this article, I’m going to demonstrate specific applications of this that can benefit network administrators who are responsible for maintaining large numbers of machines.
This scripts we’ll be creating in this article will take a two-fold approach. The first is designed to be run from a server to consolidate event logs from several machines. The second is designed as a network logon script that can be deployed on each machine in the network.
The two-fold approach has two major benefits. The first script can be managed from a single location. It doesn’t require installation on every machine, which means it can be run at will as needed.
The second script is designed to be run from each machine. This gives us the advantage of creating a real time monitor that can be used for instant notification when specific conditions occur.
You can use these methods independently of one another or in conjunction to obtain the desired level of efficiency that you are seeking. I’ll discuss this further as I show you specific case scenarios.
You’re going to need the script that we ended with in the last article. We’re going to further modify it for our needs. Both of the scripts that will be introduced in this article will grow off of the examples you’ve already seen.
I’m not going to be showing you how to sort and manage the data that we retrieve from the event logs. I may write an article later for that purpose, but for now, my goal is simply to show you how to prepare the data.
I’m going to be making two assumptions throughout this article. I believe they represent the most common opinions of network administrators as a whole. You can, however, modify any of these to fit your own specific needs.
The first assumption is that all event log entries should be archived. For the sake of size and time you may wish to limit this to only certain types of events, but I believe that most administrators will agree that historical data is best preserved in its entirety.
The second assumption is that you do not need to know about every single event that takes place in a system—especially when you are managing large numbers of systems. Whenever monitoring or creating notifications, I will be limiting the range of data that we are watching.
Again, any of these options can be modified to fit your own specific needs and style.
One third and final thing to note is that I will be archiving all data in one central database. Since each event is labeled by a machine name, sorting data for specific machines is not impossible. You could easily create multiple databases for individual machines or groups of machines if you preferred.
Let’s being by creating a script that will pull the event logs from machines across your network. I suggest creating a static list of machines to interrogate. While you could create a script that will seek other machines, the first is much more reliable and much easier to manage in the event that errors occur.
You can pull machine names from a database or flat file, but for the sake of brevity, I’m just going to create an array to hold them. Again, this can be changed based on your own needs and ease of use.
To make things easier as we progress, let’s take the time now to separate our script into sections. This way we can modify it more easily as we go.
The opening segment assigns some variables and connects to the WMI Service. I’ve also included an If statement that checks to see whether the database needs to be created first.
Sub BuildDatabase
Set objCatalog = CreateObject("ADOX.Catalog")
objCatalog.Create strConnection
Set objCatalog = Nothing
Set oConn = CreateObject("ADODB.Connection")
oConn.Open strConnection
oConn.Execute "CREATE TABLE EventTable(" _
& "Category INT, " _
& "ComputerName VARCHAR(50), " _
& "EventCode INT, " _
& "Message VARCHAR(100), " _
& "EventType VARCHAR(50), " _
& "RecordNumber INT, " _
& "SourceName VARCHAR(50), " _
& "TypeDesc VARCHAR(15), " _
& "UserName VARCHAR(50), " _
& "TimeGenerated VARCHAR(19), " _
& "TimeWritten VARCHAR(19)" _
& ")", , 129
End Sub
The next section is used to create a database. I’ve moved this into an appropriately named subroutine.
Sub GetEvents
Set colEvents = objWMIService.ExecQuery( _
"SELECT * FROM Win32_NTLogEvent")
Set objRs = CreateObject("ADODB.Recordset")
objRs.Open "SELECT * FROM EventTable;", oConn, 0, 3
In this section we query WMI for events and add them to our database. Again, I’ve moved this into a subroutine. I’ve also added a line to clear the event log on the machine after archiving it. This prevents archiving the same event each time the script is run.
Since WMI supports working with remote computers, we just need to change our script so that it polls each computer in our array in turn. To do this, we’ll need to recreate the WMI service object for each machine. We’ll begin by creating a For loop to move through the array.
This simply moves through each computer name in our array, connects to the WMI Service, and then calls the GetEvents subroutine to retrieve the events on that machine.
Let’s take a look at how to create a logon script that monitors the event logs. We’re going to add an extra feature to have the script send an email notification if it detects a warning or error event.
strComputer = "."
Set objWMIService = GetObject("winmgmts:{(Security)}" & strComputer _
& "rootcimv2")
Set colEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceCreationEvent WHERE " _
& "TargetInstance ISA 'Win32_NTLogEvent' " _
& "AND TargetInstance.Type = 'Warning' " _
& "OR TargetInstance.Type = 'Error'")
Do While True
Set objEvent = colEvents.NextEvent()
strUser = objEvent.User
If IsNull(strUser) Then strUser = "N/A"
strMessage = objEvent.Message
If Len(strMessage) > 100 Then
strMessage = Left(strMessage, 100)
End If
return = EmailNotify(objEvent.Category, _
objEvent.ComputerName, _
objEvent.EventCode, _
strMessage, _
objEvent.EventType, _
objEvent.RecordNumber, _
objEvent.SourceName, _
objEvent.Type, _
strUser, _
DateTime2String(objEvent.TimeGenerated), _
DateTime2String(objEvent.TimeWritten))
Loop
The base script looks like this. It connects to the WMI Service and issues an Event Notification Query. This script utilizes event scripting. That means our script will only be executed when a new event occurs that matches our parameters. This script will run indefinitely any time the computer is turned on.
If the event is a Warning or Error type event, the event’s details are passed to the EmailNotify function.
This function assembles the event details into an email message that is sent to an administrator using CDO. Be sure to change both the destination address and the SMTP server to match your configuration.
You’ll also need the Date2String function to create friendly date and time stamps.
There you have it. Two scripts that a network administrator can use to monitor or track the event logs for machines within their network. Making use of scripts like this will improve your efficiency and keep you in closer contact with the machines you service.
Good luck maintaining your machines. Until next time…keep coding!