Why metrics matter and how PowerShell can help
- select the contributor at the end of the page -
Ever hear the saying, If you can’t measure it, you can’t manage it? It’s one of my favorite quotes because it rings so true when dealing with IT infrastructure. The ability to build metrics around stats, like uptime, is a great way to see the level of quality you’re delivering to customers. Your servers probably don’t go down every day, so it’s possible that you don’t even realize they’re bombing every month or so. Downtime like this results in loss—it’s a major hindrance to business. It all boils down to this: Without metrics you have no way to improve. You have no number; no target goal. Thankfully, you can easily avoid this problem.
Building a useful script
One of the most common metrics we can get is general “uptime.” Uptime might mean different things to different people but, today, we’ll think of it as the time in which a Windows server has been booted up. Granted, it’s not the most sophisticated metric for uptime, but it gives you an idea of how often a server is rebooted, shutdown or lost power for whatever reason.
Whenever a Windows computer is booted up it will always register an event 6005 in the System event log; when shutdown, it will always register an event ID 6006 in the System event log. Using PowerShell and some simple date comparisons we can build a script that will show us when a computer was booted up, when it was shut down, when it came back up and when it got shut down again. We can see this information as far back as the event log goes. By then comparing the startup and shutdown dates we can build a helpful report of the times a server was down and for how long.
First, we’ll need to query the System event log. I like to use Get-WinEvent because it’s typically faster than using Get-EventLog. To only query the System event log and the 6005 ID to find all startup times, we’ll need to use the -FilterHashTable parameter.
You can see that I’m querying the computer SOMEPC for all of the start events. Since we don’t need any of the other information in the event, we'll then create a $StartTimes variable that will contain only the dates in which the computer was booted up.
Next, we’ll do the same only for the 6006 event ID. But this time, in order to get the date comparisons working right, we’ll order the events by oldest first (by default, Get-WinEvent orders the events newest first).
We now have all start and stop events on the computer. This means it’s time to loop through all of the start times to see if we can find a corresponding stop time. We'll use a foreach loop here to iterate over each of the start times and will then check for the corresponding stop time by finding the closest stop time that’s greater than the start time.
If we can’t find a stop time, this is probably because the computer is still running. In that case, just use the current time as the stop time. This will get the most current uptime.
Remember, we want to see the date and time the computer has stopped and started each time. We also want to see how long that was between those two times. To get this information in a nice format, we'll create a custom object (shown above). This custom object has properties of Startup, Shutdown, Uptime (Days) and Uptime (Min) which will be the difference of the two dates.
If all goes as planned you should get a nice output like this:
And it's as simple as that. I’ve put this script out on my Github repo if you’d like to download it and give it a shot!