This is in continuation of my last post on Using PowerShell to get client information
In this post will be exploring on the ways to do the same thing using WMI/CIM, Why ?
With WQL syntax we can ask for only the properties we need rather than getting everything back.
The post will cover 3 topics:
Most of the properties returned back may be empty depending on how you are using ConfigMgr e.g if you use endpoint protection than those attributes in the class will be populated else will be empty.
Now if you see the output of Get-CMDevice is actually is a result of the SMS_CombinedDeviceResources
Let me tell you a little secret :-$ ...if you are looking forward to explore WMI part of ConfigMgr and have a doubt on which Class to look for, then piping the output of the Cmdlets with the ConfigurationManager Module to Get-Member gives you a hint.
The cmdlets shipped with (written in C#) the Module essentially makes WMI calls and then expose the results back to us that's why IResultObject in the Typename (above screenshot) :-B
So let's explore a bit the SMS_CombinedDeviceResources class...using the Get-CIMClass cmdlet.
Note - will be using the $PSDefaultParameters as mentioned in my earlier posts to set the Computername and Namespace parameter to point to the ConfigMgr Server.
We can see a lot of properties defined in this class:
To get this information for a client can be a simple WMI call where you specify a filter for the Name property like below:
But the good thing about using the WMI/ CIM cmdlets directly is that we can use the WQL query to select only the properties we want (see below):
Note that all the extra properties show up as blank (other than those specified with Select statement), this will save the network bandwidth and will be efficient when we are processing say hundreds or thousands of clients.
Now out of all the properties listed the one which stands aside is the property named 'MemberClassName'. If you query this Class mentioned in the property MemberClassName then you get back all the members of the collection..I think you figured that out already ;)
Below is the value of the property MemberClassName for my "All Systems" collection
SMS_CM_RES_COLL_SMS00001
So let's do a WMI Call for this class:
You can see it got all the machines which were member of the 'All Systems' Collection
Now using the WQL query to optimize this a bit :
In this post will be exploring on the ways to do the same thing using WMI/CIM, Why ?
With WQL syntax we can ask for only the properties we need rather than getting everything back.
The post will cover 3 topics:
- Query individual Device in CM using WMI/CIM
- Query Members of a Device Collection using WMI/CIM
- Query Users in a User Collection using WMI/CIM
Most of the properties returned back may be empty depending on how you are using ConfigMgr e.g if you use endpoint protection than those attributes in the class will be populated else will be empty.
Now if you see the output of Get-CMDevice is actually is a result of the SMS_CombinedDeviceResources
Let me tell you a little secret :-$ ...if you are looking forward to explore WMI part of ConfigMgr and have a doubt on which Class to look for, then piping the output of the Cmdlets with the ConfigurationManager Module to Get-Member gives you a hint.
The cmdlets shipped with (written in C#) the Module essentially makes WMI calls and then expose the results back to us that's why IResultObject in the Typename (above screenshot) :-B
So let's explore a bit the SMS_CombinedDeviceResources class...using the Get-CIMClass cmdlet.
Note - will be using the $PSDefaultParameters as mentioned in my earlier posts to set the Computername and Namespace parameter to point to the ConfigMgr Server.
We can see a lot of properties defined in this class:
Query individual Device using WMI/CIM
To get this information for a client can be a simple WMI call where you specify a filter for the Name property like below:
Get-CimInstance -ClassName SMS_CombinedDeviceResources -Filter 'Name="DEXTERDC"'
But the good thing about using the WMI/ CIM cmdlets directly is that we can use the WQL query to select only the properties we want (see below):
Get-CimInstance -Query "Select Name,LastMPServerName,deviceos from SMS_CombinedDeviceResources where Name='DexterDC'"
Note that all the extra properties show up as blank (other than those specified with Select statement), this will save the network bandwidth and will be efficient when we are processing say hundreds or thousands of clients.
Query Members of a Device Collection using WMI/CIM
If you have read few of my earlier posts then you would know that all the collections we create are an instance of the class SMS_Collection. So let's go ahead and do a WMI query to get the object back for the "All Systems" collection.Get-CimInstance -ClassName SMS_Collection -Filter 'Name="All Systems"'
Now out of all the properties listed the one which stands aside is the property named 'MemberClassName'. If you query this Class mentioned in the property MemberClassName then you get back all the members of the collection..I think you figured that out already ;)
Below is the value of the property MemberClassName for my "All Systems" collection
PS> (Get-CimInstance -ClassName SMS_Collection -Filter 'Name="All Systems"').MemberClassName
SMS_CM_RES_COLL_SMS00001
So let's do a WMI Call for this class:
You can see it got all the machines which were member of the 'All Systems' Collection
Now using the WQL query to optimize this a bit :
Get-CimInstance -query 'Select Name,IsClient,LastMPServerName,DeviceOS from SMS_CM_RES_COLL_SMS00001' | select -Property Name,IsClient,LastMPServerName,DeviceOS
I pipe it to the Select-Object cmdlet to get the properties I wanted as rest every property is empty.
To give an idea on the efficiency part see below:
This is pretty explanatory right ! This would be pretty significant difference if there are a lot of members in the Collection.
Well the difference is in the type of collection:
Get-CimInstance -ClassName (Get-CimInstance -ClassName SMS_Collection -Filter 'Name="All Users"').MemberClassName |
Select Name,SMSID
To give an idea on the efficiency part see below:
PS> Measure-Command { Get-CMDeployment -CollectionName 'All Systems'} Days : 0 Hours : 0 Minutes : 0 Seconds : 1 Milliseconds : 55 Ticks : 10554314 TotalDays : 1.22156412037037E-05 TotalHours : 0.000293175388888889 TotalMinutes : 0.0175905233333333 TotalSeconds : 1.0554314 TotalMilliseconds : 1055.4314 PS> Measure-Command {Get-CimInstance -query 'Select Name,IsClient,LastMPServerName,DeviceOS from SMS_CM_RES_COLL_SMS000 01' } Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 173 Ticks : 1738179 TotalDays : 2.01178125E-06 TotalHours : 4.828275E-05 TotalMinutes : 0.002896965 TotalSeconds : 0.1738179 TotalMilliseconds : 173.8179
This is pretty explanatory right ! This would be pretty significant difference if there are a lot of members in the Collection.
Query Users in a User Collection using WMI/CIM
Now there are User Collections too so how do we query the members in it. Well easy the same way we did it with Device Collections. :PWell the difference is in the type of collection:
PS> (Get-CimInstance -ClassName SMS_Collection -Filter 'Name="All Systems"').CollectionType 2 PS> (Get-CimInstance -ClassName SMS_Collection -Filter 'Name="All Users"').CollectionType 1So if we wanted to get the members of the collection "All Users" then below is a one liner to do that:
Get-CimInstance -ClassName (Get-CimInstance -ClassName SMS_Collection -Filter 'Name="All Users"').MemberClassName |
Select Name,SMSID
You can see the Class to which a User in CM belongs is SMS_CombinedUserResources which has few properties defined in it.
[UPDATE} I was writing a function which will do all of the above things shown for me..there is a switch by the name $PropertySelect (also when I tried using $SelectProperty it gave me an error saying that 'The parameter name "SelectProperty" is reserved for future use.' ) which will give an option to select properties in Out-Gridview Window and these properties will only be retrieved ..pretty cool B-)
That's it for today's post. :) :)
That's it for today's post. :) :)