One has to get their feet wet with WMI when it comes to managing ConfigMgr with PowerShell. How ConfigMgr uses WMI ? Not only ConfigMgr but for other products if you leverage WMI with PowerShell then understanding what are Static & Instance methods is important.
But there are lot of places where People stumble ( I did too ). Below is a question asked in Hyderabad PowerShell User Group (PSHUG) showing one of the common point of confusion.
If you are a ConfigMgr Admin then you already know that in SCCM client we have a lot many Client actions that can be triggered remotely. Below are the available SCCM Client actions (In CM 2012) :
Going back to the question, below code will work,which is triggering "Software Inventory" on a remote $machine:
One can get more info on the class SMS_Client & TriggerSchedule Method.
But why are we not able to see the method when we do the below:
Note - There are two variables $Client1 & $Client2
The answer to why the TriggerSchedule method doesn't appear when we pipe it to Get-Member is really simple, Just compare the Type of both the Objects you have at hand
So from above we deduce that those two are essentially 2 different objects so you won't find the TriggerSchedule Method on the $Client2 ;)
This becomes obvious if we think over it --> [WmiClass] type accelerator gives you the WMI Class Object back not the WMI Instance
To clarify things a bit more the Class ($Client1) is a definition of Objects and Instance (Client2) is the manifestation of the class.
In our question $Client1 is Class and $Client2 is an Instance of the class.
Now a class can have 2 type of methods :
To sum it all let's take a class having both Static and Instance method e.g Win32_Share
So the only method which is static is the Create Method and rest are Static.
Verify this is correct by getting the WMI Instances back and using the Get-Member
But there are lot of places where People stumble ( I did too ). Below is a question asked in Hyderabad PowerShell User Group (PSHUG) showing one of the common point of confusion.
If you are a ConfigMgr Admin then you already know that in SCCM client we have a lot many Client actions that can be triggered remotely. Below are the available SCCM Client actions (In CM 2012) :
Going back to the question, below code will work,which is triggering "Software Inventory" on a remote $machine:
001
002 |
$Client1 = $([WmiClass]"\\$Machine\ROOT\ccm:SMS_Client")
$Client1.TriggerSchedule("{00000000-0000-0000-0000-000000000021}") |
One can get more info on the class SMS_Client & TriggerSchedule Method.
But why are we not able to see the method when we do the below:
001
002 |
$Client2 = Get-WmiObject -ComputerName $Machine -Namespace root\ccm -Class SMS_Client
$Client2 | Get-Member -MemberType * |
Note - There are two variables $Client1 & $Client2
Before we go further would like to clarify one thing first, one can get the WMI Class Object by using the Get-WMIObject cmdlet itself with -List switch
So If I do the below..take note of the -List switch at the end:
001
|
$Client3 = Get-WmiObject -Class SMS_client -Namespace Root\CCM -ComputerName $machine -List
|
Go ahead and see for yourself that the two objects $Client1 and $Client3 are essentially the same :)
The answer to why the TriggerSchedule method doesn't appear when we pipe it to Get-Member is really simple, Just compare the Type of both the Objects you have at hand
So from above we deduce that those two are essentially 2 different objects so you won't find the TriggerSchedule Method on the $Client2 ;)
This becomes obvious if we think over it --> [WmiClass] type accelerator gives you the WMI Class Object back not the WMI Instance
Detailed Explanation
To clarify things a bit more the Class ($Client1) is a definition of Objects and Instance (Client2) is the manifestation of the class.
In our question $Client1 is Class and $Client2 is an Instance of the class.
Now a class can have 2 type of methods :
- Static Methods (only available on the class)
- Instance Methods (available on the Instances of the class)
So how do we go on getting this key piece of information, whether it is a Static method or not ?
Once you have the class object ($Client1 ) you can explore it.
So once we have the WMI Class Object we can do the below to take a look at the methods and the qualifiers:
PS> $Client1 | select -ExpandProperty methods | select name,qualifiers Name Qualifiers ---- ---------- ResetPolicy {implemented, static} RequestMachinePolicy {implemented, static} EvaluateMachinePolicy {implemented, static} TriggerSchedule {implemented, static} RepairClient {implemented, static} SetAssignedSite {implemented, static} GetAssignedSite {implemented, static} SetGlobalLoggingConfiguration {implemented, static} ResetGlobalLoggingConfiguration {implemented, static} SetClientProvisioningMode {implemented, static}Notice that all the methods on the class are static.
To sum it all let's take a class having both Static and Instance method e.g Win32_Share
PS> Get-WmiObject -Class WIn32_Share -List| select -ExpandProperty methods | select name,qualifiers Name Qualifiers ---- ---------- Create {Constructor, Implemented, MappingStrings, Static} SetShareInfo {Implemented, MappingStrings} GetAccessMask {Implemented, MappingStrings} Delete {Destructor, Implemented, MappingStrings}
So the only method which is static is the Create Method and rest are Static.
Verify this is correct by getting the WMI Instances back and using the Get-Member
PS> Get-WmiObject -Class WIn32_Share | Get-Member -MemberType method -Force TypeName: System.Management.ManagementObject#root\cimv2\Win32_Share Name MemberType Definition ---- ---------- ---------- Delete Method System.Management.ManagementBaseObject Delete() GetAccessMask Method System.Management.ManagementBaseObject GetAccessMask() SetShareInfo Method System.Management.ManagementBaseObject SetShareInfo(System.UInt32 MaximumAllowed, System.St...
Notice that the Create method doesn't show up on the WMI Instance cause it is a static method on the class :)
But it does show up on the WMI Class Object
I will be presenting a session on the next PSBUG + BITPro meet on the topic
"PowerShell + ConfigMgr - Getting Started" on 19th July, in this session will shed light on this too. The registrations haven't opened yet. So you can keep an eye on the FB group links.
But it does show up on the WMI Class Object
PS> Get-WmiObject -Class win32_Share -ComputerName $Machine -List | Get-Member -MemberType Method TypeName: System.Management.ManagementClass#ROOT\cimv2\Win32_Share Name MemberType Definition ---- ---------- ---------- Create Method System.Management.ManagementBaseObject Create(System.String Path, System.String Name, System.UInt3...
I will be presenting a session on the next PSBUG + BITPro meet on the topic
"PowerShell + ConfigMgr - Getting Started" on 19th July, in this session will shed light on this too. The registrations haven't opened yet. So you can keep an eye on the FB group links.