Video Screencast Help
Protect Your POS Environment Against Retail Data Breaches. Learn More.
Endpoint Management Community Blog

Creating NS Collections to Divide Your Computers into Equal Groups

Created: 09 Jul 2007 • 1 comment
dmorrison's picture
0 0 Votes
Login to vote

Sometimes it's desirable to create 4 collections for inventory tasks so software audits only occur on a particular day for 1/4 of the computers in the environment without dealing with the random execution of AexRunControl. Or your CIO wants to evenly distribute a software delivery over 10 days to reduce risk and you would like to avoid creating 10 dynamic collections.

One of the challenges we often face in Notification Server is creating collections that evenly divide computers into several groups to distribute inventory processing or software delivery.

The SQL script below provides a simple way to create a dynamic collection which will be roughly 1/4 of the computers in your Notification Server. It contains 2 variables: @Groups and @GroupNumber. To create another collection for the different 1/4's of your computers, change the value of @GroupNumber to 2, 3 or 4. No computer will be in 2 groups and the groups will be close in size more or less evenly distributed among your enterprise.

The example code delivers 1 of 4 groups. You can specify one of the other 3 groups by changing the @GroupVariable to 2, 3 or 4. You can adjust the @Groups value to be as many groups as you wish.

DECLARE @Groups int, @GroupNumber int
/* Number of groups to divide population into */
SET @Groups = 4
/* The group for this collection( between 1 and the @Groups value */
SET @GroupNumber = 1 
SELECT Guid
FROM vComputer vc
WHERE (
   datediff(second,
    convert(datetime,convert(char(10),vc.CreatedDate,112)),
    vc.CreatedDate) 
  % @Groups
  ) +1  =  @GroupNumber 

How does that work? Some simple integer math from grade school. The modulo operation in SQL returns the remainder when one integer is divided by another. Divide 17 by 4 and you will have a modulo or remainder of 3. The possible modulos when dividing by 4 are 0,1,2 and 3.

Now, we need an integer value associated with a computer which will not change and is more or less random. Created date does not change unless the computer is deleted. The number of seconds between the midnight and the time in the created date will not change and is not based on any outside values like OS, location, etc. Even if you import a batch of computers, they will have different times in their created date column.

The number of seconds between midnight of the date it was created and the time it was created when divided by 4 yields a value of 0, 1, 2 or 3 for each computer. No computer can have 2 different values for this calculation. The near even distribution occurs because we're not using ranges of values, but relying on the spread of integers between 0 and 1,440 seconds in the day. It's not a perfectly even distribution, but it gets close and it runs very quickly.

How about that example for the 10% per day for software delivery? Create a collection for 1/10 of the population with the SQL below. Note the @GroupNumber is 1 and the comparision in the last line is "<=". Enable your software delivery task on day 1 for the first 10% of your population.

DECLARE @Groups int, @GroupNumber int
/* Number of groups to divide population into */
SET @Groups = 10
/* The group for this collection( between 1 and the @Groups value */
SET @GroupNumber = 1
SELECT Guid
FROM vComputer vc
WHERE (
   datediff(second,
    convert(datetime,convert(char(10),vc.CreatedDate,112)),
    vc.CreatedDate) 
  % @Groups
  ) +1  <=  @GroupNumber

On day 2 of your 10 day software delivery event, edit your dynamic SQL collection and change the @GroupNumber to 2. This will be a collection of the first and second 1/10th's of your population. Each day, advance the @GroupNumber by 1 to increase the population of the collection by 10%.

Having a hard time visualizing/trusting this works? Try the query below to see how it would distribute your computers into nearly congruent populations. Change the @Groups variable to the number of groups you need.

DECLARE @Groups int
SET @Groups = 10
SELECT  (
   datediff(second,
    convert(datetime,convert(char(10),vc.CreatedDate,112)),
    vc.CreatedDate) 
  % @Groups
  ) +1 AS [Group Number] ,  
  Count(*) as [Count of Computers]
FROM vComputer vc
GROUP BY  (
   datediff(second,
    convert(datetime,convert(char(10),vc.CreatedDate,112)),
    vc.CreatedDate) 
  % @Groups
  ) +1 

 

Comments 1 CommentJump to latest comment

SK's picture

However, I would refrain from using the vComputer View where possible, especially for Collections and Reports, as it is made up of about five or six database objects, and can cause your result set to be mis-leading under certain circumstances.

The actual Collection display is created from the vComputer View, whioch emans that this object is being accessed twice.

You maybe better off using the Item table or possible vResource or vResourceEx.

Connect Etiquette: "Mark as Solution" those posts which resolve your problem, and give a thumbs up to useful comments, articles and downloads.

+4
Login to vote