Summary: The Microsoft Scripting Guys show you how to use Windows PowerShell to determine the reliability of your Windows 7 or Window Server 2008 R2 computer.
Hey, Scripting Guy! Our CIO is a rather strange creature. He seems to go missing for weeks on end, and then suddenly he will appear in the server room, create havoc, and leave. He’s our poltergeist. Today was the day for his bimonthly apparition. So there I was, diligently reviewing event logs on my assigned servers, when suddenly I feel the temperature rise several degrees. The hair on the back of my neck seemed to stand on end (this might be a good time to tell you that our CIO in addition, to being spectral in his countenance, is a rather large being who radiates heat on even the coldest days). I turned around and asked him, “Can I help you?” He then asked if I could show the reliability of our newly deployed Windows Server 2008 R2 servers. I started to offer him the current uptime report that I run each day, but he said, “No! I want reliability not uptime. Get it for me by the end of the week.” Dude! I have no idea what he is talking about. Do you?
— SC
Hello SC,
Microsoft Scripting Guy Ed Wilson here. Recently, I had the opportunity to speak at SQL Saturday in Raleigh, North Carolina, in the United States. Because Raleigh is a four-hour drive from Charlotte, I sat in the passenger seat and spent the time exploring Windows Management Instrumentation (WMI) classes. This is actually one of my favorite things to do, and I found a few WMI classes that looked particularly interesting. The classes all include the word reliability in their name. I will show you some of the things I found in just a bit. By the way, SQL Saturday was a lot of fun. I was there talking about Windows PowerShell Best Practices. The following photo was taken during the session.
Anyway, SC, back to your question. Let me show you a really cool trick for finding WMI classes. You probably know that you can use the Get-WmiObject cmdlet with the –list switch to produce a listing of WMI class names. But did you know you can also filter that list? This is shown here:
PS C:\> Get-WmiObject -List “*reliabil*”
NameSpace: ROOT\cimv2
Name Methods Properties
—- ——- ———-
Win32_Reliability {} {}
Win32_ReliabilityStabilityMetrics {GetRecordCount} {EndMeasurementDate, Rel…
Win32_ReliabilityRecords {GetRecordCount} {ComputerName, EventIden…PS C:\>
Therefore, three WMI classes have the word Reliability in their name.
Note: The WMI Reliability provider exists only on Windows 7 and Windows Server 2008 R2 (and later). It is enabled by default on Windows 7 computers, but must be specifically enabled via the “Configure Reliability WMI Providers” Group Policy setting for the server operating system.
Because I was riding in the passenger seat of a motor vehicle that was traveling 65 miles per hour down the interstate, and I did not have access to the Internet, I did not have access to the MSDN documentation. Back when I was traveling every week, I used to download and install Windows SDK documentation on my laptop, but that consumes a huge chunk of my pitifully small laptop hard drive, and nowadays I always access the documentation via the Internet. The problem comes during road trips. However, this is not a problem in one knows how to use the tools that are inherent to Windows WMI implementations. Using wbemtest, I opened the first WMI class that was listed. The results are shown in the following image. The thing that is the most important to recognize is that the Win32_Reliability class is an abstract class.
I then looked at the classes that are derived from this class. They are shown in the following image.
It is possible to query an abstract class, but the results are unreliable and unsupported. One thing that is confusing is that when querying an abstract class, the results that are returned come from the derived classes and not the abstract itself. In our example, the Win32_Reliability WMI class has two classes that are derived from it: Win32_ReliabilityStabilityMetrics and Win32_ReliabilityRecords. To see that the results are returned from the derived class, you need to query the abstract. Note that the __CLASS system property tells us the class that returns the information. In this example, it is the Win32_ReliabilityStabilityMetrics class. Note also that the __RELPATH system property (relative path) and the __PATH property point to the Win32_ReliabilityStabilityMetrics class as well. The __SUPERCLASS property (I call it the “who’s your daddy” property) gives us the parent class or the class from whence the current class is derived. The system properties, therefore, tell us that Win32_Reliability did not answer our WMI query; rather, it was the Win32_ReliabilityStabilityMetrics class that responded to our question. The output is shown here:
PS C:\> Get-WmiObject -Class win32_reliability | Select-Object -First 1
__GENUS : 2
__CLASS : Win32_ReliabilityStabilityMetrics
__SUPERCLASS : Win32_Reliability
__DYNASTY : Win32_Reliability
__RELPATH : Win32_ReliabilityStabilityMetrics.TimeGenerated=”201009231500
00.000000-000″
__PROPERTY_COUNT : 5
__DERIVATION : {Win32_Reliability}
__SERVER : MRED1
__NAMESPACE : root\cimv2
__PATH : \\MRED1\root\cimv2:Win32_ReliabilityStabilityMetrics.TimeGene
rated=”20100923150000.000000-000″
EndMeasurementDate : 20100923150000.000000-000
RelID : {806265F0-CDBC-4078-84D8-53EEB08CCA22}
StartMeasurementDate : 20100923140000.000000-000
SystemStabilityIndex : 3.449
TimeGenerated : 20100923150000.000000-000PS C:\>
Just for fun, I thought I would use the abstract Win32_Reliability class to provide a breakdown between the number for each of the two derived classes. Here is the command I typed into my Windows PowerShell console:
PS C:\> GWMI win32_reliability | group __class | ft name, count -A
Name Count
—- —–
Win32_ReliabilityStabilityMetrics 8005
Win32_ReliabilityRecords 2222
That command expands when not using the aliases. Here is the same command without using the aliases.
Get-ReliabilityBreakDown.ps1
Get-WmiObject -Class win32_reliability -ComputerName .|
Group-Object -Property __class |
Format-Table -Property name, count –AutoSize
I then decided to write a script that will pull out the win32_reliabilityStabilityMetrics for my computer. The Get-ReliabilityMetrics.ps1 script is shown here.
Get-ReliabilityMetrics.ps1
“Processing $((Get-WmiObject -Class win32_reliabilityStabilityMetrics).count) records”
Get-WmiObject -Class win32_reliabilityStabilityMetrics |
Format-Table -Property @{Label = “time”; Expression = `
{[Management.ManagementDatetimeConverter]::ToDateTime($_.TimeGenerated)} },
SystemStabilityIndex -autosize
The first line uses the count method from the WMI class to display a notation about how many reliability records are to be processed. This is meant as a status indicator to let you know the script is working. Because a subexpression is required to force evaluation of the WMI object before calling the count method, the code looks a bit strange with several parentheses. This is shown here:
“Processing $((Get-WmiObject -Class win32_reliabilityStabilityMetrics).count) records”
If you did not use a subexpression, concatenation would be required to display the number of records inside a string. To me, I prefer to use the subexpression inside the expanding quotation marks rather than use the concatenation that is shown here:
“Processing ” + (Get-WmiObject -Class win32_reliabilityStabilityMetrics).count + ” records”
The basic WMI query is performed with the Get-WMiObject cmdlet, and the results are piped to the Format-Table cmdlet. This is shown here:
Get-WmiObject -Class win32_reliabilityStabilityMetrics |
If you need to target a remote computer, use the –computername parameter; use the –credential parameter if alternate credentials are required:
PS C:\> Get-WmiObject -Class win32_reliabilityStabilityMetrics -ComputerName cdc1 -Credential contoso\administrator
When the code seen above runs, the credential dialog box appears that is shown in the following image:
The most complicated portion of the script uses a hash table to create a custom property in the Format-Table command. WMI time is difficult to read, as shown here:
20100911100000.000000-000
The time seen above is the year 2010, the month is September, the day is the eleventh, and the time is 1000 GMT. It makes more sense to translate that time into something more readable. Years ago, the Microsoft Scripting Guys wrote a custom function that used string manipulation to convert the long series of numbers into a more readable format. Nowadays, such a function is neither necessary nor desired. The .NET Framework includes the ManagementDateTimeConverter class in the System.Management namespace. The word System is left off because Windows PowerShell assumes that everything is included under the System root namespace. The ToDateTime method is static and will convert the WMI time into a more readable time string. The method can be called directly as shown here where I translate the above WMI date:
PS C:\> [Management.ManagementDatetimeConverter]::ToDateTime(“20100911100000.000000-000″)
Saturday, September 11, 2010 6:00:00 AM
PS C:\>
This portion of the script is shown here:
Format-Table -Property @{Label = “time”; Expression = `
{[Management.ManagementDatetimeConverter]::ToDateTime($_.TimeGenerated)} },
SystemStabilityIndex –autosize
One thing to keep in mind is that the use of the –autosize switch to tighten up the output display significantly slows down the script. It makes for an easier output to read, as shown in the following image.
Windows PowerShell has to process each of the 8,003 records on my computer, determine how much space is required for displaying the output, and then display the output. Without this switch, the output fills the output pane of the Windows PowerShell ISE or the Windows PowerShell console, as shown in the following image.
SC, that is all there is to using the Win32_Reliability WMI classes. Reliability Week will continue tomorrow when we will talk about filtering reliability records.
We invite you to follow us on Twitter and Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
0 comments