Configuration Manager and Powershell

Hello,

This is my first blog post so I thought I would make it something vaguely interesting (to certain people).  Powershell has been around for a while, though for most ConfigMgr people it remains a dark area.  This is primarily due to the lack of samples explaining how to access the ConfigMgr WMI Provider on a Site Server.  This post will walk you through the ConfigMgr SDK sample in VBScript and show a corresponding sample in Powershell. 

I’ve written up the following sample to walk you through the process of converting the ‘How to Create a Static  Collection’ sample in the SDK from C# or VBscript to Powershell.  The sample is designed to work locally on the site server with a site code of LAB, but establishing a connection to a remote provider should not prove too difficult.  We are using some of the .NET System.Management classes directly to give us direct access to WMI.  This makes things easier to maps back to C#/VBScript samples in the SDK.

The first thing we need to do, is instantiate an instance of the SMS_Collection class.

$collClass = [WMIClass] “root\SMS\Site_LAB:SMS_Collection”
$collInstance = $collClass.CreateInstance()

With that done, we can populate all settings required for our collection.

$collInstance.Name = “FooCollection1”
$collInstance.OwnedByThisSite = $true

You may want to set additional properties for this collection. From there, we store our instance of the SMS_Collection class, and use the returned object to tell us the path of the new instance. We will need this later on. To properly handle the Path property we need to cast the type of object returned using [WMI].

$collPath = $collInstance.Put()
$collection = [WMI] $collPath.Path

We now follow the same instantiation process used above to create an instance of SMS_CollectToSubCollect class. The SMS_CollectToSubCollect class is required to tie our new collection to an existing collection so that is actually shows up in the console. This can be any existing collection’s ID or the special ID of COLLROOT to appear under the ‘Collections’ node. In our case, we are using COLLROOT for simplicities sake.

$subcollClass = [WMIClass] “root\SMS\Site_LAB:SMS_CollectToSubCollect”
$subcollInstance = $subcollClass.CreateInstance()

So we set our relationship class (SMS_CollectToSubCollect) parentCollectionID property to COLLROOT. Again, this could be any existing collection ID.

      $subcollInstance.parentCollectionID = “COLLROOT”

We now need to link our relationship class’s subCollectionID property to our new collection’s ID. Since this is assigned by the provider based on existing collection IDs, we much reference it using the new collection’s object’s CollectionID property and store the new instance of SMS_CollectToSubCollect, as such:

$subcollInstance.subCollectionID = $collection.CollectionID
$subcollection = $subcollInstance.Put()

Now that we have a new collection linked to the ‘Collections’ root node, we ought to put something in there, so let’s create a direct membership rule for a computer called ‘Test’. We follow the same WMI connection process using the [WMIClass] cast and then instantiate SMS_CollectionRuleDirect. We also set the ResourceClassName property to “SMS_R_System” to let ConfigMgr know that we want to find System resources.

$directruleClass = [WMIClass] “root\SMS\Site_LAB:SMS_CollectionRuleDirect”
$directruleInstance = $directruleClass.CreateInstance()$directruleInstance.ResourceClassName = “SMS_R_System”

With that done, we can use the Powershell Get-WmiObject commandlet to find the ‘Test’ computer. As you may have noticed, this is the first time we are going to be using a commandlet in our PowerShell script. Anyway, we are going to assume that we only have one instance returned (meaning that there is only one computer object (System resource instance) in the database). In reality there may be multiple objects with similar names, so you will want to either filter them more or use a foreach loop (foreach-object commandlet) to walk through the collection of returned computer objects.

$computer = Get-WmiObject –class “SMS_R_System” – namespace “root\SMS\Site_LAB” –Filter “NetbiosName = ‘Test’”

All we need to do is link the ResourceID property in the found computer object with the rule object’s ResourceID property, as such:

$directruleInstance.ResourceID = $computer.ResourceId

Then, we call the AddMembershipRule method from our new collection, and tie it to the new Direct Memebership rule instance we created just now.

$collection.AddMembershipRule($directruleInstance)

Finally, we call the RequestRefresh method to ask Collection Evaluator in the site to update the collection membership for our new collection and that it!

$collection.RequestRefresh()

Assuming I haven’t bored you to death with my comments so far, this is what you should have in the end:

$collClass = [WMIClass] “root\SMS\Site_LAB:SMS_Collection”
$collInstance = $collClass.CreateInstance()
$collInstance.Name = “FooCollection1”
$collInstance.OwnedByThisSite = $true
$collPath = $collInstance.Put()
$collection = [WMI] $collPath.Path
$subcollClass = [WMIClass] “root\SMS\Site_LAB:SMS_CollectToSubCollect”
$subcollInstance = $subcollClass.CreateInstance()
$subcollInstance.parentCollectionID = “COLLROOT”
$subcollInstance.subCollectionID = $collection.CollectionID
$subcollection = $subcollInstance.Put()
$directruleClass = [WMIClass] “root\SMS\Site_LAB:SMS_CollectionRuleDirect”
$directruleInstance = $directruleClass.CreateInstance()
$directruleInstance.ResourceClassName = “SMS_R_System”
$computer = Get-WmiObject –class “SMS_R_System” – namespace “root\SMS\Site_LAB” –Filter “NetbiosName = ‘Test’”
$directruleInstance.ResourceID = $computer.ResourceId
$collection.AddMembershipRule($directruleInstance)
$collection.RequestRefresh()

Hopefully, the above sample will be useful in letting you understand how you can use PowerShell with ConfigMgr’s WMI Provider.  If this has been helpful to you, please let me know by commenting below.