Availability Report using Uptime.exe

I am looking for VB/Powershell Script to use following command and update the output in CSV format.

uptime.exe \\serverA /d:01/01/2011 give you the output as below and I am looking for output as attached excel file.

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
Uptime Report for: \\ServerA [edited]

Current OS:  Microsoft Windows Server 2003 R2, Service Pack 2, (Build 3790), Multiprocessor Free.

System Events as of   9/5/2011  3:20:27 PM:


Current system uptime: 3 day(s), 10 hour(s), 26 minute(s), 18 second(s)
-------------------------------------------------------------------------------

Since 4/19/2011: (Last 157 Days)

           System Availability: 99.6804%
                  Total Uptime: 157d 3h:14m:52s
                Total Downtime: 0d 12h:5m:36s
                 Total Reboots: 27
     Mean Time Between Reboots: 5.84 days
             Total Bluescreens: 0

Notes:
4/19/2011 Is the earliest date in the event log where sufficient information is recorded to calculate availability.

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+


output.xlsx
getazharAsked:
Who is Participating?
 
RobSampsonConnect With a Mentor Commented:
OK, this should do it.

Regards,

Rob.
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
    strPath = Wscript.ScriptFullName
    strCommand = "%comspec% /k cscript  """ & strPath & """"
    Set objShell = CreateObject("Wscript.Shell")
    objShell.Run(strCommand), 1, True
    Wscript.Quit
End If

Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1

strInput = "C:\Temp\Scripts\computers.txt"
strTempFile = "C:\Temp\Scripts\a.txt"
strOutput = "C:\Temp\Scripts\LogOutput.csv"
strUptimeExe = "C:\Temp\Scripts\Uptime.exe"

Set objOutput = objFSO.CreateTextFile(strOutput, True)
objOutput.WriteLine """Server Name"",""Operating System"",""Event as of"",""Calculated Since"",""System Availability"",""Current System Uptime"",""Total Uptime"",""Total Downtime"",""Total Reboots"",""Mean Time Between Reboots"",""Total Bluescreens"""

Set objInput = objFSO.OpenTextFile(strInput, ForReading, False)
strUptimeExe = objFSO.GetFile(strUptimeExe).ShortPath
While Not objInput.AtEndOfStream
	strComputer = Trim(objInput.ReadLine)
	If strComputer <> "" Then
		WScript.Echo "Pinging " & strComputer
		If Ping(strComputer) = True Then
			WScript.Echo "Querying " & strComputer
			If objFSO.FileExists(strTempFile) = True Then objFSO.DeleteFile strTempFile, True
			strCommand = "cmd /c " & strUptimeExe & " \\" & strComputer & " /d:01/01/2011 > """ & strTempFile & """"
			objShell.Run strCommand, 0, True
			If objFSO.FileExists(strTempFile) = True Then
				Set objUptime = objFSO.OpenTextFile(strTempFile, ForReading, False)
				strCurrentOS = ""
				strEventsAsOf = ""
				strSince = ""
				strSysAvail = ""
				strUptime = ""
				strTotalUptime = ""
				strTotalDowntime = ""
				strReboots = ""
				strMeanReboot = ""
				strBluescreens = ""
				While Not objUptime.AtEndOfStream
					strLine = Trim(objUptime.ReadLine)
					If LCase(Left(strLine, 12)) = LCase("Current OS: ") Then
						strCurrentOS = Mid(strLine, 13)
					ElseIf LCase(Left(strLine, 20)) = LCase("System Events as of ") Then
						strEventsAsOf = Mid(strLine, 21)
					ElseIf LCase(Left(strLine, 6)) = LCase("Since ") Then
						strSince = Mid(strLine, 7)
					ElseIf LCase(Left(strLine, 21)) = LCase("System Availability: ") Then
						strSysAvail = Mid(strLine, 22)
					ElseIf LCase(Left(strLine, 23)) = LCase("Current System Uptime: ") Then
						strUptime = Mid(strLine, 24)
					ElseIf LCase(Left(strLine, 14)) = LCase("Total Uptime: ") Then
						strTotalUptime = Mid(strLine, 15)
					ElseIf LCase(Left(strLine, 16)) = LCase("Total Downtime: ") Then
						strTotalDowntime = Mid(strLine, 17)
					ElseIf LCase(Left(strLine, 15)) = LCase("Total Reboots: ") Then
						strReboots = Mid(strLine, 16)
					ElseIf LCase(Left(strLine, 27)) = LCase("Mean Time Between Reboots: ") Then
						strMeanReboot = Mid(strLine, 28)
					ElseIf LCase(Left(strLine, 19)) = LCase("Total Bluescreens:") Then
						strBluescreens = Mid(strLine, 20)
					End If
				Wend
				objUptime.Close
				Set objUptime = Nothing
				objFSO.DeleteFile strTempFile, True
				objOutput.WriteLine """" & strComputer & """,""" & strCurrentOS & """,""" & strEventsAsOf & """,""" & _
					strSince & """,""" & strSysAvail& """,""" & strUptime & """,""" & strTotalUptime & """,""" & _
					strTotalDowntime & """,""" & strReboots & """,""" & strMeanReboot & """,""" & strBluescreens & """"
			Else
				objOutput.WriteLine """" & strComputer & """,""ERROR RUNNING UPTIME"""
			End If
		Else
			objOutput.WriteLine """" & strComputer & """,""OFFLINE"""
		End If
	End If
Wend
objInput.Close
objOutput.Close

WScript.Echo "Finished. Please see " & strOutput

Function Ping(strComputer)
	Dim objShell, boolCode
	Set objShell = CreateObject("WScript.Shell")
	boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
	If boolCode = 0 Then
		Ping = True
	Else
		Ping = False
	End If
End Function

Open in new window

0
 
AkhaterCommented:
I am not a fan of parsing but you can find this here http://gallery.technet.microsoft.com/ScriptCenter/72fbded6-88b3-4596-98c2-067a96fe6976/

alternatively this is a powershell script that will give you a similar result
$computers = "computer1","computer2","computer3"
$all = @()


$computers | %{
    if(Test-Connection $_ -Count 1 -Quiet) {
	$out = new-object psobject 

	$out | add-member noteproperty Name $_


        $OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $_  

	$out | add-member noteproperty OS $OS.caption

        $uptime = (Get-Date) - $OS.ConvertToDateTime($OS.LastBootUpTime)            

	$suptime = $uptime.days.tostring() + “ Days ” + $uptime.hours.tostring() + “ Hours ” + $uptime.minutes.tostring() + “ Minutes ” + $uptime.seconds.tostring() + “ Seconds”

	$out | add-member noteproperty UpTime $suptime

	$all += $out
    }
}


$all | export-csv c:\uptime.csv

Open in new window

0
 
getazharAuthor Commented:
@Akhater - Thanks for your response but does not meet my requirement...
0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

 
AkhaterCommented:
which one doesn't  ? I gave you 2 scripts
0
 
getazharAuthor Commented:
@Akhter - Given PS Script gives me only Name, OS & UpTime details.

Kindly have a look at attached excel file in the initial request for desired output format & fields.

I have used given Microsoft link and doesn't meet my requirement.

Regards,
Ameer
0
 
AkhaterCommented:
As I told you I am not a fan of parsing, it is a loss of time IMHO

anyway if this is what you want it is your call this code will do it for you you will just need to finish it

assuming the a.txt contains the uptime result you pasted
$a = get-content "a.txt"

$lnServerName = $a | Select-String "uptime report"
$ServerName = $lnServerName.ToString().split("\\")[2]

$lnOS = $a | Select-String "Current OS:"
$OS = $lnOS.ToString().replace("Current OS:  ","").TrimStart()

$lnEventasof = $a | Select-String "System Events as of"
$Eventasof   = $lnEventasof.ToString().replace("System Events as of   ","").TrimStart()

$lnUptime = $a | Select-String "Current system uptime:"
$Uptime   = $lnUptime.ToString().replace("Current system uptime: ","").TrimStart()

$lnSince = $a | Select-String "since"
$Since = $lnSince.ToString().replace("Since ","").TrimStart()

$lnSysAvai = $a | Select-String "System Availability:"
$SysAvai = $lnSysAvai.ToString().replace("System Availability: ","").TrimStart()


$out = new-object psobject 

$out | add-member noteproperty "Server Name" $ServerName
$out | add-member noteproperty "Operating System" $OS
$out | add-member noteproperty "Event as of" $Eventasof 
$out | add-member noteproperty "Uptime" $Uptime
$out | add-member noteproperty "Calculated Since" $Since 
$out | add-member noteproperty "System Availability" $SysAvai 


$out | export-csv "c:\uptime.csv"

Open in new window

0
 
getazharAuthor Commented:
could you please modify the given script to take the server names from servers.txt

Servers.txt contains content in below format.

ServerA
ServerB
ServerC
0
 
getazharAuthor Commented:
@Akhater - Do you got any update on this ?

We can close this if yes.
0
 
getazharAuthor Commented:
Can someone correct the script to take the input from servers.txt ?
0
 
getazharAuthor Commented:
Hi, it's working fine when A.txt has only server output.

here is the output from output.csv

#TYPE System.Management.Automation.PSCustomObject                              
Server Name      Operating System      Event as of      Uptime      Calculated Since      System Availability
      System.Object[]      System.Object[]      System.Object[]      System.Object[]      System.Object[]
0
 
getazharAuthor Commented:
Loop needs to be added to check multiple servers info in A.txt

Can someone help me in correcting this ?
0
 
RobSampsonCommented:
Hi, I managed to stick with Powershell, and this took me longer than I care to admit, but I think it works.  I really need to learn Powershell.....
$header = "Server Name,Operating System,Event as of,Uptime,Calculated Since,System Availability"
$input = "C:\temp\scripts\computers.txt"
$tempfile = "C:\Temp\Scripts\a.txt"
$output = "C:\Temp\Scripts\LogOutput.csv"

New-Item "$output" -type file -force -value $header`r`n

get-content $input | Foreach-Object {
    cmd /c c:\temp\scripts\uptime \\$_ /d:01/01/2011 > "$tempfile"
    ParseLog "$tempfile" "$output"
}

Function ParseLog([string]$inputfile, [string]$outputfile)
{
$a = get-content "$inputfile"

$lnServerName = $a | Select-String "uptime report"
$ServerName = $lnServerName.ToString().split("\\")[2]

$lnOS = $a | Select-String "Current OS:"
$OS = $lnOS.ToString().replace("Current OS: ","").TrimStart()

$lnEventasof = $a | Select-String "System Events as of"
$Eventasof   = $lnEventasof.ToString().replace("System Events as of   ","").TrimStart()

$lnUptime = $a | Select-String "Current system uptime:"
$Uptime   = $lnUptime.ToString().replace("Current system uptime: ","").TrimStart()

$lnSince = $a | Select-String "since"
$Since = $lnSince.ToString().replace("Since ","").TrimStart()

$lnSysAvai = $a | Select-String "System Availability:"
$SysAvai = $lnSysAvai.ToString().replace("System Availability: ","").TrimStart()

add-content $outputfile "$ServerName,`"$OS`",$Eventasof,`"$Uptime`",$Since,$SysAvai"
}

Open in new window

0
 
getazharAuthor Commented:
@ Rob - glad to see your response. I would be very happy if you could code this in a VBScript. Given PowerShell script doesn't work well.. it's just created headers in output.csv and taking very long time.

Cheers,
Ameer
0
 
RobSampsonCommented:
OK, this is much more within my comfort zone ;-)

Try this.

Regards,

Rob.
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
    strPath = Wscript.ScriptFullName
    strCommand = "%comspec% /k cscript  """ & strPath & """"
    Set objShell = CreateObject("Wscript.Shell")
    objShell.Run(strCommand), 1, True
    Wscript.Quit
End If

Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1

strInput = "C:\Temp\Scripts\computers.txt"
strTempFile = "C:\Temp\Scripts\a.txt"
strOutput = "C:\Temp\Scripts\LogOutput.csv"
strUptimeExe = "C:\Temp\Scripts\Uptime.exe"

Set objOutput = objFSO.CreateTextFile(strOutput, True)
objOutput.WriteLine """Server Name"",""Operating System"",""Event as of"",""Uptime"",""Calculated Since"",""System Availability"""

Set objInput = objFSO.OpenTextFile(strInput, ForReading, False)
strUptimeExe = objFSO.GetFile(strUptimeExe).ShortPath
While Not objInput.AtEndOfStream
	strComputer = Trim(objInput.ReadLine)
	If strComputer <> "" Then
		WScript.Echo "Pinging " & strComputer
		If Ping(strComputer) = True Then
			WScript.Echo "Querying " & strComputer
			If objFSO.FileExists(strTempFile) = True Then objFSO.DeleteFile strTempFile, True
			strCommand = "cmd /c " & strUptimeExe & " \\" & strComputer & " /d:01/01/2011 > """ & strTempFile & """"
			objShell.Run strCommand, 0, True
			If objFSO.FileExists(strTempFile) = True Then
				Set objUptime = objFSO.OpenTextFile(strTempFile, ForReading, False)
				strCurrentOS = ""
				strEventsAsOf = ""
				strUptime = ""
				strSince = ""
				strSysAvail = ""
				While Not objUptime.AtEndOfStream
					strLine = Trim(objUptime.ReadLine)
					If Left(strLine, 12) = "Current OS: " Then
						strCurrentOS = Mid(strLine, 13)
					ElseIf Left(strLine, 20) = "System Events as of " Then
						strEventsAsOf = Mid(strLine, 21)
					ElseIf Left(strLine, 23) = "Current System Uptime: " Then
						strUptime = Mid(strLine, 24)
					ElseIf Left(strLine, 6) = "Since " Then
						strSince = Mid(strLine, 7)
					ElseIf Left(strLine, 21) = "System Availability: " Then
						strSysAvail = Mid(strLine, 22)
					End If
				Wend
				objUptime.Close
				Set objUptime = Nothing
				objFSO.DeleteFile strTempFile, True
				objOutput.WriteLine """" & strComputer & """,""" & strCurrentOS & """,""" & strEventsAsOf & """,""" & strUptime & """,""" & strSince & """,""" & strSysAvail & """"
			Else
				objOutput.WriteLine """" & strComputer & """,""ERROR RUNNING UPTIME"""
			End If
		Else
			objOutput.WriteLine """" & strComputer & """,""OFFLINE"""
		End If
	End If
Wend
objInput.Close
objOutput.Close

WScript.Echo "Finished. Please see " & strOutput

Function Ping(strComputer)
	Dim objShell, boolCode
	Set objShell = CreateObject("WScript.Shell")
	boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
	If boolCode = 0 Then
		Ping = True
	Else
		Ping = False
	End If
End Function

Open in new window

0
 
getazharAuthor Commented:
Working fine but data in Uptime: field is not being updated in CSV file.
0
 
RobSampsonCommented:
When you run
uptime \\PC1 /d:01/01/2011 > PC1Uptime.txt

and open that text file, do you see a line that starts with
"Current System Uptime: "

as the first 23 characters?

Could you post a sample of your file with that data?

Rob.
0
 
getazharAuthor Commented:
Hi Rob,

here is the output of requested command...
=+=+=+=+=+=+=+=+=+=+=+=+=+=+
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

Uptime Report for: \\PC1 [EDITED]

Current OS:  Microsoft Windows Server 2003 R2, Service Pack 2, (Build 3790), Multiprocessor Free.

System Events as of  9/22/2011  2:33:52 PM:


Current system uptime: 2 day(s), 0 hour(s), 28 minute(s), 48 second(s)


-------------------------------------------------------------------------------

Since 2/15/2011: (Last 219 Days)

           System Availability: 99.7677%
                  Total Uptime: 218d 15h:16m:10s
                Total Downtime: 0d 12h:13m:4s
                 Total Reboots: 31
     Mean Time Between Reboots: 7.07 days
             Total Bluescreens: 0

Notes: 2/15/2011 Is the earliest date in the event log where sufficient information is recorded to calculate availability.

=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
=+=+=+=+=+=+=+=+=+=+=+=+=+=+


Rob-output.xlsx
0
 
RobSampsonCommented:
Oh OK, yours is lowercase....for some reason, mine had upper case letters...

This should work.

Rob.
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
    strPath = Wscript.ScriptFullName
    strCommand = "%comspec% /k cscript  """ & strPath & """"
    Set objShell = CreateObject("Wscript.Shell")
    objShell.Run(strCommand), 1, True
    Wscript.Quit
End If

Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1

strInput = "C:\Temp\Scripts\computers.txt"
strTempFile = "C:\Temp\Scripts\a.txt"
strOutput = "C:\Temp\Scripts\LogOutput.csv"
strUptimeExe = "C:\Temp\Scripts\Uptime.exe"

Set objOutput = objFSO.CreateTextFile(strOutput, True)
objOutput.WriteLine """Server Name"",""Operating System"",""Event as of"",""Uptime"",""Calculated Since"",""System Availability"""

Set objInput = objFSO.OpenTextFile(strInput, ForReading, False)
strUptimeExe = objFSO.GetFile(strUptimeExe).ShortPath
While Not objInput.AtEndOfStream
	strComputer = Trim(objInput.ReadLine)
	If strComputer <> "" Then
		WScript.Echo "Pinging " & strComputer
		If Ping(strComputer) = True Then
			WScript.Echo "Querying " & strComputer
			If objFSO.FileExists(strTempFile) = True Then objFSO.DeleteFile strTempFile, True
			strCommand = "cmd /c " & strUptimeExe & " \\" & strComputer & " /d:01/01/2011 > """ & strTempFile & """"
			objShell.Run strCommand, 0, True
			If objFSO.FileExists(strTempFile) = True Then
				Set objUptime = objFSO.OpenTextFile(strTempFile, ForReading, False)
				strCurrentOS = ""
				strEventsAsOf = ""
				strUptime = ""
				strSince = ""
				strSysAvail = ""
				While Not objUptime.AtEndOfStream
					strLine = Trim(objUptime.ReadLine)
					If LCase(Left(strLine, 12)) = LCase("Current OS: ") Then
						strCurrentOS = Mid(strLine, 13)
					ElseIf LCase(Left(strLine, 20)) = LCase("System Events as of ") Then
						strEventsAsOf = Mid(strLine, 21)
					ElseIf LCase(Left(strLine, 23)) = LCase("Current System Uptime: ") Then
						strUptime = Mid(strLine, 24)
					ElseIf LCase(Left(strLine, 6)) = LCase("Since ") Then
						strSince = Mid(strLine, 7)
					ElseIf LCase(Left(strLine, 21)) = LCase("System Availability: ") Then
						strSysAvail = Mid(strLine, 22)
					End If
				Wend
				objUptime.Close
				Set objUptime = Nothing
				objFSO.DeleteFile strTempFile, True
				objOutput.WriteLine """" & strComputer & """,""" & strCurrentOS & """,""" & strEventsAsOf & """,""" & strUptime & """,""" & strSince & """,""" & strSysAvail & """"
			Else
				objOutput.WriteLine """" & strComputer & """,""ERROR RUNNING UPTIME"""
			End If
		Else
			objOutput.WriteLine """" & strComputer & """,""OFFLINE"""
		End If
	End If
Wend
objInput.Close
objOutput.Close

WScript.Echo "Finished. Please see " & strOutput

Function Ping(strComputer)
	Dim objShell, boolCode
	Set objShell = CreateObject("WScript.Shell")
	boolCode = objShell.Run("Ping -n 1 -w 300 " & strComputer, 0, True)
	If boolCode = 0 Then
		Ping = True
	Else
		Ping = False
	End If
End Function

Open in new window

0
 
getazharAuthor Commented:
Hi Rob,

Is it possible to modify the script to provide the output.csv with listed fields in the excel sheet.

Thank you so much for your understanding and help :)

Regards,
Ameer
Desired-Output.xlsx
0
 
RobSampsonCommented:
Did you want Current System Uptime in there as well, or not?  And is the CSV OK?  CSV is much easier than Excel...
0
 
getazharAuthor Commented:
yeah.. CSV is absolutely fine and it would be great if you could add additional column for "Current System Uptime" aswell... :)

Cheers Mate...

Regards,
Ameer
0
 
getazharAuthor Commented:
@ Rob

Excellent !!!  you really deserve it.

you rocks as like always.. I am amazed with your thunder fast response and scripting skills :)

looking forward to work with you on such challenging requirements... :)

Cheers,
Ameer
1
 
RobSampsonCommented:
No problem Ameer. Thanks for the grade.  I really want to learn Powershell, it's just a bit different and I struggle with some of the concepts, and I don't have much time.  One day.....

Thanks for the grade.

Regards,

Rob.
0
 
getazharAuthor Commented:
Rob, somehow "total blue screen" info is missing in the output.. could you please look into this ?
0
 
RobSampsonCommented:
Oh, please change:
                              ElseIf LCase(Left(strLine, 19)) = LCase("Total Bluescreens:") Then

to this:
                              ElseIf LCase(Left(strLine, 18)) = LCase("Total Bluescreens:") Then

Regards,

Rob.
0
 
getazharAuthor Commented:
Thank you so much for the response.

I have got one more problem in this.. I am trying to schedule this script and realized that every time I have to change below line of the script.

is it possible to modify the script in such a way where it will take look at 1st of last month on every month.. I mean when I schedule this script to run on 1st of every month it should collect the data for last month. In current scenario on November first it should execute and collect the uptime report from october 1st to 31st 2011. is it possible... sorry if I am asking too much.

strCommand = "cmd /c " & strUptimeExe & " \\" & strComputer & " /d:09/01/2011 > """ & strTempFile & """"
0
 
RobSampsonCommented:
That's pretty easy.  You can just change this line:
                  strCommand = "cmd /c " & strUptimeExe & " \\" & strComputer & " /d:01/01/2011 > """ & strTempFile & """"

to this:
                  dteDate = DateAdd("m", -1, Date)
                  strDate = Right("0" & Month(dteDate), 2) & "/01/" & Year(dteDate)
                  strCommand = "cmd /c " & strUptimeExe & " \\" & strComputer & " /d:" & strDate & " > """ & strTempFile & """"

and it will automatically subtract one month, then use the month and year from that date, and use "/01"/ for the day.

Regards,

Rob.
0
 
Anuj BaranwalCommented:
Hi ROB or someone from this thread. I tried to apply this but i am getting blank output in CSV file.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.