Getting Your Uptime – The PowerShell Way!

powershell3I remember, back in my admin days, we had an executable called uptime.exe.  It didn’t do much, but it gave us the amount of time that a system had been up and running for – which was something useful for checking if you suspected a server had gone offline and didn’t want to log in to verify if it crashed or not.

Some months back, I wrote a PowerShell script to give me the uptime on a remote system.  It worked well, but the formatting left something to be desired.  Using Get-CimInstance, and a little PowerShell math, I came up with this:

Get-CimInstance Win32_OperatingSystem -ComputerName Server01 | Select-Object CSName,LastBootUpTime,@{Name = 'Uptime';Expression = {$PSItem.LocalDateTime - $PSItem.LastBootUpTime }}

It does well enough, but the output format isn’t the prettiest.  In particular, I’m not really happy with the uptime output, as someone may not immediately realize that the first set of digits is days.

CSName      LastBootUpTime           Uptime
------      --------------           ------
Server01    11/19/2014 1:20:02 AM    14.08:16:27.5529900

So what to do?  I did a little reading and came across one of the Scripting Guys’ posts about the New-Timespan cmdlet and how it works.  Well, we know that the LastBootUpTime is a datetime data type; and we know that the New-Timespan cmdlet takes datetime datatypes; so we should be able to hook those two up.   So let’s do this!
#Define our current date and pull the last reboot date from a machine.
$Date = Get-Date
$Reboot = Get-CimInstance Win32_OperatingSystem -ComputerName Server01 |
Select-Object CSName,LastBootUpTime

This will give us our current date and time to feed in to the New-TimeSpan cmdlet, and the LastBootUpTime from the Win32OperatingSystem class.  I’m also grabbing the system name from the CSName property to feed into my output.  Now let’s build our command:
#Put it all together to get system uptime information
New-TimeSpan -Start $Reboot.LastBootUpTime -End $Date |
Select-Object @{Label = "System Name"; Expression = {$Reboot.CSName}},@{Label = "Last Reboot Time"; Expression = {$Reboot.LastBootUpTime}},Days,Hours,Minutes,Seconds |
Format-Table -AutoSize

I formatted the table to make it a little bit cleaner and relabeled the CSName and LastBootUpTime properties to make things a bit easier to read.  Now we get the following output:

System Name      Last Reboot Time         Days Hours Minutes Seconds
-----------      ----------------         ---- ----- ------- -------
Server01         11/19/2014 1:20:02 AM    14   9     19      29

Now just add some parameterization for the computer name, maybe give it some logic to scan multiple machines, and you’ve got yourself a very fine replacement for uptime.exe.

Feel free to download the script from the TechNet Script Center.