Windows Management Instrumentation (WMI) provides access to many powerful ways of managing Windows systems.

WMI model

WMI is a hierarchical namespace, in which the layers build on one another. The WMI model has three sections- Resources, infrastructure, and consumers.

  • WMI resources: Resources include anything that can be accessed by using WMI- File system, network components, event logs, files, Active Directory, and so on
  • WMI infrastructure: the infrastructure comprises three parts, WMI service, WMI repository, and WMI providers.
  • WMI consumers: A consumer provides a prepackaged way to process data from WMI. It can be a Powershell cmdlet, VBScript, et.
WMI namespaces

WMI organizes the namespaces in a similar fashion to the  filing cabinets. It is possible to extend the  filing cabinet analogy to include the three components of WMI: namespaces, providers, and classes. The namespaces are the  file cabinets. The providers are the drawers in the  file cabinet. The folders in the drawers of the  file cabinet are the WMI classes.

I pinched a paragraph from http://powershelldistrict.com/wmi-week-intro/.  On the left side you will see the names, and on the right concrete examples (here i took Cimv2win32_share and win32_bios as an exmple)

  • In red you will find the namespaces
  • In green the classes
  • In blue the properties
  • In yellow the methods

WMI_repository_structure

Namespaces can contain other namespaces, as well as other objects, and these objects contain properties you can manipulate. The Get-WmiObject cmdlet is used to make the connec- tion into WMI. The -class argument specifies the name of the class. In this example, the class name is __Namespace (the WMI class from which all WMI namespaces derive). Yes, you read that class name correctly—it is the word namespace preceded by two underscore characters.

Get-wmiObject -class __nameSpace -namespace root

When performing a WMI query against a remote computer, the user account performing the connection must be a member of the local administrators group on the remote machine. One way to accomplish this is to right-click the Windows PowerShell icon and select Run As Administrator from the menu that appears.

 

The Get-WmiNameSpace function will look like:

Function Get-WmiNameSpace

{

 Param(

  $nameSpace = "root",

  $computer = "localhost"

 )

 Get-WmiObject -class __NameSpace -computer $computer `

 -namespace $namespace -ErrorAction "SilentlyContinue" |

 Foreach-Object `

 -Process `

{

     $subns = Join-Path -Path $_.__namespace -ChildPath $_.name

     if($subns -notmatch 'directory') {$subns}

     $namespaces += $subns + "`r`n"

     Get-WmiNameSpace -namespace $subNS -computer $computer

   }
} #end Get-WmiNameSpace

Note that the highlighted part is a Recrusion (call the function inside itself), for more check here. It will stop until there is no object existe (controlled by foreach-object statement).

Listing WMI providers

To access information through WMI, you must have access to a WMI provider.

We will create a function to get the WMI provider info:

WMI bases providers on a template class, or a system class called __provider. We will look into the Win32 classes, such as Win32_NetworkAdapter or Win32_Process, monitor and manage system hardware and features. Generally, these classes are located in the root\cimv2 WMI namespace. Then we will sort the result based on the name property and only show the name.

Get-WmiProvider
      Function Get-WmiProvider
      {
       Param(
        $nameSpace = "root\cimv2",
        $computer = "localhost"
       )
        Get-WmiObject -class __Provider -namespace $namespace |
        Sort-Object -property Name |Select-Object name

      } #end function Get-WmiProvider
Work with WMI classes

Types:  core classes, common classes, and dynamic classes.

  • Core classes represent managed objects that apply to all areas of management. This provide a basic vocabulary for analyzing and describing managed systems. Two example: parameters and systemSecurity class.
  • Common classes are extensions to the core classes and represent managed objects that apply to specific management areas.  Network administrators do not use core and common classes because they serve as templates from which other classes derive.Many of the classes stored in Root\cimv2, therefore, are abstract classes and are of use as templates used in creating other WMI classes.
  • Dynamic classes:  a few classes in Root\cimv2 are dynamic classes used to hold actual information. The important aspect to remember about dynamic classes is that providers generate instances of a dynamic class, and therefore dynamic WMI classes are more likely to retrieve live data from the system.

One of the big problems with WMI is finding the needed WMI class from so many WMI classes. We can search MSDN, or use -list switch. A better solution is to stay focused on a single WMI namespace, and to use wildcard characters to assist in  finding appropriate WMI classes.

Get-WmiObject -List "*bios*"

There would be about 10 items in the result, If you want to further narrow the searching result, use the where-object cmdlet with regular expression. E.g. if we want to find WMI classes that begin with win32:

Get-WmiObject -List "*bios*" | where-object {$_.name -match '^win32'}

or

gwmi -list "*bios*" | ? name -match  '^win32'
  • gwim is the alias of Get-WmiObject.
  • ^ tells the match operator to begin looking at the beginning of the string.
  • ? symbol is an alias for the where-object cmdlet.

 

Querying WMI

Using the Get-WmiObject cmdlet to query a speci c WMI class

1. Connect to WMI by using the Get-WmiObject cmdlet.

2. Specify a valid WMI class name to query.

3. Specify a value for the namespace; omit the -namespace parameter to use the default root\ cimv2 namespace.

4. Specify a value for the -computername parameter; omit the -computername parameter to use the default value of localhost.

When an instance of the Win32_Bios WMI class appears, Windows PowerShell uses the DefaultDisplayPropertySet con guration to display only  five properties (if a <view> con guration is de ned, it trumps the default property set).

The portion of the Types.ps1xml  le that details these  ve properties appears here:

                    <PropertySet>

                        <Name>DefaultDisplayPropertySet</Name>

                        <ReferencedProperties>

                            <Name>SMBIOSBIOSVersion</Name>

                            <Name>Manufacturer</Name>

                            <Name>Name</Name>

                            <Name>SerialNumber</Name>

                            <Name>Version</Name>

                        </ReferencedProperties>

                    </PropertySet>

Another property set, called PSStatus, contains four properties.

The four properties appear in the PropertySet description shown here:

            <PropertySet>

                <Name>PSStatus</Name>

                <ReferencedProperties>

                    <Name>Status</Name>

                    <Name>Name</Name>

                    <Name>Caption</Name>

                    <Name>SMBIOSPresent</Name>

                </ReferencedProperties>

            </PropertySet>

There are some examples of how to use psstatus control data output:

gwmi win32_bios | select psstatus

gwmi win32_bios | fl psstatus

gwmi win32_bios | ft psstatus

Unfortunately, you cannot use the alternate property set psstatus to select the properties via the property parameter. Therefore, the command that appears here fails:

gwmi win32_bios -Property psstatus
Get info about screen saver

If you want to retrieve all the properties related to screen savers, you can use a wildcard asterisk screen-filter pattern. Delete the three screen saver properties and replace them with the Screen* wildcard pattern. The revised command appears here:

gwmi win32_desktop | select name, Screen*
Get service info via Get-Service cmdlet.

If you only know part of the displayName, use match method.

Get-service | where DisplayName -match "server"

you can also pipeline the result to the where-object cmdlet:

Get-service | where name -eq "bits"

You can also save the result in a variable, and then manipulate the variable:

$bitsVar=Get-service | where name -eq "bits"

$bitsVar | gm

$bitsVar.status

If you want to start or stop the bits service, use the -inputobject argument:

start-service -inputObject $bitsVar

stop-service -inputObject $bitsVar
Refereneces

 

Win32 classes: https://msdn.microsoft.com/en-us/library/aa394084(v=vs.85).aspx

Be ready for the PowerShell WMI week!!