Calculating system uptime with PowerShell

Determining system uptime in Windows can be surprisingly inconvenient. Let’s use Windows PowerShell to quickly and easily calculate how long our local system has been online.
Profile gravatar of Timothy Warner

Timothy Warner

Timothy Warner is a Microsoft Cloud and Datacenter Management Most Valuable Professional (MVP) who is based in Nashville, TN. Check out his Azure and Windows Server video training at Pluralsight, and feel free to reach out to Tim via Twitter.
Profile gravatar of Timothy Warner

How do you track server uptime at your organization? It’s all well and good if you manage a System Center shop and have all of these metrics aggregated and available to you at a glance. For the rest of us, though, we have the systeminfo command-line tool that’s built into Windows server and client operating systems. However, the output here regarding uptime is only partially helpful, at best. To illustrate, take a look at some partial systeminfo output from my Windows 8.1 workstation:

Systeminfo tool

The systeminfo tool is helpful, but it doesn’t give us uptime in an easy-to-comprehend format.

As you can see, the System Boot Time property tells us when the computer was last started, but it doesn’t tell us how much time has elapsed since startup. For instance, I’d like to see uptime presented like this:

You and I both know that we can use Windows PowerShell to accomplish this goal. The question is which PowerShell command or sequence of commands we leverage to get the job done.

What we want to do, specifically, is:

  • Get today’s date.
  • Get the system boot time.
  • Perform subtraction (today’s date – boot time) to obtain the elapsed uptime.
  • Present the result in a user-friendly way.
  • Optionally (but desirable) have the results appear every time we start a Windows PowerShell session.

In this article, we’ll begin with the final objective. If we add a new PowerShell function to our PowerShell user profile script, we’ll see the local system uptime “automagically” every time we start the console.

Setting up your user profile script ^

Start by firing up an elevated Windows PowerShell console session. Let’s see if we already have a user profile script defined on the local system:

The results of the previous command are Boolean true or false. If it’s the latter, we need to create a new .ps1 profile script file in the default user profile path location. Try this:

That’s better! By the way, $profile is a system variable that stores the default user profile path location, which is typically:

C:\Users\username\Documents\WindowsPowerShell

The user profile script has the default file name Microsoft.PowerShell_profile.ps1. Next, we need to check the active Windows PowerShell script execution policy on the local system:

Let’s make an adjustment on our local system to allow local PowerShell scripts to run:

Now that we have our PowerShell profile script defined, we can open the empty file in Windows Notepad and commence actually writing our new Get-Uptime function:

Writing the Get-Uptime script ^

First of all, let me express my debt of gratitude to the good folks at the PowerShell.org Forums, and Sam Boutros in particular, for sharing the following code with me. Let me give you the Get-Uptime function definition in total, and then I’ll explain each line to you:

This code should work in any Windows PowerShell version.

  • Line 1: Function declaration. Notice that we’re using the traditional PowerShell verb–noun command syntax.
  • Line 2: Here, we make a call to the Windows Management Instrumentation (WMI) class win32_operatingsystem and put the object into the $os variable.
  • Line 3: Here, we subtract the result of the lastbootuptime property of the $os object (formatting it as DateTime) from the current date and store the result in a variable named $uptime.
  • Line 4: Here, we use string concatenation and $uptime object properties to format the function’s return value.
  • Line 5: Here, we display the result of the $Display object to the console.

Once you’ve loaded the Get-Uptime function into session memory, you can call it at any time during that session by typing Get-Uptime and pressing ENTER.

Customizing our user profile script ^

You may have already added the Get-Uptime function to your new user profile script; if so, then so much the better. Take a look at my personal profile script, shown in the following image. In addition to finding the function definition and call, you’ll see some other profile goodies that you may want to experiment with.

So that you can preview what the Get-Uptime function output looks like in practice, have a look at the following screenshot that I generated on my Windows 7 SP1 workstation:

The Get-Uptime function output

The Get-Uptime function output

A parting challenge ^

I’ve been a puzzle solver all my life; in my opinion, this is one of the reasons I enjoy Windows PowerShell so much. To that end, I’d like to leave you with a challenge question for you to work on:

How can you modify our Get-Uptime function such that it targets a predefined list of remote computers in addition to the local system?

Post your solution in the comments.

Take part in our competition and win $100!

Related Posts

