How Can I Determine the Uptime for a Server?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I determine the uptime for a server?

-- LF

SpacerHey, Scripting Guy! AnswerScript Center

Hey, LF. This is an easy one. After all, we’re assuming you’re talking about a Windows server, and Windows servers never go down, right? Therefore, the uptime must be forever. Problem solved.

Well, OK, we suppose that maybe a Windows server could go down (probably because a non-Windows user snuck in and pulled the plug or something). If you need to know the system uptime on either a Windows XP or a Windows Server 2003 computer you can use a script like this:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * From Win32_PerfFormattedData_PerfOS_System")

For Each objOS in colOperatingSystems
intSystemUptime = Int(objOS.SystemUpTime / 60)
Wscript.Echo intSystemUptime & " minutes"

As you can see, we connect to the WMI service and then use the ExecQuery method to retrieve all instances of the Win32_PerfFormattedData_PerfOS_System class. (This, by the way, explains why the script runs only on Windows XP or Windows Server 2003: those are the only two versions of Windows that include the Win32_PerfFormattedData_PerfOS_System class.)

Win32_PerfFormattedData_PerfOS_System contains a number of performance counters related to the operating system, including SystemUpTime, which tells you how many second the machine has been running. We use this line of code to grab the value of SystemUpTime, divide it by 60 (thus giving us the uptime in minutes rather than seconds), and then convert it to an integer, stripping away anything after the decimal point:

intSystemUptime = Int(objOS.SystemUpTime / 60)

Yes, that is an awful lot for one little line of code to do, isn’t it? We then echo the value of the variable intSystemUptime and we’re done.

Well, unless you’re running Windows 2000, that is. Like we said, the preceding script won’t run on Windows 2000; Windows 2000 has never even heard of the Win32_PerfFormattedData_PerfOS_System class. Fortunately there is a workaround; it’s a bit clumsy, but it’s a workaround nevertheless:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("Select * from Win32_OperatingSystem")

For Each objOS in colOperatingSystems
dtmBootup = objOS.LastBootUpTime
dtmLastBootupTime = WMIDateStringToDate(dtmBootup)
dtmSystemUptime = DateDiff("n", dtmLastBootUpTime, Now)
Wscript.Echo dtmSystemUptime & " minutes"

Function WMIDateStringToDate(dtmBootup)
WMIDateStringToDate = CDate(Mid(dtmBootup, 5, 2) & "/" & _
Mid(dtmBootup, 7, 2) & "/" & Left(dtmBootup, 4) _
& " " & Mid (dtmBootup, 9, 2) & ":" & _
Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup,13, 2))
End Function

In this script we connect to the WMI service and then query the Win32_OperatingSystem class; that’s because Win32_OperatingSystem includes a property - LastBootUpTime - that can tell you the last time the computer started. That’s useful: if we subtract LastBootUpTime from the current time we’ll know - that’s right - how long the computer has been running.

The only tricky part is the fact that, like all WMI dates and times, LastBootUpTime is stored in the UTC (Universal Time Coordinate) format. That means you’re going to get back a value that looks like this:


Before you try, don’t bother subtracting that from the current date and time; it won’t work. Instead, we need to convert this into something that looks more like a real date and time; that’s why this line of code calls a function we wrote (WMIDateStringToDate) that converts a UTC datetime value into a regular old date-time value:

dtmLastBootupTime = WMIDateStringToDate(dtmBootup)

Note. We won’t explain how the function works. If you’re interested in that information, see this portion of the Microsoft Windows 2000 Scripting Guide.

After making the conversion we use the DateDiff function to subtract the last bootup time from the current time:

dtmSystemUptime = DateDiff("n", dtmLastBootUpTime, Now)

As you can see, we pass DateDiff three parameters:

“n”, which means to report the time difference in minutes.

dtmLastBootUpTime, a variable holding the converted datetime value.

Now, the current date and time.

All we do then is echo back the system uptime in minutes.

Like we said, we can’t imagine why you’d ever need a script like this for a Windows computer, but just in case ….

Comments (7)

  1. eric young says:

    Could you tell me how to get the system uptime in last 24 hours?

  2. malcolm says:

    Your WMIDateStringToDate, while it may work fine for those in the US, could do with a little tweak.

    European users tend to use dd/mm/yyyy for dates, and things become even more confusing when you have (like I do) a system in the UK which is installed with English (US) as the base language but the account has English (UK) set; unless that's set you end up with some accounts with mm/dd/yyyy for dates and some with dd/mm/yyyy and the conversions become unreliable.

    But! there is an easy way out of this; CDate will accept date-times in the form YYYY-MM-DD HH:MM:SS; so if you adjust the function a little you get accurate results no matter which way round the local date format is:

    Function WMIDateStringToDate(dtmBootup)

       WMIDateStringToDate = CDate(Left(dtmBootup, 4) & "-" & _

           Mid(dtmBootup, 5, 2) & "-" & Mid(dtmBootup, 7, 2) & _

               " " & Mid (dtmBootup, 9, 2) & ":" & _

                   Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup,13, 2))

    End Function

  3. Malcolm. says:

    Eric … system event log; look for the appropriate events and use their times for the shutdown and startup times [a quick look at my log reveals you probably want source EventLog, Event ID 6009 for system startup and Event ID 6006 for shutdown], the rest is just adding up.

    Of course, you can also assume an event ID 6009 which is NOT preceded by an event ID 6006 is an abnormal shutdown. This is just a simple first pass at answering your question and the method will probably need further tweaking 😉

  4. Wil Welsh says:

    The value of LastBootUpTime is blank on some machines.   What gives?

  5. Toby S says:

    Thank.  Your post was very helpful.

    I think a better way to deal with WMI dates is to use the WMI class "WbemScripting.SWbemDateTime".  You could write:

    Function WMIDateStringToDate(dtmBootup)

     Set objWMIDate = CreateObject("WbemScripting.SWbemDateTime")

     objWMIDate.Value = dtmBootup

     WMIDateStringToDate = objWMIDate.GetVarDate(True)

    End Function

    The True parameter for .GetVarDate(True) means treat it as a local time (instead of UTC).  I'm not certain if this works for Windows 2000, but that OS is now defunct anyway.

    And querying Win32_OperatingSystem is much faster than Win32_PerfFormattedData_PerfOS_System – at least on Windows 7.

  6. Jason says:

    spent most of my day trying to get this script to run via a monitoring system. I finally realized (after getting it to run) that the returned number is not the amount of minutes since boot time- honestly I don’t get how it arrives at that number anyone
    here experience that and find a fix? (trying to monitor uptime properly on a W2k server)

  7. LuisT says:

    Great post!

    Here are more methods to know Windows uptime:

Skip to main content