There are a lot of examples out there if you need to interact with ConfigMgr via WMI but I found that there is very little information on how to use CIM
commandlets instead of WMI. The advantage of using CIM over WMI is that it
works on .Net core and Powershell 7.x. It also uses WinRM for remote operations
rather than WMI’s DCOM.
If you just want a script with some ready to use
functions I have one here:
Invoke-CMCimFunctions.ps1
But if you want some explanation, read on and I will do my best to explain.
Here I will show you how to add and remove a direct member to a ConfigMgr
Collection. First, we need to get the ResourceID from a computername.
$CMComputer
= Get-CimInstance -ComputerName CM01.corp.mblab.org -Namespace
"ROOT\SMS\Site_PS1" -ClassName "SMS_R_System" -Filter
"Name = 'COMPUTER01'"
$CMComputer.ResourceId
Pretty straight forward, not much different than using Get-WMIObject.
Then retrieve the Collection object:
$Collection
= Get-CimInstance -ComputerName CM01.corp.mblab.org -Namespace
"ROOT\SMS\Site_PS1" -ClassName "SMS_Collection" -Filter
"CollectionID = 'PS100015'"
Let see what methods there are available, wait what? This doesn’t look right..
When comparing to the Get-wmiobject you can clearly see that there are some methods missing from the Get-Members on the CIM-object.
The methods on the CIM object above are in fact the methods of the ciminstance rather then the methods of the object/instance itself. To get the methods of the actual object we need to use CimClass.CimClassMethods
$Collection.CimClass.CimClassMethods
|Where-Object { -not $_.Qualifiers['Static'] }
This is what we are looking for!
Looking at the available methods above there is one called "AddMembershipRule" and one called "DeleteMembershipRule", these are the ones we need.
In the collection there is already one computer added as a direct member.
But when the $Collection object is inspected, there are no CollectionRules.
The CollectionRules property isn't loaded unless requested. To request it
the Select-object command with ExpandProperty needs to be invoked.
[ciminstance[]]$collRules
= Get-CimInstance -InputObject $Collection | Select-Object -ExpandProperty CollectionRule
The CimClass is of type "SMS_CollectionRuleDirect" which means this rule is a Direct membership rule.
Delete a Direct Member from a collection
In this example there is already a direct member in the collection that has been added from the console.
To remove the computer by using Invoke-CimMethod use the following code:
Foreach
($rule in $collRules) {
# Only check for Direct Members
If ($rule.CimClass.CimClassName -eq "SMS_CollectionRuleDirect") {
If($rule.ResourceID -eq
"16777225")
{
$params = @{ collectionRule = $rule
}
Invoke-CimMethod -InputObject $Collection
-MethodName DeleteMembershipRule -Arguments $params
}
}
}
Using the CimClassMethods we previous learnt that the DeleteMembershipRule took "collectionRule" as input. This is done by creating $params = @{ collectionRule = $rule } which then is used as an argument to Invoke-CimMethod.
If
successful the Invoke-CimMethod will return ReturnValue = 0
Adding a Direct member to collection
To add a new rule the collectionrule must be created manually first.
$null =
New-CimInstance -Namespace "ROOT\SMS\Site_PS1" -OutVariable
collectionRule -ClassName SMS_CollectionRuleDirect -ClientOnly -Property @{
ResourceClassName =
[string]"SMS_R_System"
RuleName = [string]"COMPUTER01"
ResourceID = [uint32]16777225
}
If you create a direct rule via the console the RuleName is always the same as the computer name, but when creating via script the name can be set to anything so make sure to set it to something useful.
Using the New-CimInstance command above we have specified an OutVariable as "collectionRule" this will create a new PowerShell variable with the properties we have set. To add multiple rules to the same variable add a "+" before the variable name (ie -OutVariable +collectionRule). Just make sure if you planning to add multiple rules at the same time to use the "AddMemberShipRules" instead of "AddMemberShipRule". The "ClientOnly" parameter creates the new object without checking that the Namespace and Class exists. This is needed when operating on a remote system that doesn't have the SMS classes in WMI.
New collection rule.
Then add the new rule to the collection using Invoke-CimMethod:
Invoke-CimMethod
-InputObject $Collection -MethodName AddMemberShipRule -Arguments @{
CollectionRule = [CimInstance]$collectionRule[0] }
Once
again, ReturnValue = 0 means success.
Hope this helps someone trying to use Cim-Methods with Configuration
Manager!
/Matt
Principal Engineer
Twitter @matbe