Friday, 9 December 2011

Getting system uptime with PowerShell

Finding out how long your system has been powered on (minus the time it was hibernating) shouldn't be difficult, and it isn't. All I had to was call the TickCount property of the System.Environment .Net class which returned the number of milliseconds since the last restart. In PowerShell, this would be:

 [System.Environment]::TickCount  
I divided the TickCount by 3600000 to get the number of hours since last boot-up, enclosed the line in a function and added it my functions.psm1 file:
 function uptime()  
 {  
   [System.Environment]::TickCount/3600000  
 }  

Everything was fine for about 25 days of continuous operation. After that, every time I typed 'uptime', I would get a negative value. Although it was immediately clear that 25 days translated to about 2 billion milliseconds which is more then long-type TickCount could hold, it brought me to square one. The solution to the problem I had thought solved had to be redesigned.

Before I go any further, for those who don't want to know how I came about it and what it does, here's the final solution:

 function uptime()  
 {    
   $pc = New-Object System.Diagnostics.PerformanceCounter("System", "System Up Time")  
   $upSeconds = 0.0  
   $totalSleepTime = 0  
   $sleepFor = 100  
   do  
   {  
     $upSeconds = $pc.NextValue()  
     $totalSleepTime = $totalSleepTime + $sleepFor  
     sleep -m $sleepFor  
   }  
   while(($upSeconds -eq 0) -or ($totalTime -eq 1000))  
   $pc.Close()  
   $upMinutes = [Math]::Floor($upSeconds / 60)  
   $upHours = [Math]::Floor($upMinutes / 60)  
   $remainingMinutes = $upMinutes % 60  
   [string]::Format("{0:0} Hours {1:0} Minutes", $upHours, $remainingMinutes)  
 }