Hey, Scripting Guy! Using the Get-Member cmdlet with Windows PowerShell is pretty cool, but the one thing I do not like is the way that Windows PowerShell hides stuff from me. When I look in MSDN for information about a WMI class, I see all of these methods listed. When I use the Get-Member cmdlet, some of the methods are not listed. So it seems that the WMI implementation in Windows PowerShell is incomplete. If this is the case, how can I find out where this stuff is documented? I would like to see a list of all the things I can do with Windows PowerShell and WMI.
— DF
Hello DF,
You already have the documentation. It is called (drumroll please) MSDN. All of the information about our products can be found in the reference documentation on MSDN. You may also want to check out some of the various team blogs as well. There are two things you need to know about Windows Management Instrumentation (WMI). The first is that the WMI team does not write all the WMI classes. They develop the core technology, and the various teams at Microsoft create their own WMI providers and write their own WMI classes. When you go to the WMI documentation (the software development kit [SDK] on MSDN), you only find information about the WMI core classes. For example, if you want to find out about the WMI classes for Hyper-V, you will find the documentation under virtualization—not under WMI.
But when you talk about hidden WMI class methods, you are not talking about hidden WMI documentation. You are talking about the way the information is supplied via the Get-Member cmdlet. Let’s take a common scenario: the Win32_Process cmdlet. This important WMI class has been written about by Microsoft Scripting Guys numerous times, and therefore our loyal informed readers know the things this class can do. It is also documented on MSDN with the WMI core classes. As seen in Table 1, the Win32_Process WMI class exposes 6 methods.
Table 1 Methods of the Win32_Process class
Method |
Description |
AttachDebugger |
Launches the currently registered debugger for a process. |
Create |
Creates a new process. |
GetOwner |
Retrieves the user name and domain name under which the process is running. |
GetOwnerSid |
Retrieves the security identifier (SID) for the owner of a process. |
SetPriority |
Changes the execution priority of a process. |
Terminate |
Terminates a process and all of its threads. |
When you use the Get-Member cmdlet to examine the methods of the Win32_Process WMI class, you see only five methods that are returned. As seen here, the Create method is missing:
PS C:> Get-WmiObject -Class win32_process | Get-Member -MemberType method
TypeName: System.Management.ManagementObject#rootcimv2Win32_Process
Name MemberType Definition
—- ———- ———-
AttachDebugger Method System.Management.ManagementBaseObject AttachDebug…
GetOwner Method System.Management.ManagementBaseObject GetOwner()
GetOwnerSid Method System.Management.ManagementBaseObject GetOwnerSid()
SetPriority Method System.Management.ManagementBaseObject SetPriority…
Terminate Method System.Management.ManagementBaseObject Terminate(S…
A clue can be obtained by using the Method Editor from the Windows Management Instrumentation Tester (WbemTest). For more information about using WbemTest, refer to yesterday’s Hey, Scripting Guy! article.
As seen in the following image, the Create method has the Static qualifier.
Armed with the fact that the Create method is a static method from the Win32_Process WMI class, you might be tempted to once again return to the Get-Member cmdlet, this time to retrieve static methods. To retrieve static methods, you use the MemberType parameter and choose methods and the static switch. This is seen here:
PS C:> Get-WmiObject -Class win32_process | Get-Member -MemberType method -Stat
ic
TypeName: System.Management.ManagementObject
Name MemberType Definition
—- ———- ———-
Equals Method static bool Equals(System.Object objA, System.Obj…
ReferenceEquals Method static bool ReferenceEquals(System.Object objA, S…
Unfortunately, the two static methods that are returned by the Get-Member cmdlet do not solve our problem. In fact the two static methods that are returned by Get-Member do not even appear in the MSDN documentation for the Win32_Process WMI class (this is because they are inherited from the System.Object .NET Framework class).
What have we discovered so far? We have seen that the WbemTest utility states that the Create method from the Win32_Process WMI class is a static method. We have also seen that the Get-Member cmdlet did not appear to find the Create method. The reason that the Get-Member cmdlet did not find the Create method is that the Get-WmiObject cmdlet returns instances of Win32_Processes. This is seen here:
PS C:> Get-WmiObject -Class win32_process | Select-Object -Property name
name
—-
System Idle Process
System
smss.exe
csrss.exe
wininit.exe
csrss.exe
winlogon.exe
services.exe
lsass.exe
lsm.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
SLsvc.exe
svchost.exe
svchost.exe
svchost.exe
spoolsv.exe
svchost.exe
vmsrvc.exe
inetinfo.exe
svchost.exe
vpcmap.exe
taskeng.exe
SearchIndexer.exe
taskeng.exe
dwm.exe
explorer.exe
vmusrvc.exe
SnagIt32.exe
TscHelp.exe
SnagPriv.exe
SnagItEditor.exe
powershell.exe
WmiPrvSE.exe
Each of the objects that are returned by the Get-WmiObject cmdlet is an instance of a Win32_Process WMI class. It makes sense that an instance of a WMI class cannot be used to create an instance of a class. We need to move up one step in the WMI hierarchy. We need to move to the class itself, not to an instance of the class. This process is true, whether you are using the Get-WmiObject cmdlet from Windows PowerShell, or whether you are using the GetObject method from VBScript. To try to keep things in perspective, you can think of using the Get-WmiObject cmdlet in a similar fashion to the way you used the ExecQuery method from within VBScript. You can certainly use the ExecQuery method from VBScript to return a collection of processes that match the name “Notepad” and you can certainly call the terminate method to stop such a process. This process makes sense because you are working with an instance of the Win32_Process class. You want to terminate an instance of the class. Terminating a process named “Notepad” can be as easy as using a WMI query that retrieves a single instance of the class and calling the terminate method. If the query returns more than one instance of the Win32_Process class, you will need to use the Foreach-Object cmdlet to walk through the collection. This is seen here:
PS C:> (Get-WmiObject -Class win32_process -Filter “name = ‘notepad.exe'”).Term
inate()
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 1
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ReturnValue : 0
All this might make you wonder where the hidden WMI methods are. The key to finding the hidden WMI methods is understanding if the method is an instance method or if it is a static WMI method. If the method is an instance method, it is available directly from within using the Get-WmiObject, in the same way the methods were available from VBScript using the ExecQuery method. The method operates on an instance of the WMI class. If the method is a static WMI method, you will need to use the [wmiclass] type accelerator. This is similar to the way you had to use a different syntax in VBScript to call the class methods. In Windows PowerShell, you use the [wmiclass] type accelerator to retrieve the WMI class—not an instance of the class. To retrieve the class, you use [wmiclass] and the WMI class name. This is seen here:
PS C:> [wmiclass]”Win32_process”
NameSpace: ROOTcimv2
Name Methods Properties
—- ——- ———-
Win32_Process {Create, Terminat… {Caption, CommandLi…
You can think of it as casting a string into a WMI class, or you can think of it as a type accelerator because it makes it easy to get access to the WMI class. After you have the WMI class, you can send it to Get-Member as seen here:
PS C:> [wmiclass]”Win32_process” | Get-Member
TypeName: System.Management.ManagementClass#ROOTcimv2Win32_Process
Name MemberType Definition
—- ———- ———-
Name AliasProperty Name = __Class
Create Method System.Management.ManagementBaseObject Cre…
__CLASS Property System.String __CLASS {get;set;}
__DERIVATION Property System.String[] __DERIVATION {get;set;}
__DYNASTY Property System.String __DYNASTY {get;set;}
__GENUS Property System.Int32 __GENUS {get;set;}
__NAMESPACE Property System.String __NAMESPACE {get;set;}
__PATH Property System.String __PATH {get;set;}
__PROPERTY_COUNT Property System.Int32 __PROPERTY_COUNT {get;set;}
__RELPATH Property System.String __RELPATH {get;set;}
__SERVER Property System.String __SERVER {get;set;}
__SUPERCLASS Property System.String __SUPERCLASS {get;set;}
ConvertFromDateTime ScriptMethod System.Object ConvertFromDateTime();
ConvertToDateTime ScriptMethod System.Object ConvertToDateTime();
The only WMI method that is seen is the Create method. The remaining properties are all system properties. There are two scriptMethods that were added by Windows PowerShell team to the object. To use the create method, you can call the method directly from the class as seen here:
PS C:> ([wmiclass]”Win32_process”).Create(“notepad”)
__GENUS : 2
__CLASS
0 comments