Solved

Script to monitor CPU usage of 50+ servers

Posted on 2011-09-29
10
1,991 Views
Last Modified: 2012-08-14
Hi All,

I am looking for a script that would monitor CPU usage, RAM usage and Disk space usage of approx 50+ servers.

I should be able to mention those servers in a seperate txt file and this script should pull the server name from this txt file.

should show the output in a HTML page something like...

                          CPU                 RAM               F Drive (Free space)
Computer 1         5%                    20%                80%
Computer 2         6%                    30%                60%
Computer 3         8%                    80%                50%
Computer 4         10%                  95%                0%

This values should refresh automatically in some interval and also, it should have some threshold, if breached it should show them in RED color. example, if CPU is more than 70% then it should show in red... same for others
0
Comment
Question by:ghelaniabhishek
  • 6
  • 4
10 Comments
 

Author Comment

by:ghelaniabhishek
ID: 36853121
can somebody please help??
0
 
LVL 14

Expert Comment

by:rejoinder
ID: 36893960
Here is a way you can pull this off using vbscript.  You will need the attached XML file plus script code.  In the XML file is where you can place your settings such as the polling interval, threshold numbers and server names.  As an added bonus I allow for you to group the servers for a nicer output.  You can group them anyway you want I suppose but in this example I grouped them by similar function.  Open the XML and you will see.
Polling CPU time for 50 servers is going to take a long, long time.  Believe me, this will be your biggest problem with using vbscript.  Since the script cannot thread like a normal program it hits each server one at a time.  The output does not display in real time because IE will not show the finished table until it gets the final </table> command.  The screen will remain white/blank for the duration it takes to reach all the servers.  The end result is what you asked for, just wait for it that's all.
on error resume next
Dim intInterval
Dim xmlDoc
Dim strQuery
Dim colIntervals, objInterval
Dim colGroups, objGroup
Dim colThresholds, colThreshold
Dim intCPU
Dim intRAM
Dim intHDD
Dim objIE
Dim txtTable
Dim objDocument

StartIE()
'Read XML file
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.Load("servers.xml")
if xmlDoc.parseError.errorcode <> 0 then
	wscript.echo "Error opening file"