10 Comments
  1. avatar
    Serge Nikalaichyk 3 years ago

    Imagine you have to modify your function to get system up time of multiple remote system in different time zones. You'll certainly get into problems.

    Long time ago I created a similar function. Check it out:

    function Get-UpTime
    {
    [CmdletBinding()]
    param (
    [Parameter(Position = 0, Mandatory = $false, ValueFromPipeline = $true)]
    [Alias("CN")]
    [String]$ComputerName = $Env:ComputerName,

    [Parameter(Position = 1, Mandatory = $false)]
    [Alias("RunAs")]
    [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
    )
    process
    {
    "{0} Uptime: {1:%d} Days {1:%h} Hours {1:%m} Minutes {1:%s} Seconds" -f $ComputerName,
    (New-TimeSpan -Seconds (Get-WmiObject Win32_PerfFormattedData_PerfOS_System -ComputerName $ComputerName -Credential $Credential).SystemUpTime)
    }
    }

    # Local computer's uptime
    Get-UpTime

    # Remote computer's uptime with prompt for credential
    Get-UpTime -ComputerName "Server01" -Credential (Get-Credential)

    # This function can be used in a pipeline
    "Server01", "Server02", "Server03" | Get-UpTime

    0
  2. avatar
    Serge Nikalaichyk 3 years ago

    I've slightly modified the function from my previous comment to support multiple computer names. PowerShell is all about objects, that's why it's also recommended to use the TimeSpan object to represent system up times instead of a String so we can reuse the output later. For example to sort computers by their up time (see examples below).

    function Get-SystemUpTime
    {
    [CmdletBinding()]
    param (
    [Parameter(Position = 0, Mandatory = $false, ValueFromPipeline = $true)]
    [Alias("CN")]
    [String[]]$ComputerName = $Env:ComputerName,

    [Parameter(Position = 1, Mandatory = $false)]
    [Alias("RunAs")]
    [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
    )
    process
    {
    foreach ($Name in $ComputerName)
    {
    Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_System -ComputerName $Name -Credential $Credential |
    Select-Object @{Name = "ComputerName"; Expression = {$_.__SERVER}},
    @{Name = "SystemUpTime"; Expression = {New-TimeSpan -Seconds $_.SystemUpTime}}
    }
    }
    }

    Get-SystemUpTime "Server01", "Server02", "Server03" | Sort-Object SystemUpTime

    "Server01", "Server02", "Server03" | Get-SystemUpTime | Sort-Object SystemUpTime

    0
  3. avatar Author
    Timothy Warner 3 years ago

    Wow, Serge--outstanding work! Thanks for sharing. -Tim

    0
  4. Profile gravatar of Mike J
    Mike J 3 years ago

    Why not use the CMD utility "uptime" ?

    1+
  5. avatar
    jeff hicks 3 years ago

    Using Get-CIMInstance the datetime value is automatically formatted for you.

    0
  6. avatar
    Jason 1 year ago

    Thanks everyone for detailing how all of this works.  Serge reading your post indicating that I could input objects into the function led me to create this. This code will scan the contents of an active directory OU and query eqch machine for its up time. I'm not very good at powershell so feel free to critique the efficiency of this "script".  I suppressed the errors but it would be cool if it would spit out something like "Unable to communicate with" $_.ComputerName

    Get-ADComputer -Filter '*' -Searchbase "OU=OU Name,DC=Domain Name,DC=net" | Select Name | Foreach-object {Get-WmiObject -Class Win32_PerfFormattedData_PerfOS_System -ComputerName $_.Name -ErrorAction SilentlyContinue| Select-Object@{Name="ComputerName";Expression = {$_.PSComputername}}, @{Name="SystemUpTime";Expression={New-TimeSpan -seconds $_.SystemUptime}}}

    0
  7. avatar
    Roger Valle 8 months ago

    Thank you for sharing Serge!

    I am new with PowerShell, and I need to get the physical address of the computers at my work. I wonder if there is a script I can use?

    Thank you in advance.

    0
  8. avatar
    Ralph 3 months ago

    Hello,

    For faster, i use the calculator ( date calculation ) on windows to get how much days the system have been running.

    PS : First, i run the systeminfo | more cmd,  to get the system boot time date information as source date.

     

    🙂 Hope i help.

    0
  9. avatar
    Nate Ferrell 2 months ago

    In case anyone is curious, I took the provided ideas and ran with them a little more... The below function works for multiple computers, allows specification of formatting as String (i.e. responses so far), DateTime object or TimeSpan object. DateTime and TimeSpan have the computer name added as a NoteProperty to the object so that multiple computers in the same run are distinguishable when running subsequent commands against them (i.e. If computer's uptime is greater than 1 week, Restart-Computer, etc)... Hope this helps others!

    0
  10. avatar
    Alan 4 weeks ago

    Hi, I am new to powershell and interested in machine uptime information for data analysis. May I check if the above powershell script is capable of checking total uptime over a certain period even after reboots or shutdowns/startups (ie: for 2 months or 1 year)?

    0

Leave a reply

Your email address will not be published. Required fields are marked *

*

CONTACT US

Please ask IT administration questions in the forum. Any other messages are welcome.

Sending
© 4sysops 2006 - 2017
Do NOT follow this link or you will be banned from the site!

Log in with your credentials

or    

Forgot your details?

Create Account