Creating a ConfigMgr collection using PowerShell v2 CTP3

I’ve been working with the ConfigMgr (and previously, the SMS) provider for years, using the underlying WMI classes to completely automate the administration of ConfigMgr.  So I have existing scripts, C# code, and Visual Basic code to do things like creating a collection.  See https://myitforum.com/articles/8/view.asp?id=1309 for an old example I created almost four years ago.

I didn’t expect it to be particularly difficult to convert this logic into PowerShell, but I have to say it wasn’t nearly as easy as I expected.  But after some swearing at the computer (and knowing that there is no way it can hear me or understand my level of frustration), I did get it to work.

So here’s my next example, continuing on what was in the previous blog posting (https://blogs.technet.com/mniehaus/archive/2009/04/07/fun-with-configmgr-2007-and-powershell.aspx).  Add the following text (hopefully the line wrapping doesn’t cause problems) to the bottom of the file you created previously:

function New-SCCMCollection
{
    [CmdletBinding()]
    PARAM
    (
        [Parameter(Position=1)] $name,
        [Parameter(Position=2)] $comment,
        [Parameter(Position=3)] [ValidateRange(0, 59)] [int] $refreshMinutes,
        [Parameter(Position=4)] [ValidateRange(0, 23)] [int] $refreshHours,
        [Parameter(Position=5)] [ValidateRange(0, 31)] [int] $refreshDays,
        [Parameter(Position=6)] $parentCollectionID
    )

    # Build the parameters for creating the collection
    $arguments = @{Name = $name; Comment = $comment; OwnedByThisSite = $true}
    $newColl = set-wmiinstance -class SMS_Collection -arguments $arguments -computername $sccmServer -namespace $sccmNamespace

    # Hack - for some reason without this we don't get the CollectionID value
    $hack = $newColl.PSBase | select * | out-null

    # It's really hard to set the refresh schedule via set-wmiinstance, so we'll set it later if necessary
    if ($refreshMinutes -gt 0 -or $refreshHours -gt 0 -or $refreshDays -gt 0)
    {
        # Create the recur interval object
        $intervalClass = [wmiclass]"\\$sccmServer\$($sccmNamespace):SMS_ST_RecurInterval"
        $interval = $intervalClass.CreateInstance()
        if ($refreshMinutes -gt 0)
        {
            $interval.MinuteSpan = $refreshMinutes
        }
        if ($refreshHours -gt 0)
        {
            $interval.HourSpan = $refreshHours
        }
        if ($refreshDays -gt 0)
        {
            $interval.DaySpan = $refreshDays
        }

        #  Set the refresh schedule
        $newColl.RefreshSchedule = $interval
        $newColl.RefreshType=2
        $path = $newColl.Put()
    }   

    # Build the parameters for the collection to subcollection link
    $subArguments = @{SubCollectionID = $newColl.CollectionID}
    if ($parentCollectionID -eq $null)
    {
        $subArguments += @{ParentCollectionID = "COLLROOT"}
    }
    else
    {
        $subArguments += @{ParentCollectionID = $parentCollectionID}
    }

    # Add the link
    $newRelation = set-wmiinstance -class SMS_CollectToSubCollect -arguments $subArguments -computername $sccmServer -namespace $sccmNamespace

    # Return the collection
    $newColl
}

So what does this do?  Simple, it creates a new collection.  You can use it in various ways:

import-module C:\SCCM.psm1

Connect-SCCMServer MTN-SERVER

new-SCCMCollection -name "Test 1"

new-SCCMCollection -name "Test 2" -comment "Test comment"

new-SCCMCollection -name "Test 3" -refreshMinutes 30

new-SCCMCollection -name "Test 4" -refreshHours 1

new-SCCMCollection -name "Test 5" -refreshDays 1

new-SCCMCollection -name "Test 6" -parentCollectionID CEN0001C

Now, for some explanation of the wackiness above:

  • In theory, you should be able to set up an array of refresh schedules and provide that to set-wmiinstance so that it establishes the refresh interval as expected.  But for some reason that doesn’t work – it generates a type conversion error.  So, the code above creates the collection and then sets the schedule.
  • Getting the collection ID from the new collection (needed to create the association) doesn’t work if you don’t have the “hack” line above.  I suspect that’s a bug.
  • Creating the SMS_ST_RecurInterval isn’t as simple as you might think, as you need to create the class instance.

Of course now you’ll want to know how to add membership rules to that collection.  That’s up next, but I need to get some “real work” done first…

*** Updated to fix two issues (lack of testing, sorry):

  • Set the OwnedByThisSite parameter to true so the new collections aren’t locked.
  • Changed “refresh” to refreshMinutes, refreshHours, refreshDays.  You can specify any of the three values, but not a combination.  Minutes can be 0-59, hours 0-23, days, 0-31.  The longest value specified wins.