else
	Do While 1 <> 2
		objDocument.Writeln "<title>Server NOC</title>"
		objDocument.Writeln "<table width=100% border=""1"">"
		objDocument.Writeln "<tr bgcolor=""#7BA7E1""><th align=""left"">Server</th><th align=""left"">CPU</th><th align=""left"">RAM</th><th align=""left"">HDD</th></tr>"
		'Read XML file for changes since last poll
		Set xmlDoc = CreateObject("Microsoft.XMLDOM")
		xmlDoc.async = false
		xmlDoc.Load("servers.xml")
		
		'Get % values for INTERVAL, CPU, RAM and HDD
		intInterval = 300 'set a default value just in case
		intCPU = .9 'default value, red flag if over - ie CPU% > 90%
		intRAM = .8 'default value, red flag if over - ie RAM in use > 80%
		intHDD = .1 'default value, red flag if under - ie HDD free space < 10%
		
		strQuery = "/servers/ (interval | cpu | ram | hdd)"
		Set colThresholds = xmlDoc.selectNodes(strQuery)
		For Each objThreshold in colThresholds
			select case objThreshold.nodeName
				case "interval"
					intInterval = objThreshold.text
				case "cpu"
					intCPU = objThreshold.text
				case "ram"
					intRAM = objThreshold.text
				case "hdd"
					intHDD = objThreshold.text
			end select
		Next
		
		'Get group and server names from XML file
		strQuery = "/servers/group/ (name | server)"
		Set colGroups = xmlDoc.selectNodes(strQuery)
		For Each objGroup in colGroups
			'objGroup.nodeName = Either "name" or "server"
			'objGroup.text = Will either be the group name or the server name
			select case objGroup.nodeName
				Case "name"
					objDocument.Writeln "<tr bgcolor=""#CEDEF4""><td colspan=""4"">" & objGroup.text & "</td></tr>"
				Case "server"
					'wscript.echo objGroup.text
					objDocument.Writeln "<tr><td>" & objGroup.text & "</td>"
					set objSvc = GetObject("winmgmts:{impersonationLevel=impersonate}//" & objGroup.text & "/root/cimv2")
					if CINT(err.number) = 0 then
						'Check CPU usage
						strColour = ""
						strValue = ""
						objDocument.Writeln "<td>"
						set objRet = objSvc.InstancesOf("Win32_Processor")
						for each item in objRet
							strColour = "green"
							if item.LoadPercentage > intCPU then
								strColour = "red"
							end if
							strValue = item.LoadPercentage & "%"
							objDocument.Writeln "<font color=""" & strColour & """>" & strValue & "</font>&nbsp;"
						next
						objDocument.Writeln "</td>"
						
						strColour = ""
						strValue = ""
						set objRet = objSvc.InstancesOf("win32_OperatingSystem")
						for each item in objRet
							'Check RAM if over 80% in use red flag
							if ((item.TotalVisibleMemorySize-item.FreePhysicalMemory)/item.TotalVisibleMemorySize)*100 > intRAM*100 then
								strColour = "red"
							else
								strColour = "green"
							end if
							strValue = FormatNumber(((item.TotalVisibleMemorySize-item.FreePhysicalMemory)/item.TotalVisibleMemorySize)*100,0)& "%"
							objDocument.Writeln "<td><font color=""" & strColour & """>" & strValue & "</font></td>"
						next
						
						'Check hard drive space if free space is less than 10% red flag
						strColour = ""
						strValue = ""
						objDocument.Writeln "<td>"
						set objRet = objSvc.InstancesOf("win32_LogicalDisk")
						for each item in objRet
							if item.DriveType = 3 then
								'Default is drive has enough space and is green
								strColour = "Green"
								if (item.FreeSpace/item.size)*100 <= intHDD*100 then
									'There is less than a certain % of drive space left
									strColour = "Red"
								end if
								strValue = item.caption & " " & FormatNumber((item.FreeSpace/item.size)*100,0) & "%"
								objDocument.Writeln "<font color=""" & strColour & """>" & strValue & "</font>&nbsp;"
							end if
						next
						objDocument.Writeln "</td></tr>"
					else
						objDocument.Writeln "<td><font color=""red"">Server could not be reached</font></td></tr>"
					end if
					err.clear
			end select
		Next
		objDocument.Writeln "</table>"
		wscript.sleep intInterval*1000
		objDocument.body.innerHTML = ""
	loop
end if

Sub StartIE()
	Dim objWshShell
	Set objIE = CreateObject("InternetExplorer.Application")
	objIE.menubar = false
	objIE.toolbar = false
	objIE.statusbar = false
	objIE.addressbar = false
	objIE.resizable = true
	objIE.navigate ("about:blank")
	While (objIE.busy)
	wend
	set objDocument = objIE.document 
	objDocument.Open
	objIE.visible = True
End Sub

Open in new window

servers.xml
0
 

Author Comment

by:ghelaniabhishek
ID: 36907901
Thank you for the wonderful script. I tested it with 10 servers. And you were right, it took almost 55 Seconds to load it.

Do you recommend anything else that would give the output much quicker if not vbscript?
0
 

Author Comment

by:ghelaniabhishek
ID: 36907915
Also I played around a bit with the threshold limit. For HDD I set the limit to .2, ie if above 80% then it should be marked in red.
but in the output what I observed is that all the drives are listed in one colument,
example: C: 17%  D: 86%  F: 61%  
So, I expected that it would show D: 86% in red, but instead it showed C:17% in red and D and F in green
0
 
LVL 14

Accepted Solution

by:
rejoinder earned 350 total points
ID: 36910852
There could very well be a better option.  Open "Performance Monitor", start, run - perfmon and click ok.  When the window opens, go to Monitoring Tools, Performance Monitor.  Click the report style button dropdown and pick "Report".  Right click in the grey area and choose some options like Logical Disk - Free Space - All instances.  Add a few more to cover the memory etc.  Now, right click the grey area and pick "Save Settings As..."  For now save the htm file to your desktop.  Open the newly saved file on using Internet Explorer.  There will be a warning about there being active content - approve this and you will see a static report that was taken at the time of the save.  There will be a toolbar near the top that looks very much like the toolbad that was in perfmon.  Click the Green triable "Unfreeze display" button from that toolbar.  You will be asked if you want to erase the data in the graph, click OK to continue.  The report will now show you live up to date details as to what's going on.  The htm file can be shared with others so that if you have a group that needs to monitor these settings they can just open the file too.  The really crazy thing is that through the web page you can add or remove items to track and you can pick the style of report.  It doesn't have the threshold color component but the speed in unmatched.  50 servers will likely go right off the screen but as an alternative it does show live data.

I will check out the % thing shortly.
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 14

Expert Comment

by:rejoinder
ID: 36911143
About the HDD free space thing.  The calculation is getting the amout of free space remaining.  For example, C drive is 100MB and you are using 88MB, you have 12% free.  The HDD threshold being set to 10% sees this as OK and paints it green.  Now lets say you made the threshold .2 or 20%.  This would then get flagged in red showing 12% free.
So the number you are seeing is the amount of free space left on the drive; you are red flagging those drives that fall below a certain point of free space.

I did make a minor change to the code so there is only once place to enter the XML filename rather than two places as was the case above.
on error resume next
Dim intInterval
Dim xmlDoc
Dim strQuery
Dim colIntervals, objInterval
Dim colGroups, objGroup
Dim colThresholds, colThreshold
Dim intCPU
Dim intRAM
Dim intHDD
Dim objIE
Dim txtTable
Dim objDocument
Dim xmlFile

xmlFile = "servers.xml"

StartIE()
'Read XML file
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.Load(xmlFile)
if xmlDoc.parseError.errorcode <> 0 then
	wscript.echo "Error opening file"
else
	Do While 1 <> 2
		objDocument.Writeln "<title>Server NOC</title>"
		objDocument.Writeln "<table width=100% border=""1"">"
		objDocument.Writeln "<tr bgcolor=""#7BA7E1""><th align=""left"">Server</th><th align=""left"">CPU</th><th align=""left"">RAM</th><th align=""left"">HDD</th></tr>"
		'Read XML file for changes since last poll
		Set xmlDoc = CreateObject("Microsoft.XMLDOM")
		xmlDoc.async = false
		xmlDoc.Load(xmlFile)
		
		'Get % values for INTERVAL, CPU, RAM and HDD
		intInterval = 300 'set a default value just in case
		intCPU = .9 'default value, red flag if over - ie CPU% > 90%
		intRAM = .8 'default value, red flag if over - ie RAM in use > 80%
		intHDD = .1 'default value, red flag if under - ie HDD free space < 10%
		
		strQuery = "/servers/ (interval | cpu | ram | hdd)"
		Set colThresholds = xmlDoc.selectNodes(strQuery)
		For Each objThreshold in colThresholds
			select case objThreshold.nodeName
				case "interval"
					intInterval = objThreshold.text
				case "cpu"
					intCPU = objThreshold.text
				case "ram"
					intRAM = objThreshold.text
				case "hdd"
					intHDD = objThreshold.text
			end select
		Next
		
		'Get group and server names from XML file
		strQuery = "/servers/group/ (name | server)"
		Set colGroups = xmlDoc.selectNodes(strQuery)
		For Each objGroup in colGroups
			'objGroup.nodeName = Either "name" or "server"
			'objGroup.text = Will either be the group name or the server name
			select case objGroup.nodeName
				Case "name"
					objDocument.Writeln "<tr bgcolor=""#CEDEF4""><td colspan=""4"">" & objGroup.text & "</td></tr>"
				Case "server"
					'wscript.echo objGroup.text
					objDocument.Writeln "<tr><td>" & objGroup.text & "</td>"
					set objSvc = GetObject("winmgmts:{impersonationLevel=impersonate}//" & objGroup.text & "/root/cimv2")
					if CINT(err.number) = 0 then
						'Check CPU usage
						strColour = ""
						strValue = ""
						objDocument.Writeln "<td>"
						set objRet = objSvc.InstancesOf("Win32_Processor")
						for each item in objRet
							strColour = "green"
							if item.LoadPercentage > intCPU then
								strColour = "red"
							end if
							strValue = item.LoadPercentage & "%"
							objDocument.Writeln "<font color=""" & strColour & """>" & strValue & "</font>&nbsp;"
						next
						objDocument.Writeln "</td>"
						
						strColour = ""
						strValue = ""
						set objRet = objSvc.InstancesOf("win32_OperatingSystem")
						for each item in objRet
							'Check RAM if over 80% in use red flag
							if ((item.TotalVisibleMemorySize-item.FreePhysicalMemory)/item.TotalVisibleMemorySize)*100 > intRAM*100 then
								strColour = "red"
							else
								strColour = "green"
							end if
							strValue = FormatNumber(((item.TotalVisibleMemorySize-item.FreePhysicalMemory)/item.TotalVisibleMemorySize)*100,0)& "%"
							objDocument.Writeln "<td><font color=""" & strColour & """>" & strValue & "</font></td>"
						next
						
						'Check hard drive space if free space is less than 10% red flag
						strColour = ""
						strValue = ""
						objDocument.Writeln "<td>"
						set objRet = objSvc.InstancesOf("win32_LogicalDisk")
						for each item in objRet
							if item.DriveType = 3 then
								'Default is drive has enough space and is green
								strColour = "Green"
								if (item.FreeSpace/item.size)*100 <= intHDD*100 then
									'There is less than a certain % of drive space left
									strColour = "Red"
								end if
								strValue = item.caption & " " & FormatNumber((item.FreeSpace/item.size)*100,0) & "%"
								objDocument.Writeln "<font color=""" & strColour & """>" & strValue & "</font>&nbsp;"
							end if
						next
						objDocument.Writeln "</td></tr>"
					else
						objDocument.Writeln "<td><font color=""red"">Server could not be reached</font></td></tr>"
					end if
					err.clear
			end select
		Next
		objDocument.Writeln "</table>"
		wscript.sleep intInterval*1000
		objDocument.body.innerHTML = ""
	loop
end if

Sub StartIE()
	Dim objWshShell
	Set objIE = CreateObject("InternetExplorer.Application")
	objIE.menubar = false
	objIE.toolbar = false
	objIE.statusbar = false
	objIE.addressbar = false
	objIE.resizable = true
	objIE.navigate ("about:blank")
	While (objIE.busy)
	wend
	set objDocument = objIE.document 
	objDocument.Open
	objIE.visible = True
End Sub

Open in new window

0
 

Author Comment

by:ghelaniabhishek
ID: 36914676
I liked your performance monitor option.
But is there a way were I can add counters for 50+ servers at once instead of manually adding counters for each server one by one. Its too time consuming
0
 
LVL 14

Assisted Solution

by:rejoinder
rejoinder earned 350 total points
ID: 36918697
I improved the polling time with this script by using a different monitoring option for getting the CPU in use %.  Now at the end of the table is the time the last poll was done for reference.  The table stays persistent while the poll takes place and will blink when the page refreshes with new data.  

I may have not mentioned this but you can change the values of the XML file while the script is running so if you want to add a server, move names around, edit the threshold numbers you can do this without having to stop and start the script.
on error resume next
Dim intInterval
Dim xmlDoc
Dim strQuery
Dim colIntervals, objInterval
Dim colGroups, objGroup
Dim colThresholds, colThreshold
Dim intCPU
Dim intRAM
Dim intHDD
Dim objIE
Dim txtTable
Dim objDocument
Dim xmlFile
Dim strPageBody

xmlFile = "servers-copy.xml"

StartIE()
'Read XML file
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = false
xmlDoc.Load(xmlFile)
if xmlDoc.parseError.errorcode <> 0 then
	wscript.echo "Error opening file"
else
	Do While 1 <> 2
		strPageBody = "<title>Server NOC</title>"
		strPageBody = strPageBody & "<table width=100% border=""1"">"
		strPageBody = strPageBody & "<tr bgcolor=""#7BA7E1""><th align=""left"">Server</th><th align=""left"">CPU</th><th align=""left"">RAM</th><th align=""left"">HDD</th></tr>"
		'Read XML file for changes since last poll
		Set xmlDoc = CreateObject("Microsoft.XMLDOM")
		xmlDoc.async = false
		xmlDoc.Load(xmlFile)
		
		'Get % values for INTERVAL, CPU, RAM and HDD
		intInterval = 300 'set a default value just in case
		intCPU = .9 'default value, red flag if over - ie CPU% > 90%
		intRAM = .8 'default value, red flag if over - ie RAM in use > 80%
		intHDD = .1 'default value, red flag if under - ie HDD free space < 10%
		
		strQuery = "/servers/ (interval | cpu | ram | hdd)"
		Set colThresholds = xmlDoc.selectNodes(strQuery)
		For Each objThreshold in colThresholds
			select case objThreshold.nodeName
				case "interval"
					intInterval = objThreshold.text
				case "cpu"
					intCPU = objThreshold.text
				case "ram"
					intRAM = objThreshold.text
				case "hdd"
					intHDD = objThreshold.text
			end select
		Next
		
		'Get group and server names from XML file
		strQuery = "/servers/group/ (name | server)"
		Set colGroups = xmlDoc.selectNodes(strQuery)
		For Each objGroup in colGroups
			'objGroup.nodeName = Either "name" or "server"
			'objGroup.text = Will either be the group name or the server name
			select case objGroup.nodeName
				Case "name"
					strPageBody = strPageBody & "<tr bgcolor=""#CEDEF4""><td colspan=""4"">" & objGroup.text & "</td></tr>"
				Case "server"
					'wscript.echo objGroup.text
					strPageBody = strPageBody & "<tr><td>" & objGroup.text & "</td>"
					set objSvc = GetObject("winmgmts:{impersonationLevel=impersonate}//" & objGroup.text & "/root/cimv2")
					if CINT(err.number) = 0 then
						'Check CPU usage
						strColour = ""
						strValue = ""
						strPageBody = strPageBody & "<td>"
						set objRet = objSvc.ExecQuery("select * from Win32_PerfFormattedData_PerfOS_Processor WHERE NAME=""_Total""")
						for each item in objRet
							strColour = "green"
							if CINT(item.PercentProcessorTime) > CINT(intCPU*100) then
								strColour = "red"
							end if
							strValue = item.PercentProcessorTime & "%"
							strPageBody = strPageBody & "<font color=""" & strColour & """>" & strValue & "</font>&nbsp;"
						next
						strPageBody = strPageBody & "</td>"
						
						strColour = ""
						strValue = ""
						set objRet = objSvc.InstancesOf("win32_OperatingSystem")
						for each item in objRet
							'Check RAM if over 80% in use red flag
							if ((item.TotalVisibleMemorySize-item.FreePhysicalMemory)/item.TotalVisibleMemorySize)*100 > intRAM*100 then
								strColour = "red"
							else
								strColour = "green"
							end if
							strValue = FormatNumber(((item.TotalVisibleMemorySize-item.FreePhysicalMemory)/item.TotalVisibleMemorySize)*100,0)& "%"
							strPageBody = strPageBody & "<td><font color=""" & strColour & """>" & strValue & "</font></td>"
						next
						
						'Check hard drive space if free space is less than 10% red flag
						strColour = ""
						strValue = ""
						strPageBody = strPageBody & "<td>"
						set objRet = objSvc.InstancesOf("win32_LogicalDisk")
						for each item in objRet
							if item.DriveType = 3 then
								'Default is drive has enough space and is green
								strColour = "Green"
								if (item.FreeSpace/item.size)*100 <= intHDD*100 then
									'There is less than a certain % of drive space left
									strColour = "Red"
								end if
								strValue = item.caption & " " & FormatNumber((item.FreeSpace/item.size)*100,0) & "%"
								strPageBody = strPageBody & "<font color=""" & strColour & """>" & strValue & "</font>&nbsp;"
							end if
						next
						strPageBody = strPageBody & "</td></tr>"
					else
						strPageBody = strPageBody & "<td colspan=""3""><font color=""red"">Server could not be reached</font></td></tr>"
					end if
					err.clear
			end select
		Next
		strPageBody = strPageBody & "</table>"
		strPageBody = strPageBody & "Last poll: " & now()
		objDocument.body.innerHTML = ""
		objDocument.Writeln strPageBody
		wscript.sleep intInterval*1000
	loop
end if

Sub StartIE()
	Dim objWshShell
	Set objIE = CreateObject("InternetExplorer.Application")
	objIE.menubar = false
	objIE.toolbar = false
	objIE.statusbar = false
	objIE.addressbar = false
	objIE.resizable = true
	objIE.navigate ("about:blank")
	While (objIE.busy)
	wend
	set objDocument = objIE.document 
	objDocument.Open
	objIE.visible = True
End Sub

Open in new window

0
 

Author Comment

by:ghelaniabhishek
ID: 36921815
it gives "Error opening file" message
0
 

Author Comment

by:ghelaniabhishek
ID: 36921912
I fixed that issue. the file name was different. Checking the script now
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

This is pretty cool.  The purpose of this VB Script is to help you document where JAR (Java ARchive) files and specifically java class files are located so that you can address issues seen with a client or that you can speak intelligently with a dev…
This article is the result of a quest to better understand Task Scheduler 2.0 and all the newer objects available in vbscript in this version over  the limited options we had scripting in Task Scheduler 1.0.  As I started my journey of knowledge I f…
This video discusses moving either the default database or any database to a new volume.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now