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.

PowerShell : Trust network share to load modules & ps1

Problem Do you have a central network share, where you store all the scripts or PowerShell modules ? What happens if you try to run the script from a network share ? or if you have scripts (local) which invoke scripts or import PowerShell modules stored on this network share ? Well you would see a security warning like below (Note - I have set execution policy as 'Unrestricted' not 'bypass' here): Run a .ps1 from the network share Well this is a similar warning, which you get when you download scripts from Internet. As the message says run Unblock-File cmdlet to unblock the script and then run it, let's try it.