Remotely Check for Memory Dumps - BSODCheck.vbs
I was working on a server the other night. I was working with a developer, trying to resolve an issue that had suddenly become business critical on a Friday night after everyone had gone home. As I was clicking away, I suddenly lost connectivity to the server. Since I was working remotely over a VPN and the internet, I thought I simply dropped the network connection.
I fired up IE and tried to go to our corporate intranet and it came right up. Well, this made me wonder why I suddenly lost connectivity to the server I was just working on. After a couple of minutes the server started responding again and when I finally got logged back into the machine it had rebooted for no apparent reason.
Since our group handed over the responsibility of monitoring CIM, I have been really insulated from monitoring server’s hardware health. So I started wondering how often these servers have been randomly be rebooting and if this has been a pattern. I thought to myself what, what would be the easiest way of checking to see if a server has crashed. I could check the event log and parse all the events to see if and events have been logged.
I thought an easier way might be just to check and see if the “memory.dmp” file was in the C:\WINNT directory. What would be really handy would be to scan a bunch of computers and if a new dump had been created, send an email to myself or just fire up a popup saying so.
So, here it is: a script that will scan a list of servers for the presence of “memory.dmp” and compare its file date. This script will use the logs of the last script run as input for its current scan. This script is really designed to be run periodically, once a day or every couple of hours. So setting it up as a scheduled task would be a great idea. The script looks for the input file to start with the name “BSODCheck-“.
The script also determines the computer name by searching for “=”. Computer names should be in the following format
Computer1=
Computer2=
Server1=
Workstation1=
If you don’t include an equals sign, the script will assume that the line you have added is a comment and it will be skipped.
I fired up IE and tried to go to our corporate intranet and it came right up. Well, this made me wonder why I suddenly lost connectivity to the server I was just working on. After a couple of minutes the server started responding again and when I finally got logged back into the machine it had rebooted for no apparent reason.
Since our group handed over the responsibility of monitoring CIM, I have been really insulated from monitoring server’s hardware health. So I started wondering how often these servers have been randomly be rebooting and if this has been a pattern. I thought to myself what, what would be the easiest way of checking to see if a server has crashed. I could check the event log and parse all the events to see if and events have been logged.
I thought an easier way might be just to check and see if the “memory.dmp” file was in the C:\WINNT directory. What would be really handy would be to scan a bunch of computers and if a new dump had been created, send an email to myself or just fire up a popup saying so.
So, here it is: a script that will scan a list of servers for the presence of “memory.dmp” and compare its file date. This script will use the logs of the last script run as input for its current scan. This script is really designed to be run periodically, once a day or every couple of hours. So setting it up as a scheduled task would be a great idea. The script looks for the input file to start with the name “BSODCheck-“.
The script also determines the computer name by searching for “=”. Computer names should be in the following format
Computer1=
Computer2=
Server1=
Workstation1=
If you don’t include an equals sign, the script will assume that the line you have added is a comment and it will be skipped.
| 'BSODCheck v1.01 - 10-11-06 ' 'This script will read a log file and determine if new memory dumps 'have been created by a list of servers. The script will look for 'the last log file created and then determine if any new dumps 'have occured since the last time the list has been scanned. ' 'This script detects input files based on their filenames. Correct 'filenames will start with "BSODCheck-" followed by the date and '".log". Your first input file needs only be named "BSODCheck-.log" ' 'The script parses out computer names based on the equals sign (=). 'Examples of correct names are as follows: ' 'computer1= 'computer2= 'computer3= ' 'If your log file contains server names that are not followed by 'the equals sign, the script will ignore them and assume they are 'administrative comments. ' 'Change Log: '1.01 - Changed loging of "datecreated" to "datemodified" because new 'dumps weren't logging correct times. ' 'This script is provided under the Creative Commons liscense located 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not 'be used for comercial purposes with out the expressed written consent 'of NateRice.com Const OpenAsDefault = -2 Const FailIfNotExist = 0 Const CreateIfNotExist = 1 Const ForReading = 1 Const ForWriting = 2 Set oFSO = CreateObject("Scripting.FileSystemObject") Set WshShell = WScript.CreateObject("WScript.Shell") sNewDumps = False '--Find current working directory-- aScriptFilename = Split(Wscript.ScriptFullName, "\") sScriptFilename = aScriptFileName(Ubound(aScriptFilename)) sWorkingDirectory = Replace(Wscript.ScriptFullName, sScriptFilename, "") '---------------------------------- sInputFile = FindInputFile(sWorkingDirectory) sNow = Replace(Replace(Now(),"/","-"),":",".") sLogFile = sWorkingDirectory & "BSODCheck-" & sNow & ".log" Set oResultsLog = oFSO.OpenTextFile(sLogFile, ForWriting, CreateIfNotExist) oResultsLog.WriteLine "-----------------BSODCheck LOG FILE-------------------" oResultsLog.WriteLine "Input File: " & sInputFile oResultsLog.WriteLine "Start Time: " & Now() oResultsLog.WriteLine "" sStartTime = Now() On Error Resume Next Set oInputFile = oFSO.OpenTextFile(sInputFile, ForReading) sInputFileContents = oInputFile.ReadAll If Not Err.Number = 0 Then oResultsLog.WriteLine "!!!!!!Error: " & Err.Number oResultsLog.WriteLine "!!!!!!Error Desc: " & Err.Description If Err.Number = 424 Then oResultsLog.WriteLine "!!!!!! No Input Log File Found." End If If Not Instr(sInputFileContents,"=") > 0 And Not trim(Err.Number) = "424" Then oResultsLog.WriteLine "ERROR!" oResultsLog.WriteLine "An error occured. No system names were found in the input" oResultsLog.WriteLine "file. System names must be followed by an equals sign." oResultsLog.WriteLine "" End If On Error Goto 0 aInputFileContents = Split(sInputFileContents,vbCRLF) For Each sLine In aInputFileContents If InStr(sLine,"=") > 0 Then aServerName = Split(sLine,"=") sServerName = aServerName(0) sCheckResults = CheckForMemoryDump(sServerName) sCurrentDump = Split(sCheckResults,"|") sLastDump = Split(aServerName(1),"|") If IsDate(sCurrentDump(0)) And (IsDate(sLastDump(0)) Or sLastDump(0) = "0") Then If DateDiff("S",sLastDump(0),sCurrentDump(0)) > 0 Then oResultsLog.WriteLine sServerName & "=" & sCheckResults & _ "|New Dump Since Last Log!" sNewDumps = True Else oResultsLog.WriteLine sServerName & "=" & sCheckResults End If Else oResultsLog.WriteLine sServerName & "=" & sCheckResults End If End IF Next oResultsLog.WriteLine "" oResultsLog.WriteLine "Stop Time: " & Now() oResultsLog.WriteLine "Total Time: " & ReadableTime(DateDiff("S",sStartTime,Now())) oResultsLog.WriteLine "---------------End BSODCheck LOG FILE-----------------" oResultsLog.Close If sNewDumps Then WScript.Echo "NEW DUMPS! Please Check: " & vbCRLF & sLogFile '----This section could be used to send an email with the results of the log file.--- ' Set oResultsLog = oFSO.OpenTextFile(sLogFile,ForReading) ' sLogContents = oResultsLog.ReadAll ' oResultsLog.Close ' Set oMessage = CreateObject("CDO.Message") ' oMessage.Subject = "New Memory Dumps!" ' oMessage.From = "somebody@naterice.com" ' oMessage.To = "somebody@somebody.com" ' oMessage.TextBody = sLogContents ' oMessage.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 _ ' oMessage.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "mailserver" ' oMessage.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 ' oMessage.Configuration.Fields.Update ' oMessage.Send '------------------------------------------------------------------------------------ End If Set oFSO = Nothing Function CheckForMemoryDump(sServerName) 'This functions checks for the existance of the file "memory.dmp" 'on a remote computer. If the file exists, the size and date 'are returned as a string seperated by the "|" character. 'This script is provided under the Creative Commons liscense located 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not 'be used for comercial purposes with out the expressed written consent 'of NateRice.com If oFSO.FileExists("\\" & sServerName & "\c$\winnt\memory.dmp") Then Set fMemoryDump = oFSO.GetFile("\\" & sServerName & "\c$\winnt\memory.dmp") sDateCreated = fMemoryDump.DateLastModified sSize = ReadableBytes(fMemoryDump.Size) CheckForMemoryDump = sDateCreated & "|" & sSize Else CheckForMemoryDump = 0 End If End Function Function FindInputFile(sDirectory) 'This function scans the current working directory for files beginning 'with the name "bsodcheck". If the file is found, it's name is parsed 'to find the date. If the date is the lastest found in the current 'working directory, the file name is returned as FindInputFile. ' 'Format: BSODCheck-10-01-2006 10.06.21PM.log 'This script is provided under the Creative Commons liscense located 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not 'be used for comercial purposes with out the expressed written consent 'of NateRice.com Set oFileList = oFSO.GetFolder(sDirectory).Files For Each fFile In oFileList If LCase(Left(fFile.Name,9)) = "bsodcheck" And Len(fFile.Name) > 13 Then sFileName = Replace(fFile.Name,".log","") sDate = Replace(sFileName,".",":",11) If DateDiff("S",sLatestLogDate,sDate) > 0 Or len(sLatestLogDate) = 0 Then sLatestLogDate = sDate sLatestLog = fFile.Name End If End If Next FindInputFile = sLatestLog End Function Function ReadableTime(vSeconds) 'This function creates readable time in Years:Days:Hours:Minutes:Seconds 'From the a value (vSeconds) passed in seconds. ' 'This script is provided under the Creative Commons liscense located 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not 'be used for comercial purposes with out the expressed written consent 'of NateRice.com If Not IsNumeric(vSeconds) Then ReadableTime = -1 Exit Function End If vScale = "seconds" If vSeconds >= 60 Then vSeconds1 = vSeconds Mod 60 aMinutes = Split((vSeconds / 60), ".") vMinutes = aMinutes(0) vSeconds = "." & vSeconds1 vScale = "mm.ss" End If If vMinutes >= 60 Then vMinutes1 = vMinutes Mod 60 aHours = Split((vMinutes / 60), ".") vHours = aHours(0) vMinutes = ":" & vMinutes1 vScale = "hh:mm.ss" End If If vHours >= 24 Then vHours1 = vHours Mod 24 aDays = Split((vHours / 24), ".") vDays = aDays(0) vHours = ":" & vHours1 vScale = "dd:hh:mm.ss" End If If vDays >= 365 Then vDays1 = vDays Mod 365 aYears = Split((vDays / 365), ".") vYears = aYears(0) vDays = ":" & vDays1 vScale = "yyyy:dd:hh:mm.ss" End If ReadableTime = vYears & vDays & vHours & vMinutes & vSeconds & " (" & vScale & ")" End Function Function ReadableBytes(num_bytes) 'This function will convert a value passed in bytes to a more readable 'format with the appropriate two character suffex. Ex: ' 1936022345 would return 1.8 GB ' 43112345 would return 41.12 MB 'This script is provided under the Creative Commons liscense located 'at http://creativecommons.org/licenses/by-nc/2.5/ . It may not 'be used for comercial purposes with out the expressed written consent 'of NateRice.com If num_bytes <= 1023 Then ReadableBytes = num_bytes & " B" 'Bytes! ElseIf num_bytes <= (1024 ^ 2) And num_bytes >= 1024 Then ReadableBytes = Round(num_bytes / 1024, 2) & " KB" 'Kilobytes! ElseIf num_bytes <= (1024 ^ 3) And num_bytes >= (1024 ^ 2) Then ReadableBytes = Round(num_bytes / (1024 ^ 2), 2) & " MB" 'Megabytes! ElseIf num_bytes <= (1024 ^ 4) And num_bytes >= (1024 ^ 3) Then ReadableBytes = Round(num_bytes / (1024 ^ 3), 2) & " GB" 'Gigabytes! ElseIf num_bytes <= (1024 ^ 5) And num_bytes >= (1024 ^ 4) Then ReadableBytes = Round(num_bytes / (1024 ^ 4), 2) & " TB" 'Terabytes! ElseIf num_bytes <= (1024 ^ 6) And num_bytes >= (1024 ^ 5) Then ReadableBytes = Round(num_bytes / (1024 ^ 5), 2) & " PB" 'Petabytes! ElseIf num_bytes <= (1024 ^ 7) And num_bytes >= (1024 ^ 6) Then ReadableBytes = Round(num_bytes / (1024 ^ 6), 2) & " EB" 'Exabytes! ElseIf num_bytes <= (1024 ^ 8) And num_bytes >= (1024 ^ 7) Then ReadableBytes = Round(num_bytes / (1024 ^ 7), 2) & " ZB" 'Zettabytes! ElseIf num_bytes <= (1024 ^ 9) And num_bytes >= (1024 ^ 8) Then ReadableBytes = Round(num_bytes / (1024 ^ 8), 2) & " YB" 'Yottabytes! End If End Function |
| Send this to: |

Comments
said...
Thanks for sharing this wonderful script. I will try this.
10/4/2010 2:20:36 AM