Boundary and Boundary Group Import and Export

Boundary and Boundary Group Import and Export

Sadly, Microsoft Enterprise Manager Configuration Manager (ConfigMgr) has no built-in methods to export or import boundaries and boundary groups. This shortcoming is reasonably easy to address with PowerShell though, so I did a quick search on the web and found a bunch of examples for boundaries but none for boundary groups (I didn’t look that much though). What I found though were longer, custom scripts that only provided export capabilities. Not liking these and thinking I could do better, I set out to create my own set of PowerShell one-liners for these tasks.

Boundaries

Import and export for boundaries are super simple using the built-in ConfigMgr cmdlets. Run these one-liners on any system with the console installed on it if you load the ConfigMgr PowerShell module first and switch to the provider for your site. If you don’t know how to do this manually, launch PowerShell directly from the ConfigMgr console using the Connect via Windows PowerShell main menu option.

Export

The following one-liner exports the name/description, the value, and the boundary type for all boundaries using the Get-CMBoundary cmdlet and saves it to a CSV at the specified location.

Get-CMBoundary | Select-Object -Property DisplayName,Value,BoundaryType | Export-CSV -Path <path>\<file>.csv -NoTypeInformation

Import

Import is as easy as export using the following one-liner and the same CSV that the above export one-liner creates. This one-liner loops through the items in the CSV and calls New-CMBoundary for each. Easy peasy.

Import-CSV -Path <path>\<file>.csv | ForEach-Object { New-CMBoundary -Name $_.DisplayName -Type $_.BoundaryType -Value $_.Value }
Keep in mind that there is no graceful error handling here, so if the boundary already exists, you’ll get a standard, all in red, PowerShell error.

Boundary Groups

Boundary groups are a little more involved because the built-in cmdlets don’t list the site system associated with the boundary group and use a separate cmdlet to add boundaries to a boundary group. As with the boundary import and export one-liners above, run these one-liners on any system with the console installed on it if you load the ConfigMgr PowerShell module first and switch to the provider for your site.

Export

This long one-liner extracts the name, site assignment site code, member boundary names, and names of associated site systems and then saves all of that to a CSV at the specified location.

Get-CMBoundaryGroup | Select-Object -Property Name,DefaultSiteCode,@{Name = 'Boundaries'; Expression = { (Get-CMBoundary -BoundaryGroupName $_.Name).DisplayName -join ';'}}, @{Name='SiteSystems'; Expression = { ( (Get-WmiObject -ComputerName <SMSProvider> -Namespace root\sms\site_<sitecode> -Class SMS_BoundaryGroupSiteSystems -Filter "GroupID='$($_.GroupID)'").ServerNALPath | ForEach-Object { ($_ -split '\\\\')[2].trim('\\') }) -join ';' }} | Export-CSV -Path <path>\<file>.csv -NoTypeInformation

So, what does this crazy looking one-liner do? Let’s break it down.

  • Get-CMBoundaryGroup
    Gets all of the boundary groups.
  • Select-Object
    Extracts certain properties including two calculated properties.
  • @{Name = 'Boundaries'; Expression = { (Get-CMBoundary -BoundaryGroupName $_.Name).DisplayName -join ';'}}

    The first calculated property gets the boundaries associated with the current boundary group, extracts their display names, and then joins them into a single string with a semi-colon separator.
  • @{Name='SiteSystems'; Expression = { ( (Get-WmiObject -ComputerName <SMSProvider> -Namespace root\sms\site_<sitecode> -Class SMS_BoundaryGroupSiteSystems -Filter "GroupID='$($_.GroupID)'").ServerNALPath | ForEach-Object { ($_ -split '\\\\')[2].trim('\\') }) -join ';' }}

    The second calculated property uses WMI to get the site systems associated with the boundary group (from the SMS_BoundaryGroupSiteSystems class). The ServerNALPath attribute stores the site systems; this attribute is processed using a split and trim to get the actual server name and then joined into a single string with a semi-colon separator.
Make sure to replace [sitecode] with your site’s three character site code and [SMSProvider] with the name of the site system hosting your SMS Provider (which is usually the primary site server, but not always).

Import

Import is a two-step process that first imports the boundary group and then adds the boundaries to that boundary group. You can do these two steps using a single, complex, and long one-liner, but I decided to break it up into two smaller one-liners.

This first one-liner loops through the specified CSV file and creates the boundary groups using the New-CMBoundaryGroup and Set-CMBoundaryGroup cmdlets.

Import-CSV -Path <path>\<file>.csv | ForEach-Object { New-CMBoundaryGroup -Name $_.Name; if($_.DefaultSiteCode) { Set-CMBoundaryGroup -Name $_.Name -DefaultSiteCode $_.DefaultSiteCode }; if($_.SiteSystems) { Set-CMBoundaryGroup -Name $_.Name -AddSiteSystemServerName ($_.SiteSystems -split ';')} }

This one-liner is fairly straight-forward but does contain a couple of embedded if statements that conditionally call the Set-CMBoundaryGroup cmdlet because the New-CMBoundaryGroup cmdlet doesn’t handle blank values.

Keep in mind that there is no graceful error handling here either so if the boundary group already exists, you’ll get a standard, all in red, PowerShell error.

This second one-liner once again loops through the specified CSV file and adds the boundaries to the boundary groups using the Add-BoundaryToBoundaryGroup cmdlet.

Import-CSV -Path <path>\<file>.csv | ForEach-Object { foreach($boundary in ($_.Boundaries -split ';')) { Add-CMBoundaryToGroup -BoundaryGroupName $_.Name -BoundaryName $boundary } }

The only complexity with this one-liner is that the Add-BoundaryToBoundaryGroup cmdlet only takes a single boundary at a time and so must be called for each boundary in the data file.

Summary

There you have five easy one-lines for complete boundary and boundary group import and export for backup and restore, migration, simple kicks, or whatever your purpose. Yes, these could all be made into scripts of their own or combined into one larger, master script, but part of the beauty of PowerShell is that you don’t have to, but you can if you want to.

No Comments

Cancel