One of the most wonderful things about PowerShell is the ability to pass objects down the Pipe for further processing. In my first version of Get-Uptime I did not utilize this because I wanted to show what a huge difference it makes. I wanted to get this out pretty quick so I didn’t add the prettiness that I had in my first version, but it is easy enough to add.

Here is the new Code. After the code I give some examples of how to use it.

  1. Function Get-Uptime{
  2.     Param([string]$server)
  3.     Begin {
  4.         function PingServer {
  5.             Param([string]$srv)
  6.             $pingresult = Get-WmiObject win32_pingstatus -f "address=’$srv’"
  7.             if($pingresult.statuscode -eq 0) {$true} else {$false}
  8.         }
  9.         function myUptime {
  10.             param([string]$srv)
  11.             $os = Get-WmiObject Win32_OperatingSystem -ComputerName $srv
  12.             $uptime = $os.LastBootUpTime
  13.             return $uptime
  14.         }
  15.         function ConvertDate {
  16.             param([string]$date,[string]$srv)
  17.             $year = $date.substring(0,4)
  18.             $Month = $date.Substring(4,2)
  19.             $day = $date.Substring(6,2)
  20.             $hour = $date.Substring(8,2)
  21.             $min = $date.Substring(10,2)
  22.             $sec = $date.Substring(12,2)
  23.             $RebootTime = new-Object System.DateTime($year,$month,$day,$hour,$min,$sec)
  24.             $now = [System.DateTime]::Now
  25.             $uptime = $now.Subtract($RebootTime)
  26.             $uptimeval = "$($uptime.days) days, $($uptime.Hours) hours, $($uptime.Minutes) minutes, $($uptime.seconds) seconds"
  27.             $lastReboot = $rebootTime.toString()
  28.             $sObject = new-Object -typename System.Object
  29.             $sObject | add-Member -memberType noteProperty -name ServerName -Value $srv
  30.             $sObject | add-Member -memberType noteProperty -name Days -Value $uptime.days
  31.             $sObject | add-Member -memberType noteProperty -name Hours -Value $uptime.Hours
  32.             $sObject | add-Member -memberType noteProperty -name Minutes -Value $uptime.Minutes
  33.             $sObject | add-Member -memberType noteProperty -name Seconds -Value $uptime.seconds
  34.             $sObject | add-Member -memberType noteProperty -name uptime -Value $uptimeval
  35.             $sObject | add-Member -memberType noteProperty -name LastReboot -Value $rebootTime.ToUniversalTime()
  36.             $sObject | add-Member -memberType noteProperty -name LastRebootUtc -Value $rebootTime.ToFileTimeUtc()
  37.             write-Output $sObject
  38.         }
  39.         Write-Host
  40.         $process = @()
  41.         $objCollection = @()
  42.     }
  43.     Process {
  44.         if($_){
  45.             if($_.ServerName ){
  46.                 $process += $_.ServerName
  47.             }
  48.             else{
  49.                 $process += $_
  50.             }
  51.         }
  52.     }
  53.     End {
  54.         if($Server){$process += $server}
  55.         $i = 1
  56.         foreach ($Server in $process){
  57.             write-progress $Server "Total Progress->" -percentcomplete ($i/$process.length*100)
  58.             if(PingServer $server){
  59.                 $result = myUptime $server
  60.                 $srvObject = ConvertDate $result $server
  61.                 $objCollection += $srvObject
  62.             }
  63.             else {
  64.                 Write-Host "Server [$server] not Pingable" -foregroundcolor red
  65.             }
  66.             $i = $i+1
  67.         }
  68.         Write-Output $objCollection
  69.         Write-Host
  70.     }
  71. }



Examples:

This get uptime on a Single Server

  1. get-uptime server | %{$_.uptime}

This gets all servers up for more than 30 days

  1. $sl | Get-Uptime | ?{$_.Days -gt 30} | %{write-host "$($_.ServerName) :: $($_.uptime)"}

This Displays the Last Reboot Time of a list of servers.

  1. $sl | get-uptime | %{Write-Host "Server $($_.ServerName) rebooted on $($_.LastReboot)"}



The part of this I want to focus on is this

  1. $sObject = new-Object -typename System.Object
  2.  $sObject | add-Member -memberType noteProperty -name ServerName -Value $srv
  3.  $sObject | add-Member -memberType noteProperty -name Days -Value $uptime.days
  4.  $sObject | add-Member -memberType noteProperty -name Hours -Value $uptime.Hours
  5.  $sObject | add-Member -memberType noteProperty -name Minutes -Value $uptime.Minutes
  6.  $sObject | add-Member -memberType noteProperty -name Seconds -Value $uptime.seconds
  7.  $sObject | add-Member -memberType noteProperty -name uptime -Value $uptimeval
  8.  $sObject | add-Member -memberType noteProperty -name LastReboot -Value $rebootTime.ToUniversalTime()
  9.  $sObject | add-Member -memberType noteProperty -name LastRebootUtc -Value $rebootTime.ToFileTimeUtc()

This is where I define my custom object. There are numerous ways to do this, but I chose this way. Notice the use of add-member cmdlets… It is extremely powerfull and extremely easy to use.

Basically what I do is create a Generic Object $sObject. Add some noteProperties and populate them. Very simple, but as you can very “POWER”ful.

Lee Holms has some excelent information on Custom Objects here:
http://www.leeholmes.com/blog/AddCustomMethodsAndPropertiesToTypesInPowerShell.aspx

I hope you enjoyed this new version… I currently actually keep both versions in my functions.ps1 file that I load in my profile. One as Get-Uptime and one as Get-UptimeExt. I get pretty and Smart :)