Nested loop help needed badly!

Tagged: ,

This topic contains 3 replies, has 3 voices, and was last updated by Profile photo of Adam Bertram Adam Bertram 2 years, 6 months ago.

  • Author
    Posts
  • #15433
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    I have a need for a script that collects computer names and operating systems from a ConfigMgr collection and then groups those computers by operating system. Once it has the OS groupings created, it then needs to pick (at random) a computer name from each of the groups up to a limit of a number of computers specified.

    I've figured out the SCCM part and the random part but I'm having a hell of a time wrapping my head around the logic to get this done. Here's an example attempt at explaining it in code:

    ## This is the total number of computers I need (total) out of all the operating system groups
    $NumberOfRandomClientsNeeded = 55
    
    ## This outputs objects grouped by operating system containing the computer names in the Group property
    $OperatingSystemGroups = Get-WmiObject @ConfigMgrWmiProps -Class "SMS_CM_RES_COLL_$SourceCollectionId" | select Name, DeviceOS | group DeviceOS | sort count -Descending
    
    ## This defines only the Top Count operating systems groups in case the number of clients I need is less than the total operating system grouping
    ## If I have more clients needed than OS groupings, I just use them all
    If ($NumberOfRandomClientsNeeded -lt $OperatingSystemGroups) {
      $OperatingSystemGroups = $OperatingSystemGroups[0..($NumberOfRandomClientsNeeded - 1)]
    }
    
    ## Here's where I'm going to use pseudo-code because I have no idea how to do this
    ##1. Pick a client from OS group 1.
    ##2. Pick a client from OS group 2.
    ##3. Pick a client from OS group 3.
    ##...
    ##END OS GROUPS
    ##XX. Pick a client from OS group 1.
    ##XX. Pick a client from OS group 2.
    ##XX. Pick a client from OS group 3.
    ##...
    ##END OS GROUPS
    ##XX. Pick a client from OS group 1.
    ##XX. Pick a client from OS group 2.
    ##XX. Pick a client from OS group 3.

    I need the code to grab a client from each OS group and repeat through the OS groups until it hits the $NumberOfRandomClientsNeeded number. I do not want it to grab a client from the operating system group back to back. It must iterate through all the OS groups 1 at a time.

    I sure hope I'm explaining this well. I started off on this script thinking it'd be easy but I've spent close to 3 hours just trying every kind of nested loop I can think of and I can't get the result I'm looking for.

  • #15442
    Profile photo of Joakim
    Joakim
    Participant

    Can you add some sample data? I don't have System Center nearby and I am not sure what the result would look like in the $OperatingSystemGroups variable?

    If your main issue is how to find the random tem in the array, try using the Get-Random cmdlet. Something like this:

    $OperatingSystemGroups | ? { $_.DeviceOS -eq 'osname' } | Get-Random

    What this example illustrates is how you can filter they array, pick out the specific items mathing the "osname" and then pass it all to Get-Random to get a randomly selected item from the list.

  • #15447
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    In this case, you don't necessarily need a nested loop. You can use the modulus operator to achieve the same result. For example:

    $groupCount = 10
    $NumberOfRandomClientsNeeded = 55
    
    for ($i = 0; $i -lt $NumberOfRandomClientsNeeded; $i++)
    {
        $groupIndex = $i % $groupCount
    
        Write-Host "Selecting a client from group $groupIndex..."
    }
    
  • #15471
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    @Dave – That worked great! I had played around with using the modulus operator a little but I never considered getting the group index that way.

You must be logged in to reply to this topic.