Hey, Scripting Guy! Question

Hey, Scripting Guy! I’m trying to write a script that can go through a log file and determine the number of users who logged off on a particular day. Can you help me?
-- TM

SpacerHey, Scripting Guy! AnswerScript Center

Hey, TM. You know, when you work at Microsoft people think you probably come to work in your pajamas, ride a unicycle through the hallways, and do all those other weird and wacky things that people in the high-tech industry do. As it turns out, though, that’s not the case, not at all. (And thank goodness: it’s bad enough seeing people around here in their shorts, let alone in their pajamas.)

Instead, Microsoft is just like any other workplace. For example, often-times people around here leave you absolutely speechless with their … ideas …. This is a problem the Scripting Guys have been grappling with for over a year now. “Hey, guys,” we’ve been told over and over. “Remember how, under the old system, you were able to do 100 different things? Well now, under our new system, we’ve improved things to the point where you’ll only be able to do 12 of those things! Isn’t that great!?!”

We’ll have to get back to you on that.

Note. Of course, dealing with certain people here has caused the Scripting Guy who writes this column to completely revise his career goals. His goal now is to become the person who hands over the check to the winner of the Washington state lottery. With any luck at all, one of these Microsoft people will win the lottery, and when he goes to hand them the check the Scripting Guy who writes this column will say, “Remember how you won $10 million in the Washington state lottery? Well, just think: if you give me $9 million of those dollars, you’ll still be able to keep a whole million for yourself! Isn’t that great!?!”

And sure, it’s a bit of a long shot. But, then again, his so-called “real” retirement plan (e.g., 401K and stock options) isn’t doing much better.

Anyway, we mention all this simply because the Scripting Guys have a meeting later today that could go a long way to determining the future of the Script Center and of scripting documentation in general. Are we looking forward to this meeting? Let’s put it this way: when it comes to meetings, we’d prefer to see everyone come to work in their pajamas.

No, wait, we take that back. After all, there’s always a chance that some of these people don’t wear pajamas.

At any rate, the Scripting Guy is awfully busy today, and he’s in an even worse mood than usual. But does that mean he’s too busy and too grouchy to write a script that can tally logon/logoff data using information taken from a text file? Yes.

Oh, wait; we mean, no:

Const ForReading = 1

intLoggedOn = 0
intLoggedOff = 0

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSo.OpenTextFile("C:\Scripts\Test.txt", ForReading)

Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
    If InStr(strLine, "2008-04-04") Then
        If InStr(strLine, "logged on") Then
            intLoggedOn = intLoggedOn + 1
        ElseIf InStr(strLine, "logged off") Then
            intLoggedOff = intLoggedOff + 1
        End If
    End If
Loop

Wscript.Echo "Logons: " & intLoggedOn
Wscript.Echo "Logoffs: " & intLoggedOff

Note. True, a real Microsoft employee might tell you, “Remember that script that was supposed to tally logon/logoff data using information taken from a text file? Well, instead, we wrote you a script that doesn’t tally logon/logoff data using information taken from a text file. Isn’t that great!?!” Fortunately, though, the Scripting Guys are usually not considered real Microsoft employees.

Especially by other Microsoft employees.

Our script – which, to set your mind at ease, really does tally logon/logoff data using information taken from a text file – starts off by defining a constant named ForReading and setting the value to 1; we’ll use this constant when we open up and read the text file. Speaking of text files, the sample file TM sent us looks something like this:

