The details of the event scenario and the design points for Beginner Event #6 of the 2012 PowerShell Scripting Games can be found on the “Hey, Scripting Guys! Blog”.
Write a PowerShell script to determine the uptime of servers by using the WMI class WMI32_OperatingSystem. The script should display the server name, how many days, hours, and minutes the server has been up.
As usual, I started out by running Get-Help Get-WMIObject to determine what the available parameters were for this cmdlet. I ran Get-WMIObject -Class Win32_OperatingSystem but that didn’t return much:
I could pipe this to Get-Member to determine what the property names are, but sometimes it’s easier to pipe it to Format-List * to not only see what the available properties are, but to also see what their values are. I’ve selected only the properties that are inportant as shown in the screenshot below since the results of all (*) are lengthy.
I did some research online and determined that I would need to convert the LastBootUpTime to a DateTime to be able to use it. I then started out using Get-Date for the current time and $Env:ComputerName for the computer name. Then I thought about the requirements of using WMI. Based on the information in the screenshot above, I could pull everything I needed out of that single WMI class. I could use LocalDateTime instead of using Get-Date and CSName instead of $Env:ComputerName. I read somewhere that it’s better to use CSName than __Server for the computer name although they both contained the same value.
My research on how to convert the DateTime information returned by WMI to a useable format lead me to the “Manipulating Dates Returned by Windows Management Instrumentation (WMI)” blog on the Hey, Scripting Guy! Blog.
One of the prep video’s by Chris Brown (@chrisbrownie) titled “2012 Scripting Games – Video 2 – Working with Dates” on PowerShellDownUnder.com helped me figure out how to format my output. I initially defined variables for each of the items such as $Days = $Uptime.Days and the code in my script was eleven lines long, by using $($Uptime.Days) directly in the output, I was able to cut my code to five lines and simplify it.
I tried to match the output in the screenshot provided in the scenario so I wanted the “as of” date to be in AM/PM format instead of what was being returned by default (24 hour format). I found an MSDN article on “Standard Date and Time Format Strings” which assisted me in converting the date to a “General date/time pattern (long time)” using .ToString(‘G’).
I’ve formatted it slightly different in the above screenshot so it fits better on this blog.
$win32os = Get-WmiObject -Class Win32_OperatingSystem
$now = ($win32os.ConvertToDateTime($win32os.LocalDateTime))
$lastboot = ($win32os.ConvertToDateTime($win32os.LastBootupTime))
$uptime = $now - $lastboot
Write-Output "The computer $($win32os.csname) has been up for $($uptime.days) days $($uptime.hours) hours $($uptime.minutes) minutes, $($uptime.seconds) seconds as of $($now.tostring('G'))"
Here’s a link to my entry for this event on the PowerShell Code Repository site.