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.

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:

Uptime: 2 days, 5 hours, 14 seconds

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:

Test-Path $profile

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:

New-Item –Path $profile –Type file -Force

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


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:

Set-ExecutionPolicy –ExecutionPolicy RemoteSigned

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:

notepad $profile

Writing the Get-Uptime script ^

First of all, let me express my debt of gratitude to the good folks at the 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:

function Get-Uptime {
   $os = Get-WmiObject win32_operatingsystem
   $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
   $Display = "Uptime: " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes" 
   Write-Output $Display

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.

Set-Location C:\
$console = $host.UI.RawUI
$console.WindowTitle = "Tim's PowerShell Console"
$console.BackgroundColor = "Gray"
$console.ForegroundColor = "Black"

$buffer = $console.BufferSize
$buffer.Width = 80
$buffer.Height = 5000
$console.BufferSize = $buffer

$size = $console.WindowSize
$size.Width = 80
$size.Height = 25
$console.WindowSize = $size

New-Item alias:np -value "C:\Windows\System32\notepad.exe"
New-Item alias:st -value "C:\Program Files\Sublime Text 3\sublime_text.exe"

function Get-Uptime {
   $os = Get-WmiObject win32_operatingsystem
   $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
   $Display = "Uptime: " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes" 
   Write-Output $Display


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.

  1. Serge Nikalaichyk 8 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
    param (
    [Parameter(Position = 0, Mandatory = $false, ValueFromPipeline = $true)]
    [String]$ComputerName = $Env:ComputerName,

    [Parameter(Position = 1, Mandatory = $false)]
    [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
    “{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

    # 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

  2. Serge Nikalaichyk 8 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
    param (
    [Parameter(Position = 0, Mandatory = $false, ValueFromPipeline = $true)]
    [String[]]$ComputerName = $Env:ComputerName,

    [Parameter(Position = 1, Mandatory = $false)]
    [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
    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

  3. Author
    Timothy Warner 8 years ago

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

  4. Mike J 8 years ago

    Why not use the CMD utility “uptime” ?

  5. jeff hicks 8 years ago

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

  6. Jason 6 years 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}}}

  7. Roger Valle 6 years 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.

  8. Ralph 5 years ago


    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.

  9. Nate Ferrell 5 years 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!

    function Get-Uptime {
     $ComputerName = $env:COMPUTERNAME,
     $Format = "String",
     $Credential = [System.Management.Automation.PSCredential]::Empty
     $Final = @()
     foreach ($Computer in $ComputerName)
     $OS = Get-WmiObject win32_operatingsystem -ComputerName $Computer -Credential $Credential
     $Current = ($OS.ConvertToDateTime($OS.LocalDateTime))
     $LastBoot = ($OS.ConvertToDateTime($OS.LastBootUpTime))
     if ($Format -eq "DateTime")
     $LastBoot | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer
     $Final += $LastBoot
     $Uptime = $Current - $LastBoot
     if ($Format -eq "String")
     $Final += "[$Computer] Uptime: " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes" 
     $Uptime | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer
     $Final += $Uptime
     return $Final

  10. Alan 5 years 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)?

  11. Brad 3 years ago

    Here is a one liner

    $os = Get-WmiObject win32_operatingsystem; $uptime = (Get-Date) – ($os.ConvertToDateTime($os.lastbootuptime)); Write-Host “Uptime: ” $Uptime.Days ” days, ” $Uptime.Hours ” hours, ” + $Uptime.Minutes + ” minutes”

    • Luc Fullenwarth 3 years ago


      Here is an interesting explanation of Mike Robbins about what is a oneliner and what is not a oneliner.

      Anyway, besides the definition of a oneliner, your method is interesting. But you should have a look at the comment of Jeffery Hicks a few lines above. Here is the line of code he is talking about.

      PS> Get-CimInstance -ClassName Win32_OperatingSystem|Select-Object -Property LastBootUpTime
      01-Mar-19 20:39:44

      Or also

      PS> (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime
      Friday, 1 March, 2019 20:39:44

      Thanks for sharing Brad!

  12. Luc Fullenwarth 3 years ago


    This is a bit late, but it will probably help others…

    uptime over a certain period even after reboots or shutdowns/startups

    An uptime value has only sense between two reboot or stop/start.
    An uptime value has no sense spanning several computer restarts.

Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


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


Log in with your credentials


Forgot your details?

Create Account