Today I was building a script to create system resources in SCCM 2012 and part of the task was to add these resources to a set of collections.
The script will use from the SCCM server when finally implemented but for now I was using my laptop for editing and debugging.
When I came to the point where I had to create the actual membership rules for the collections I ran into a hurdle that puzzled me.
The WMI object I had to create was the SMS_CollectionRuleDirect, which often is done using this simple PowerShell snippet:
$ruleClass = [WMICLASS]"\\$($server)\root\sms\site_$($sitecode):SMS_CollectionRuleDirect".CreateInstance()
And don’t get me wrong, it works and it is fairly short … BUT there is no way to assign any credentials to this call, which I needed when calling the server from remote.
So I looked around for a way to create this instance using some other method.
First I tried Set-WMIInstance but that resulted in an error from SCCM as Set-WMIInstance apparently contains and implicit call to Put(), and this particular object is not supposed to be Put().
After quite a lot of reading and searching I came across a blog called “Schnitzelspechts Blog” where the author was struggling with a very similar issue related to the WMI registry provider, stdregprov.
It turns out that Get-WMIObject has a switch called -List that allows you to list all classes in a namespace, so using this snippet you can list all classes in the SMS\Site_XXX namespace.
Get-WMIObject –List -Namespace Root\SMS\Site_XXX
A pretty long list by the way …
Using this I was then able to get my class object remotely using credentials as Get-WMIObject works very well with credentials.
$ruleClass = Get-WmiObject -List -ComputerName "$server" -Namespace Root\SMS\Site_"$sitecode" -Credential $cred | where-object { $_.name -eq "SMS_CollectionRuleDirect" }
yippee ki … well almost … yay … the list was pretty long so the call does take a while to finish, and I was going to create a few memberships so I tried to see if there was a way to query the class in the call to Get-WMIObject and not by using a where-object, as that would get the whole list and query into that.
My first attempt was to see if the -class argument would help me out.
$ruleClass = Get-WmiObject -List -ComputerName "$server" -Namespace Root\SMS\Site_"$sitecode" -Credential $cred –class SMS_CollectionRuleDirect
I was expecting a polite error message saying that my life was not THAT easy but no, it worked like a charm and was quite a lot faster than the previous call.
I now had my class and could continue on to call the CreateInstance method.
So for future use I might stick to using this approach as I find the [WMIClass]”\\ syntax very crude and not very readable but maybe that’s just me.
You can read Schnitzelspecht’s very helpful post here
thanks for blogging this.. I’m been stuck on this one for a few hours and this helped me a lot!
Nice work!
Nice! Many thanks!
Thank you very much, Its helped me after a couple of days struggling with
([WMIClass]”\$SiteServerrootSMSSite_$($Sitecode):SMS_CollectionRuleDirect”).CreateInstance().
Thanks once again.
Babu
Could you please share the complete script? I am getting below error.
Exception setting “ResourceClassName”: “The property ‘ResourceClassName’ cannot be found on this object. Verify that the property exists and can be set.”
Hi, I’m facing a similar issue when trying to cast a string to wmi. I’m also trying to connect to a remote wmi. Below is the code, please help if possible!
function DeleteAllQueryRules($Coll, $Server, $NameSpace)
{
#Write-Host “Deleting Collection Query Rules.”
log (“Deleting Collection Query Rules from ” + $Coll)
$strPath = (gwmi sms_collection -namespace $NameSpace -computer $server credentials – $cred | where-object { $_.CollectionID -eq $coll }).__Path
$collwmi = [wmi]$strPath
$collWMI.DeleteMembershipRules($collWMI.CollectionRules)
}
NOTE: $collwmi = [wmi]$strPath is giving an issue of access denied, any help would be welcome!
The cast from string to wmi is creating a wmi object from a path and you dont have access to that path, you got the first by supplying creds to the get-wmiobject – you need to do this every time you try to get a wmi object – so rewrite your code to use the correct syntax for a get and then you can supply your creds as required