2015-11-03

Windows PerfCounters and Powershell - Infrastructure

In this series of blogs, I will cover Windows performance counters infrastructure, collecting and interpreting the data and, in final blog, provide the Powershell script built on this. I should note that I am very new to Powershell so take my empirical findings with grain of salt. Also, coming from Linux bash, I found Powershell confusing at first but, after getting comfortable with concept of passing Objects down the pipe, I have to say I like it a lot.

It all starts in WDM framework (Windows Driver Model) where metrics is collected for WMI-for-WDM enabled device drivers. The classes created by the WDM provider to represent device driver data reside in the "Root\WMI" namespace. I will talk of namespaces shortly.
So, the WDM provider records information about WDM operations in the WMI Log Files. However, WMI is not just mirroring physical data provided by WDM but it also adds (logical) counters.
Windows Management Instrumentation (WMI) is the Microsoft implementation of Web-Based Enterprise Management (WBEM), which is an industry initiative to develop a standard technology for accessing management information in an enterprise environment. WMI uses the Common Information Model (CIM) industry standard to represent systems, applications, networks, devices, and other managed components. CIM is developed and maintained by the Distributed Management Task Force (DMTF). I will talk of CIM cmdlets in Powershell shortly.

There are many ways to collect performance data in Windows, like through Registry functions, but not all of them make sense. Since WMI is a database-like service always returning live data, it is used to find out details about physical and logical computer configurations and works locally as well as remotely (only for Windows OS). It is organized in PerfCounter classes which return PerfCounter objects. So the usual way to start exploring is to collect the Classes with Get-WmiObject -List. First lines are similar to below:
NameSpace: ROOT\CIMV2

Name Methods Properties
---- ------- ----------
...


So what is NAMESPACE? The WMI infrastructure is a part of Microsoft Windows operating system and has two components: the WMI service (winmgmt), including the WMI Core, and the WMI repository.
WMI repository is organized in WMI namespaces. The WMI service creates some namespaces such as root\default, root\cimv2, and root\subscription at system startup and preinstalls a default set of class definitions, including the Win32 Classes, the WMI System Classes, and others. The remaining namespaces found on your system are created by providers for other parts of the operating system or products.
The WMI service acts as an intermediary between the providers (management applications) and WMI repository. Only static data about objects is stored in the repository, such as the classes defined by the providers meaning WMI obtains most data dynamically from the provider when a client requests it.
A WMI consumer is a management application or script that interacts with the WMI infrastructure. A management application can query, enumerate data, run provider methods, or subscribe to events by calling either the COM API for WMI or the Scripting API for WMI (like WMI-enabled Powershell cmdlets). The only data or actions available for a managed object, such as a disk drive or a service, are those that a provider supplies.
So, basically, NAMESPACE is a subfolder :-) The default namespace is “root\CIMV2” and you do not need to submit the namespace to a function call as long as the class you're addressing is located inside the default one. Most of us will use default namespace (ROOT\CIMV2) for most of the tasks but let's list them here for the sake of completeness:
PS > Get-WmiObject -Query “Select * from __Namespace” -Namespace Root | Select-Object -ExpandProperty Name
subscription
DEFAULT
CIMV2
Cli
nap
SECURITY
SecurityCenter2
RSOP
WMI
IntelNCS2
directory
Policy
Interop
ServiceModel
SecurityCenter
MSAPPS12
Microsoft
aspnet


Now, back to Get-WmiObject -List | Select Name output. We also see "duplicate" entries like this:
CIM_SoftwareElementActions
Win32_SoftwareElementAction

So, what's CIM? The Common Information Model is an open standard that defines how managed elements in an IT environment are represented as a common set of objects and relationships between them. The Distributed Management Task Force maintains the CIM to allow consistent management of these managed elements, independent of their manufacturer or provider. So CIM cmdlets will allow you to gather management data in heterogeneous environment as opposed to WMI cmdlets which work only on Windows. See wiki for the list of operating systems and provider-specific CIM implementations. This basically means that some of the WMI classes and their objects are copied to CIMv2 namespace to produce more standard objects.
So, CIM provider for WMI is consuming data from WMI and there are many benefits of using CIM in place of WMI:
  • Use of WSMAN for remote access – no more DCOM errors.
  • Note: You can drop back to DCOM for accessing systems with WSMAN 2 installed.
  • Use of CIM sessions for accessing multiple machines.
  • Get-CIMClass for investigating WMI classes.
  • Improved way of dealing with WMI associations.
  • Get-CimInstance do not contain any methods.
  • Note: This may appear as a drawback but GWMI will also loose this info when returned from background job or remote session due to serialization.
  • Works on other operating systems.

Note: Should you still find yourself in need to work with boxes running older Windows (such as XP), you can still use CIM cmdlets only define DCOM as protocol:
$oldProt = New-CimSessionOption -Protocol DCOM
$oldBoxSession = New-CimSession -ComputerName someOldXPBox -SessionOption $option
Get-CimInstance -ClassName Win32_SystemDevices -CimSession $oldBoxSession

However, DCOM is not firewall friendly and can be unavailable on destination box (which should run Windows OS).
Note: CIM cmdlets are available as of Powershell v3.

So, we learned how to list classes:
WMI: Get-WmiObject -List
CIM: Get-CimClass | Select CIMClassName | Sort CIMClassName

Note:From now on, I will mostly use CIM commands as they provide TAB completion.

Next, we need actual performance objects that chosen class provides:
PS > Get-CimInstance -Class Win32_Process
ProcessIdName HandleCountWorkingSetSizeVirtualSize
------------- ------------------------------------
0 System Idle P...0 24576 0
4 System 976 2834432 6344704

This is simple class but you will encounter more complex ones having Instances:
PS > Get-CimInstance -Class Win32_PerfFormattedData_Counters_ProcessorInformation

#All CPU's:
Name : _Total
...
PercentIdleTime : 73

#Core 0, total:
Name : 0,_Total
...
PercentIdleTime : 73

#Core 0, CPU 0:
Name : 0,0
...
PercentIdleTime : 100

and so on.

Notice also that I used PerfFormattedData class in this example. There are RawData classes too but that's for next blog.
PS > Get-CimInstance -Class Win32_PerfRawData_Counters_ProcessorInformation
Name : _Total
...
PercentIdleTime : 66682471448


This concludes the first blog in series. In next blog I will deal with various flavours of counter values.

In this series:
BLOG 1: PerfCounters infrastructure
BLOG 2: PerfCounters Raw vs. Formatted values
BLOG 3: PerfCounters, fetching the values
BLOG 4: PerfCounters, CPU perf data
BLOG 5: PerfCounters, Memory perf data
BLOG 6: PerfCounters, Disk/IO perf data
BLOG 7: PerfCounters, Network and Contention perf data

No comments:

Post a Comment