SCCM Device Collection Membership based on Machine Variable

sccm

I'm not sure if this is quite possible but I'm struggling with writing the WQL query statement that would allow me to have SCCM device collections populate based on a machine variable.

Example:
Device named "TestVM-01" has a machine variable named "PatchGroup" with a value of "Hour1".
I would like the device collection called "Hour1" to dynamically populate any devices with the PatchGroup variable set to Hour1.

I first struggled with just querying the device variables via powershell and WMI since the SMS_MachineVarible class is a lazy property of SMS_MachineSettings so you have to call the objects by their full path.

In Powershell/WMI I can query it with something like this

(([wmi]"\\SCCM-LAB\root\sms\site_001:SMS_Machinesettings.ResourceID=11111111").machinevariables | where name -eq "PatchGroup").value

If you query SMS_MachineSettings without specifying the full path of the object, it will return the MachineVariables attribute as empty

Would anyone be able to tell me how I would write the WQL for that to pull those list of objects from the SMS_Resource class "where PatchGroup = x"?

Best Answer

A single WMI Query will not work on this, neither do the default 'Create Device Collection Wizard'. The lazy Properties is a list of another object instances' properties and values, we need to use SwbemServices.ExecQuery() COM interface in VBscript & PowerShell, or Get-WmiObject in PowerShell to pulling data.

I would do this using, like PowerShell Script, to generate a list of computer ResourceIDs and using these IDs to create a DirectRule collection using built-in CM cmdlet. Each time I will run the script before I'm going to use this collection.

See below script blocks to get list of ResourceIDs:

$cmdletLocaltion = 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
$sitecode = 'P01:'
Import-Module $cmdletLocaltion
cd $sitecode
#-Lines to cleanup all the directcollection membership rules -#
$machineObject = Get-WmiObject -Namespace root\sms\site_p01 -Class sms_machinesettings
Foreach ($machine in $machineObject)
    {
        $Path = $machine.__PATH
        $machine = [wmi]"$path"
        foreach ($varvalue in $machine.MachineVariables)
            {
                if (($varvalue.name -eq 'PatchGroup') -and ($varvalue.Value -eq 'Hour1'))
                    {
                        $machine.ResourceID
                #--line here to add to collection membership--#
                    }
            }    
    }