tim laqua dot com Thoughts and Code from Tim Laqua

26Nov/0811

Monitoring, Starting, and Stopping Perfmon Performance Counter Logs using VBScript

Performance counters are great - unless they're not running. 😉 So this script illustrates one approach to monitoring the Performance Counter Logs on a given machine, starting them when they stop (for whatever reason) and letting someone know about it.

UPDATE For 2008+ Data Collector Sets: Monitoring and Starting Data Collector Sets with Powershell

I check the registry to determine the current state of a counter log, and use the logman command line utility to start the log when needed. Logman can also tell you the state of the counters, but it's crazy slow. I've been unable to locate a way to do all of this using WMI and the interweb has been less helpful than usual on this issue. So here's my solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
Const HKLM = &H80000002
Set arrRunningCounterLogs = CreateObject( "System.Collections.ArrayList" )
Set arrStoppedCounterLogs = CreateObject( "System.Collections.ArrayList" )
Set dictCounterLogs = CreateObject( "Scripting.Dictionary" )
 
' ================= START Configuration Settings
 
strComputer = "."
arrCounterLogExclusionList = Array("System Overview","PerfWiz")
strExchangeServer = "smtpServer"
strScriptEmailIdentity = """PerfMonMon.vbs"" <tim@timlaqua.com>"
strLogStartEmailRecipients = "tim@timlaqua.com"
 
' ================= END Configuration Settings
 
strBasePath ="SYSTEM\CurrentControlSet\Services\SysmonLog\Log Queries"
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
    strComputer & "\root\default:StdRegProv")
 
oReg.EnumKey HKLM, strBasePath, arrSubKeys
For Each subkey In arrSubKeys
	strLogKeyPath = strBasePath & "\" & subkey
	oReg.GetStringValue HKLM, strLogKeyPath, "Collection Name", strCollectionName
 
	If Not InArray(strCollectionName, arrCounterLogExclusionList) Then
		dictCounterLogs.Add strCollectionName, strLogKeyPath
		If IsLogRunning(strCollectionName) Then
			arrRunningCounterLogs.Add(strCollectionName)
		Else
			arrStoppedCounterLogs.Add(strCollectionName)
		End If
	End If
Next
 
If arrStoppedCounterLogs.Count > 0 Then
	Set oShell = WScript.CreateObject("WScript.Shell")
	boolErrors = False
 
	For Each strCounterLog in arrStoppedCounterLogs
		oShell.Run "logman start """ & strCounterLog & """ -s " & strComputer, 0, True
 
		If IsLogRunning(strCounterLog) Then
			strMessage = strMessage & "  " & strCounterLog & _
						 " was stopped - started log at " & Now & vbCrLf
		Else
			strMessage = strMessage & _
						 "  ERROR: Unable to start " & strCounterLog & vbCrLf
			boolErrors = True
		End If
	Next
 
	If boolErrors Then
		strSubject = "Stopped Counter Log Alert - Some counters could not be started"
	Else
		strSubject = "Stopped Counter Logs Detected - Counter Logs Started"
	End If
 
	SendEmail strExchangeServer, strScriptEmailIdentity, strLogStartEmailRecipients, strSubject, strMessage
End If
 
Function InArray(needle, haystack) 'As Boolean
	InArray = False
	For Each item In haystack
		If needle = item Then : InArray = True : Exit Function : End If
	Next
End Function
 
Function IsLogRunning(logName) 'As Boolean
	IsLogRunning = False
	oReg.GetDWORDValue HKLM, dictCounterLogs(logName), "Current State", dwCurrentState
	If dwCurrentState Then
		IsLogRunning = True
	End If
End Function
 
Sub SendEmail(server, sender, recipient, subject, textbody)
	Set objMessage = CreateObject("CDO.Message") 
	objMessage.Subject = subject 
	objMessage.From = sender 
	objMessage.To = recipient 
	objMessage.TextBody = textbody
 
	objMessage.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 
	objMessage.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/smtpserver") = server
	objMessage.Configuration.Fields.Item _
		("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 
	objMessage.Configuration.Fields.Update
 
	objMessage.Send 
End Sub
Comments (11) Trackbacks (1)
  1. Hi Tim,
    We do have almost 40 citrix server, i need to start conter logs when system start up, automatic. Though i created a batch file and start counter logs on start up using logman command but almost half of the server it is unable to do same . Pls write a VBscript for me so that i can implement on my environment .

    Thanks a lot in advance .

    Iman
    Server Eng- Ocwen

  2. The script here will work just fine for that. Run it as a Scheduled Task that fires every 5 minutes – when the server comes up, the task will fire – it will attempt to start the logs that still aren’t running next time it fires (5 minutes later).

    Comment out line 58 (the SendEmail line) if you don’t care to receive emails when it starts logs – but for the first few times, it’s good to let it email you so you can understand what logs are starting the first time and which ones are still having difficulties starting.

  3. Thanks Tim,
    But i am really zero knowledge on script can you let me specify where i need to put server name or can get a CSV file where list of servers will be there ? And also let me know how to put this script in server.
    Like copy the contents and paste in text file ?

    Pls guide …

    Iman

  4. Yes, copy it, paste it in to a text file and save it as PerfMonMon.vbs

    Then, copy it to each server (do this with one server first, just to make sure you have it right). Once it’s on the server, create a new scheduled task (in Control Panel) and configure it to run ever 5 minutes (even if no users are logged on) and run the script (PerfMonMon.vbs).

    also, make sure to edit the line above where it says strExchangeServer = “yourmailgateway” if you want it to email you

  5. hi,
    thank you for your script.
    I’m automating the collect of perf data for servers in a domain, so this saves me a huge time.
    i’ll post the result to my blog
    regards,

  6. Hi Tim,
    a bit of a long time ago since you made that script.
    i tried running it on my desktop, but it gave me errors
    (line: 21, char 1, object not a collection, code: 800A01C3, source: microsoft VBScript runtime error)

    i am running an x64 bit version of windows 7.
    However, i get it to run on any x86 environment.

    Do you know which variable is not recognised in x64 environments? Any help is much appreciated…!!!

    Regards, Michael

  7. This is great and just what I am looking for however when I run it I get a
    line 1
    char 1
    error invalid character
    code 800a0408
    source microsoft vbscript compaltion error

    I do not know scripting all that well but sure would like to get this to work.

    Thanks,
    Gus

  8. This is great just what I was looking for however when I run the scriipt i get
    Line 1
    Char 1
    Error Invalid character

    I am not good a t scripting and would really like to use this script

    any thoughts,
    Thanks,
    Gus

  9. Try copying just the code again (not the line numbers) and make sure you save it using ANSI encoding when you save the file (I think nodepad is ANSI by default).

  10. Have you had the opportunity to do this with Windows Server 2008? I am able to accomplish similar with my own script for 2003, but i’d like to check my 2008 servers as well.

  11. Yeah, check the UPDATE note in the post above.


Leave a comment