Skip to main content

SCCM 2007 + PowerShell -- Final Post

This is the last post on the SCCM 2007 + Automation Series in this blog.
I will share the Script with which I was able to achieve automation of the Query Based Deployments.


Finally using this Script I can Add machine names to the Query Membership Rule in a Collection...thus freeing myself of the GUI clicks needed in ConfigMgr Console.

So I have a test collection by the name "Deepak test 1" and what I have done is removed all the Query Rules from it to show how the Script works.
So Initially the collection has no Query membership rules, as evident from below screenshot of the Collection Properties in the ConfigMgr07 console:




And below is a count of no of members inside the collection...No members



I will be using the SCCM-Commands PowerShell module for my Script , I did cover some parts of it in previous post

So I will describe the logic quickly.....I have a Function named Add-MachineToSCCMQueryRule which is the Function which will add specified machine name to the Collection (Need to Input Collection ID).

To not screw up exisiting Query MemberShip Rules on a Collection..the function creates a new Query Rule by the name "Dexter_TEST_QueryRule" (you can change that inside the Source).
Note that the above Query Rule is created only the first time and subsequent times the machine names are added to this Query Rule.


So once we have the Query Rule in place...then we get do some text manipulation add the machine name to the Query Expression .

To update the query we have to delete the Old Query Rule and Add the new updated one.....There is not method to updated the QueryRule (only add & remove operations).

The code is very self explanatory and available for download from the Technet Repository

Apart from adding the computernames to the collection Query Rule the Script will refresh the machine  policy at the end and check if necessary SMS related services are working on the client.....and try to fix them.



The Query Expression on the Query Rule is of the below format at the beginning (Notice the "null")...You can change that in the Source:
'select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.NetbiosName in ("null")'

The machine names are appended to it at the end. So if machine name "server01" is added to the Query Expression then it would change to:
'select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where SMS_R_System.NetbiosName in ("null","server01")'

So after getting the function loaded into my session (by dot sourcing) in PowerShell...Below is how you use it
PS C:\> Add-MachineToSCCMQueryRule -SCCMServer sdwpsms012 -CollectionId DEX123BD -computername Win7Test01,Win7Test02 -Verbose
VERBOSE: Add-MachineToSCCMQueryRule: Starting the function
VERBOSE: Add-MachineToSCCMQueryRule: Module SCCM-Commands already imported
VERBOSE: Add-MachineToSCCMQueryRule: Successfully connected to the SCCM server
VERBOSE: WMI Query: SELECT * FROM SMS_Collection WHERE CollectionID='DEX123BD'
VERBOSE: Add-MachineToSCCMQueryRule: Queried the Collection Deepak Test 1 with CollectionId : DEX123BD  successfully
VERBOSE: Collecting rules for DEX123BD
VERBOSE: Add-MachineToSCCMQueryRule: Queried the QueryRules on the Collection successfully
VERBOSE: Add-MachineToSCCMQueryRule: Dexter_TEST_QueryRule not found for this collection..creating one
VERBOSE: Add-MachineToSCCMQueryRule: Dexter_TEST_QueryRule Created and saved for the Collection
VERBOSE: The machine name Win7Test01 is not in the QueryRule.....adding it
VERBOSE: Win7Test01 seems to have Client Installed
VERBOSE: SCCM Client on the Win7Test01 is Active
VERBOSE: The machine name Win7Test02 is not in the QueryRule.....adding it
VERBOSE: Win7Test02 seems to have Client Installed
VERBOSE: SCCM Client on the Win7Test02 is Active
VERBOSE: Taking backup of the QueryExpression to C:\Temp\QueryBackup.txt...just in case
VERBOSE: Invoked Method DeleteMembershipRule on the Collection
VERBOSE: Invoked Method RequestRefresh on the Collection
VERBOSE: Invoked Method AddMembershipRule on the Collection
VERBOSE: Invoked Method RequestRefresh on the Collection


SCCMClient        : Yes
Action            : Added
Computername      : Win7Test01
QueryRuleName     : Dexter_TEST_QueryRule
CollectionId      : DEX123BD
CollectionName    : Deepak Test 1
SCCMClient_Active : Yes

SCCMClient        : Yes
Action            : Added
Computername      : Win7Test02
QueryRuleName     : Dexter_TEST_QueryRule
CollectionId      : DEX123BD
CollectionName    : Deepak Test 1
SCCMClient_Active : Yes

VERBOSE: Add-MachineToSCCMQueryRule: All the machines added..now doing post advertisement tasks
VERBOSE: Win7Test01 --> is online doing Policy Refresh and Service Check
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test01 --> Automatic Updates Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test01 --> Windows Management Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test01 --> Remote Registry Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test01 --> SMS Agent Host Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test01 --> BITS service Checked
VERBOSE:  Invoke-MachinePolicyRefresh: Win7Test01 --> Machine Policy refreshed :) 
VERBOSE: Win7Test02 --> is online doing Policy Refresh and Service Check
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test02 --> Automatic Updates Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test02 --> Windows Management Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test02 --> Remote Registry Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test02 --> SMS Agent Host Service Checked
VERBOSE: Invoke-SCCMServiceCheck_Fix : Win7Test02 --> BITS service Checked
VERBOSE:  Invoke-MachinePolicyRefresh: Win7Test02 --> Machine Policy refreshed :) 
VERBOSE: Add-MachineToSCCMQueryRule: Ending the function

So you just call the Function pass it the SCCM server name , CollectionId and the machine names to be added to your Query Rule.

Note: I choose to hard-code SCCM Server name and the Template of the Query in the Script Source so that I don't have to specify it each time and not to confuse my other colleagues.



So after doing this if you go to the ConfigMgr Console...and select the test collection (you will need to hit F5 to update the view if console is already opened to see the members)

Now see below the Query Rule appears...Voila !!



And you can see the count now too:



So this solution makes adding the machine names easy to the collection, thus reducing my job of deploying applications. 

To add more awesomeness to the Script ....it will pop-up a warning if the computernames specified don't have a SCCM client installed or SCCM Client not active on them.

I wrote this Script to work in PowerShell v2.
So in future am going to add CIM sessions and a couple of things to it too. Let me know your feedback if any.Download from the Technet Repository

Popular posts from this blog

Test connectivity via a specific network interface

Recently while working on a Private cloud implementation, I came across a scenario where I needed to test connectivity of a node to the AD/DNS via multiple network adapters.  Many of us would know that having multiple network routes is usually done to take care of redundancy. So that if a network adapter goes down, one can use the other network interface to reach out to the node. In order to make it easy for everyone to follow along, below is an analogy for the above scenario: My laptop has multiple network adapters (say Wi-Fi and Ethernet) connected to the same network. Now how do I test connectivity to a Server on the network only over say Wi-Fi network adapter?

PowerShell + SCCM : Run CM cmdlets remotely

Today I saw a tweet about using implicit remoting to load the Configuration Manager on my machine by Justin Mathews . It caught my eye as I have never really tried it, but theoretically it can be done. Note - The second tweet says "Cannot find a provider with the name CMSite", resolution to which is in the Troubleshooting section at the end.

Azure DevOps Tips & Tricks - Find private REST APIs

Original source -  Azure DevOps Tip - Find private APIs Often working with Azure DevOps, I hit a wall trying to automate some tasks but there are no REST API's made public yet. It was one of those task of automating creation of Environments in multi-stage YAML based pipelines in AzDO. Quick research reveals that this has been requested in uservoice  (please upvote). Let's see one of the very simple ways to discover some of these APIs.