29        00000001  2008-04-04 10:17:34  Server successfully initialized.
30        00000001  2008-04-04 10:17:42  Connection made from workstation atl-ws-001 (CID:14537, API:1.25).
Client: ServerAdministration; SDK 8.0.0.74; JVM 1.5.0_03-b07; Windows 2003
31        00000001  2008-04-04 10:17:42  User StarTeam Server Administrator logged on connection from workstation StarTeamApp01 (CID:14537).
32        00000001  2008-04-04 10:20:31  Connection made from workstation atl-ws-002 (CID:4272, API:1.24).
Client: StarTeam 7.0.131; Windows XP
33        00000001  2008-04-04 10:20:31  User Ken Myer logged on connection from workstation atl-ws-002 (CID:4272).
34        00000001  2008-04-04 10:21:20  User Ken Myer logged off connection from workstation atl-ws-002 (CID:4272).
35        00000001  2008-04-04 11:00:56  Connection made from workstation atl-ws-003 (CID:7800, API:1.24).
Client: StarTeam 7.0.131; Windows XP
36        00000001  2008-04-04 11:00:56  User Pilar Ackerman logged on connection from workstation atl-ws-003 (CID:7800).

If you look through this sample test, you’ll see that we have two logons and one logoff for April 4, 2008:

33        00000001  2008-04-04 10:20:31  User Ken Myer logged on connection from workstation atl-ws-002 (CID:4272).
34        00000001  2008-04-04 10:21:20  User Ken Myer logged off connection from workstation atl-ws-002 (CID:4272).
36        00000001  2008-04-04 11:00:56  User Pilar Ackerman logged on connection from workstation atl-ws-003 (CID:7800).

Our job is simple: we need to programmatically count up the total number of logons and logoffs for a given date.

So how are we going to do that? Well, after we define our constant we’re going to assign the value 0 to a pair of variables, intLoggedOn and intLoggedOff:

intLoggedOn = 0
intLoggedOff = 0

Once that’s done we create an instance of the Scripting.FileSystemObject, then use this line of code to open the text file C:\Scripts\Test.txt for reading:

Set objFile = objFSo.OpenTextFile("C:\Scripts\Test.txt", ForReading)

Our next step is to set up a Do Until loop designed to run until we’ve reached the end of the file; that is, until the file’s AtEndOfStream property is True. Inside that loop, the first thing we do is use the ReadLine method to read the initial line in the file and store it in a variable named strLine:

strLine = objFile.ReadLine

At this point we need to do two things. First, we need determine whether or not the action recorded on this line of code took place on April 4, 2008. We can do that by using VBScript’s InStr function to search for the date-time value 2008-04-04:

If InStr(strLine, "2008-04-04") Then

If InStr returns a 0 that means that the date-time value 2008-04-04 couldn’t be found; therefore we simply go back to the top of the loop and repeat the process with the next line in the text file. If the date-time value was found we then need to check to see if either a logon or a logoff took place. That’s what this block of code is for:

If InStr(strLine, "logged on") Then
    intLoggedOn = intLoggedOn + 1
ElseIf InStr(strLine, "logged off") Then
    intLoggedOff = intLoggedOff + 1
End If

As you can see, in line 1 we’re again using InStr to search the line of text for a particular phrase; in this case, that’s the phrase logged on. What if we find the search phrase? Well, that means we’re dealing with a logon; in turn, we increment the value of the variable intLoggedOn by 1:

intLoggedOn = intLoggedOn + 1

What if we don’t find the search phrase? Well, in that case we try again, this time looking for the string logged off:

ElseIf InStr(strLine, "logged off") Then

If found, we increment the value of the variable intLoggedOff by 1. Either way, it’s then back to the top of the loop, where we try, try again with the next line in the text file.

After we’ve read each line in the text file we echo back the values of intLoggedOn and intLoggedOff. That’s going to give us output similar to this:

Logons: 2
Logoffs: 1

And there you have it.

That’s all we have time for today; we need to straighten our pajamas, hop on our unicycles, and head off to a meeting. To be honest, we don’t expect anything bad to come out of this meeting, and we expect that life will go on the same as ever. But you never know; after all, this is Microsoft: “Remember that Script Center thing where you can find all sorts of information about system administration scripting? Well, now we have a Script Center where you can’t find any information about system administration scripting! Isn’t that great!?!”

We’ll keep you posted.