Type Accelerators: A Useful But Undocumented Feature in PowerShell 1.0
A look at the [wmi], [wmiclass], and [wmisearcher] type accelerators
March 18, 2009
If you never heard of the [wmi], [wmiclass], and [wmisearcher] type accelerators, you're not alone. The online documentation that comes with Windows PowerShell doesn't mention them. And if you search the Microsoft website, you'll find references to them in some "Hey, Scripting Guy!" columns and in a few blogs, but that's it.
So what are type accelerators and why should you care about them? As you probably know, PowerShell uses the Windows .NET Framework, which is why the .NET Framework is required to install PowerShell. Type accelerators let you more easily access .NET classes in PowerShell code. In the case of the [wmi], [wmiclass], and [wmisearcher] type accelerators, you can more easily access several classes in the .NET Framework's System.Management namespace, which is used by Windows Management Instrumentation (WMI). Other type accelerators let you access different .NET namespaces and their classes. (To learn more, see the box "More Types of Type Accelerators.") Because you can more easily access the .NET classes, you can sometimes reduce the amount of code you need to type. But perhaps more important, you can easily gain access to the .NET classes' properties and methods, some of which aren't accessible through PowerShell's Get-WmiObject cmdlet.
The [wmi] Type Accelerator
The [wmi] type accelerator provides a way to more easily access the ManagementObject class, which represents a WMI object. You provide a path to a specific WMI object and the [wmi] type accelerator returns that object. You can use this type accelerator instead of using the Get-WmiObject cmdlet with the -filter parameter. For example, suppose you want to access the object representing Task Scheduler on your computer. Using the Get-WmiObject cmdlet, you can run the statement
Get-WmiObject -class Win32_Service –filter "name='Schedule'"
Using the [wmi] type accelerator, you'd run
[wmi] 'Win32_Service.Name="Schedule"'
Figure 1 shows the results of both statements.
Figure 1: Results of the Get-WmiObject and [wmi] statements |
As you can see, you get the same information with either statement, but the [wmi] type accelerator statement requires less typing (albeit not much, especially if you use an alias for the Get-WmiObject cmdlet).
If you want to quickly find information not in the default display, you can use a statement such as
([wmi] 'Win32_Service.Name="Schedule"').description
As with most good things, there is a caveat. To use the [wmi] type accelerator, you need to know the exact path to the object, which the __PATH property contains. You can customize and use the following code to find a path for a WMI object in the rootcimv2 namespace:
$colItems = Get-WmiObject -class "" | sort "Name"foreach ($objItem in $colItems) {Write-Host $objItem.Name, $objItem.__Path}
In this code, you need to replace with the name of the class that contains the WMI object you're seeking. (Don't include the angle brackets when you specify the class.)
This path-finding code returns the name and path for all the WMI objects in the specified class, so you'll need to search through the names to find the object of interest. Next to the name will be the path. The part of the path you need to use with the [wmi] type accelerator appears after the colon.
For example, if you want to find a path for the WMI object representing the Spooler service in the Win32_Service class, you'd run the code
$colItems = Get-WmiObject -class "Win32_Service" | sort "Name"foreach ($objItem in $colItems) {Write-Host $objItem.Name, $objItem.__Path}
In the output, you'll find the entry
Spooler \rootcimv2:Win32_Service.Name="Spooler"
where is your computer's name. In this case, the part of the path you'd use with the [wmi] type accelerator is Win32_Service.Name="Spooler".
Checking the path is important because it's not always the object's name like in these examples. For instance, if you assume that the path for a WMI object representing an Internet Explorer (IE) process is Win32_Process.Name="iexplore.exe" and you run the statement
[wmi] 'Win32_Process.Name="iexplore.exe"'
you'll get an error message. WMI object paths use an object's key property. A key property is one that uniquely identifies an instance. Because all services must have unique names, the Name property is the key property of the Win32_Service class. However, that's not the case with the Win32_Process class because you can be running multiple instances of a process. If you run the path-finding code
$colItems = Get-WmiObject -class "Win32_Process" | sort "Name"foreach ($objItem in $colItems) {Write-Host $objItem.Name, $objItem.__Path}
you'll find that the key property for the Win32_Process class is the Handle property, which is the same as the process ID. Process IDs can change often, so you need to obtain the path each time you want to access a Win32_Process object.
After you find the Handle property value of the process you want, you can retrieve information about that process with the statement
[wmi] 'Win32_Process.Handle=""'
where is that value. (Don't include the angle brackets.) Process IDs can be anywhere from one to four digits long. Note that you can type even less by specifying only the key property's value. For example, the code
[wmi] 'Win32_Process=""'
will return the same results as the previous statement. If you decide to terminate that process, you can then run code such as
([wmi] 'Win32_Process=""').Terminate()
The [wmiclass] Type Accelerator
The [wmiclass] type accelerator provides a way to more easily access the ManagementClass class, which represents the WMI classes for managing Windows-based OSs (e.g., Win32_Process, Win32_Service, Win32_LogicalDisk). Like the Get-WmiObject cmdlet, the [wmiclass] type accelerator lets you work with existing WMI classes. Unlike the Get-WmiObject cmdlet, the [wmiclass] type accelerator lets you create a new instance of a WMI class because you're accessing the class's static methods (i.e., methods not bound to an object but rather provided by the class itself).
For example, the code
([wmiclass]'Win32_Process').create("cmd.exe")
uses the [wmiclass] type accelerator to access the Win32_Process class, then uses that class's Create method to create a new cmd.exe process. In "Use PowerShell to Execute Commands on Remote Machines," James Lim expands on this technique. He uses the [wmiclass] type accelerator to access the Win32_Process class, then uses the class's Create method to create a new cmd.exe process to run an ipconfig command.
The [wmisearcher] Type Accelerator
The [wmisearcher] type accelerator provides a way to more easily access the ManagementObjectSearcher class, which represents a collection of WMI objects retrieved from a query. When you use this type accelerator, you specify the WMI Query Language (WQL) query you want to run and you use the ManagementObjectSearcher class's Get() method to access the collection returned from that query. For example, the statement
([wmisearcher] "select * from win32_service where state='stopped'").get()
returns a collection that contains information about the Win32 services that are stopped. You can get the same results if you use the Get-WmiObject cmdlet with the -query parameter, as in
Get-WmiObject -query "select * from win32_service where state='stopped'"
As you can see, the statements are about the same length, so the [wmisearcher] type accelerator doesn't seem to reduce amount of typing involved. However, it lets you access the EnumerationOptions class's ReturnImmediately and Timeout properties (accessed though the ManagementObjectSearcher class's Options property), which you can use to help solve problems with queries that time out. For more information about using the ReturnImmediately and Timeout properties with the [wmisearcher] type accelerator, see the "Dealing with WMI Timeouts" Get-ChildItem $Blog posted on January 26.
Further Exploring the WMI Type Accelerators
I've provided only a quick introduction to the world of the WMI type accelerators. If you'd like to further explore these type accelerators, check out the following:
Section 3 of the "Mastering PowerShell in your Lunch Break" PowerShell Live blog. This blog is one of the most in-depth discussions I found on the [wmi] type accelerator. It also briefly discusses the [wmiclass] and [wmisearcher] type accelerators. This blog is being retired, so you might want to look at it sooner rather than later.
Richard Siddaway's blogs "[WMI]" and "WMI Objects" explain and give examples of the [wmi] and [wmiclass] type accelerators. "WMI Objects" includes an excellent discussion about the difference between using the [wmiclasses] type accelerator and the Get-WmiObject cmdlet.
Sapien Press has a sample of the book Windows PowerShell v1.0: TFM, 2nd Edition by Don Jones and Jeffrey Hicks available as a PDF file for public viewing. The sample includes short discussions and examples of the [wmi] and [wmisearcher] type accelerators. You'll find this information on pages 35-38 in the PDF file.
The Windows PowerShell Blog "Improved Support for WMI" briefly discusses the [wmi], [wmisearcher], and [wmiclass] type accelerators. Although not too much information is provided, it's written by Jeffrey Snover, Windows PowerShell architect.
Under the Stairs blogs "PowerShell's [WMI] Type Accelerator" and "WMI, PowerShell and PowerShell's WMI Type Accelerators" are helpful in understanding the basic concepts and provide examples of the [wmi] type accelerator.
In addition, the Learning Path at the top of the page provides some resources that provide code snippets containing WMI type accelerators.
About the Author
You May Also Like