Saturday 14 August 2010

Windows Uptime

It's a bit odd that Windows does not provide an uptime command whose sole purpose were that, telling us the Uptime of our machine, but well, we have different options to get it:

  1. net statistics server
    as this command will display a bit more of information than just the uptime, we can trim it to just our desired line by using the grep equivalent provided by the Windows Resource Kit, qgrep:
    net statistics server | qgrpe -e "Statistics since"
    As you can test, it returns when the the computer was last booted.

  2. SystemInfo
    this command provides a lot of information about our system, but because of that it can take some seconds to run, so it's less useful for this task. Again, you can refine the results with qgrep:
    SystemInfo | qgrep -e "System Up Time"
    Again, it returns when the computer was last booted.

  3. WMI and WSH
    WMI is one of those wonderful Windows technologies of which potential not everyone is fully aware. I'm used to work with it from WSH (another underrated Windows technology), so I've prepared a script that uses WMI for either getting when the computer was booted:



    var wmiDate = WScript.CreateObject("WbemScripting.SWbemDateTime");
    var wmiObj = GetObject("winmgmts:\\\\" + strComputer + "\\root\\cimv2");
    var aux = wmiObj.ExecQuery("
    Select * from Win32_OperatingSystem");
    //WMI queries always return a collection, so get the first element (the only element in this case)
    var osInfo = new Enumerator(aux).item();
    wmiDate.Value = osInfo.LastBootUpTime;
    WScript.Echo(wmiDate.GetVarDate());


    or obtaining how many seconds have elapsed since then:



    var wmiObj = GetObject("winmgmts:\\\\" + strComputer + "\\root\\cimv2");
    //returns a collection with an only item
    var aux = wmiObj.ExecQuery("
    Select * From Win32_PerfFormattedData_PerfOS_System");
    var osPerfInfo = new Enumerator(aux).item();
    WScript.Echo("
    UpTime: " + osPerfInfo.SystemUpTime + " seconds");


    As you can see in the full source for this second case I had to add some extra code to turn the seconds into weeks, days, hours... this made me think that with .Net I just would need to create a TimeSpan object from those seconds, and it would already provide me the Days, Hours, minutes... so, why not to use the successor technology to WSH, one with full access to the .Net power? this takes us to:

  4. WMI and Windows PowerShell
    After playing for a while with the PowerShell console (If you have PowerShell installed, it should be here: C:\WINDOWS\system32\windowspowershell\v1.0)
    I realized this would involve several lines and I would better write a PowerShell script, so I came up with this uptime.ps1 file (it's my first PowerShell script, so please, be understanding):



    $perfObject = gwmi Win32_PerfFormattedData_PerfOS_System
    $seconds = $perfObject.SystemUpTime
    write-output ($seconds.ToString() + " seconds uptime")

    $timeSpan = new-object System.TimeSpan -argumentlist ($seconds * 1000 * 1000 * 10)
    write-output ($timeSpan.Days.ToString() + " days, " + $timeSpan.Hours.ToString() + " hours, " + $timeSpan.Minutes.ToString() + " minutes, " + $timeSpan.Seconds.ToString() + " seconds")


    in order to run it from the console you'll need to set permissions for running .ps1 scripts (yes, I agree it's weird that it's not enabled by default, but MS is taking security really serious), so type:

    Set-ExecutionPolicy RemoteSigned

    then, if you cd to the folder containing the script, just type:

    .\uptime.ps1

    and that's all.

No comments:

Post a Comment