Category Archives: Powershell

Scripted Deployment of Distribution Points in SCCM 2012 including rate scheduling

Somewhat quick and dirty, but I’m sure it’ll be of use to anyone doing a larger scale rollout of distribution points.

The following script can interactively roll out distribution points for you, saving a huge amount of clicking around in the SCCM console. The code can easily be adapted to run everything from functions and bulk import a list of distribution points from CSV to SCCM.

#Add distribution point with State Migration and Pulse Rate limitation and scheduling
#Author: Jos Lieben, OGD
#Copyright: Free to Use and Distribute
#Credits: David O’Brien (david-obrien.net) for WMI class interaction
#notice: you must have the required console updates for some of these commands to work with SCCM 2012 SP1

####GENERAL CONFIGURATION####
#If you clear any config, the script will prompt you for it, config simply helps you simplify deployments if for example, you only have one site
#Path to your PSD files
Import-Module “C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1″
#Your site code
$site_code = “EU1″
#Name of your distribution point (Fully Qualified Name required!)
$server_name = “”
#Drive letter for your primary content library, use Automatic if you wish SCCM to manage this for you
$driveletter_plibrary = “”
#Drive letter for your primary content share, use Automatic if you wish SCCM to manage this for you
$driveletter_pshare = “”
#If you wish to add a state migration point to the DP, set this to $true
$add_statemigrationpoint = $false
#Path to data on the state migration point
$state_migrationpoint_localpath = “”
#Distribution Point Group Membership can be configured with this variable
$distributionpointgroup = “”
####END OF GENERAL CONFIGURATION####
####SCHEDULING CONFIGURATION####
#Set to False if you do not wish to configure transfer schedules for your DP ($false recommended)
$add_schedule = $true
#size of each block sent, leave at 0 to prompt, only used when add_schedule=$true
$block_size = 0
#delay between each block sent, leave at 0 to prompt, only used when add_schedule=$true
$block_delay = 0
#Array containing 24 elements, one for each hour of the day. This property specifies the type of usage for each hour.
# 1 means all Priorities, 2 means all but low, 3 is high only, 4 means none
#this example allows only high priority sendings from monday till friday between 8AM and 8PM and everything outside that timeframe
$HourUsageScheduleWeekdays = @(1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1)
$HourUsageScheduleWeekend = @(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
####END OF SCHEDULING CONFIGURATION#####
#standard variables
$ja = new-Object System.Management.Automation.Host.ChoiceDescription “&Yes”,”help”
$nee = new-Object System.Management.Automation.Host.ChoiceDescription “&No”,”help”

Clear-Host
if($site_name -eq “”) {
$site_code = Read-Host “Enter your site code (for example: EU1)”
}
if($server_name -eq “”) {
$server_name = Read-Host “Enter the FQDN of your new distribution point (for example: dp01.ogd.local)”
}
if($driveletter_plibrary -eq “”) {
$driveletter_plibrary = Read-Host “Enter the driveletter for the primary content library (for example: E)”
}
if($driveletter_pshare -eq “”) {
$driveletter_pshare = Read-Host “Enter the driveletter for the primary content share (for example: E)”
}
if($add_statemigrationpoint -eq $true -And $state_migrationpoint_localpath -eq “”){
$state_migrationpoint_localpath = Read-Host “Enter the path your state migration point should use to store data (use quotes, for example: “C:\USMT”)”
}
if($distributionpointgroup -eq “”) {
$distributionpointgroup = Read-Host “Enter the name of the group you wish your distribution point to be a member of (for example OGD Production Site)”
}
if($add_schedule -eq $true){
if($block_size -eq 0){
$block_size = Read-Host(“Specify the maximum block size in KB for the Pulse Rate (min 1, max 256)”)
}
if($block_delay -eq 0){
$block_delay = Read-Host(“Specify the delay between blocks (min 1, max 30)”)
}
if([int]$block_delay -gt 30) {[int]$block_delay = 30}
if([int]$block_delay -lt 1) {[int]$block_delay = 1}
if([int]$block_size -gt 256) {[int]$block_size = 256}
if([int]$block_size -lt 1) {[int]$block_size = 1}
}

#bind to correct site
Set-Location $site_code”:”
#summarize
Write-Host “”
Write-Host “”
Write-Host “We have enough information to proceed, the following will take place:”
Write-Host ” * A distribution point will be added to site $site_code”
Write-Host ” * The FQDN is $server_name”
Write-Host ” * A Content Library will be placed on drive $driveletter_plibrary”
Write-Host ” * A Content Share will be placed on drive $driveletter_pshare”
Write-Host ” * The DP will be added to the $distributionpointgroup group”
if($add_statemigrationpoint -eq $true){
Write-Host ” * A state migration point will be added”
Write-Host ” * State Migration Point Storage Path: $state_migrationpoint_localpath”
$folders = New-CMStorageFolder -StorageFolderName $state_migrationpoint_localpath -MaximumClientNumber 100 -MinimumFreeSpace 100 -SpaceUnit Megabyte
}else{
Write-Host ” * A state migration point will NOT be added”
}
if($add_schedule -eq $true){
Write-Host ” * Rate Limitation will be set to $block_size KB per $block_delay seconds according to schedule in config”
}else{
Write-Host ” * Rate Limitation will NOT be configured”
}

Write-Host “”
$options = [System.Management.Automation.Host.ChoiceDescription[]]($ja,$nee)
$prompt = $host.ui.PromptForChoice(“”,”Do you wish to proceed?”,$options,0)
Write-Host “”
if($prompt -eq 1) {
Write-Host “Cancelled…”
Exit
}

new-CMSiteSystemServer -ServerName $server_name -SiteCode $site_code

add-CMdistributionpoint -SiteSystemServerName $server_name -SiteCode $site_code -CertificateExpirationTimeUtc “Monday, January 2, 2017 1:00:00 AM” -MinimumFreeSpaceMB 5000 -InstallInternetServer -PrimaryContentLibraryLocation $driveletter_plibrary -PrimaryPackageShareLocation $driveletter_pshare -EnablePxeSupport -AllowRespondIncomingPxeRequest -EnableUnknownComputerSupport

add-CMDistributionPointToGroup -DistributionPointName $server_name -DistributionPointGroupName $distributionpointgroup
if($add_statemigrationpoint -eq $true){
add-cmstatemigrationpoint -EnableRestoreOnlyMode $false -sitesystemservername $server_name -sitecode $site_code -storagefolders $folders -TimeDeleteAfter 7 -TimeUnit Days -AllowFallBackSourceLocationForContent $false
}

if($add_schedule -eq $true){

$Percent = 100
$UsageAsBackup = @($true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true,$true)

$RateLimitingSchedule = @($Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent,$Percent)

$SMS_SCI_ADDRESS = “SMS_SCI_ADDRESS”
$class_SMS_SCI_ADDRESS = [wmiclass]””
$class_SMS_SCI_ADDRESS.psbase.Path =”ROOT\SMS\Site_$($site_code):$($SMS_SCI_ADDRESS)”

$SMS_SCI_ADDRESS = $class_SMS_SCI_ADDRESS.CreateInstance()
# Set the UsageSchedule For Weekdays
$SMS_SiteControlDaySchedule = “SMS_SiteControlDaySchedule”
$SMS_SiteControlDaySchedule_class = [wmiclass]””
$SMS_SiteControlDaySchedule_class.psbase.Path = “ROOT\SMS\Site_$($site_code):$($SMS_SiteControlDaySchedule)”
$SMS_SiteControlDaySchedule = $SMS_SiteControlDaySchedule_class.createInstance()
$SMS_SiteControlDaySchedule.Backup = $UsageAsBackup
$SMS_SiteControlDaySchedule.HourUsage = $HourUsageScheduleWeekdays
$SMS_SiteControlDaySchedule.Update = $true

# Set the UsageSchedule For Weekend
$SMS_SiteControlDayScheduleWeekend = “SMS_SiteControlDaySchedule”
$SMS_SiteControlDayScheduleWeekend_class = [wmiclass]””
$SMS_SiteControlDayScheduleWeekend_class.psbase.Path = “ROOT\SMS\Site_$($site_code):$($SMS_SiteControlDayScheduleWeekend)”
$SMS_SiteControlDayScheduleWeekend = $SMS_SiteControlDayScheduleWeekend_class.createInstance()
$SMS_SiteControlDayScheduleWeekend.Backup = $UsageAsBackup
$SMS_SiteControlDayScheduleWeekend.HourUsage = $HourUsageScheduleWeekend
$SMS_SiteControlDayScheduleWeekend.Update = $true

$SMS_SCI_ADDRESS.UsageSchedule = @($SMS_SiteControlDayScheduleWeekend,$SMS_SiteControlDaySchedule,$SMS_SiteControlDaySchedule,$SMS_SiteControlDaySchedule,$SMS_SiteControlDaySchedule,$SMS_SiteControlDaySchedule,$SMS_SiteControlDayScheduleWeekend)

$SMS_SCI_ADDRESS.RateLimitingSchedule = $RateLimitingSchedule

$SMS_SCI_ADDRESS.AddressPriorityOrder = “0”
$SMS_SCI_ADDRESS.AddressType = “MS_LAN”
$SMS_SCI_ADDRESS.DesSiteCode = “$($server_name)”
$SMS_SCI_ADDRESS.DestinationType = “1”
$SMS_SCI_ADDRESS.SiteCode = “$($site_code)”
$SMS_SCI_ADDRESS.UnlimitedRateForAll = $false

# Set the embedded Properties
$embeddedpropertyList = $null
$embeddedproperty_class = [wmiclass]””
$embeddedproperty_class.psbase.Path = “ROOT\SMS\Site_$($site_code):SMS_EmbeddedPropertyList”
$embeddedpropertyList = $embeddedproperty_class.createInstance()
$embeddedpropertyList.PropertyListName = “Pulse Mode”
$embeddedpropertyList.Values = @(1,$block_size,$block_delay) #second value is size of data block in KB, third is delay between data blocks in seconds

$SMS_SCI_ADDRESS.PropLists += $embeddedpropertyList

$embeddedproperty = $null
$embeddedproperty_class = [wmiclass]””
$embeddedproperty_class.psbase.Path = “ROOT\SMS\Site_$($site_code):SMS_EmbeddedProperty”
$embeddedproperty = $embeddedproperty_class.createInstance()
$embeddedproperty.PropertyName = “Connection Point”
$embeddedproperty.Value = “0”
$embeddedproperty.Value1 = “$($server_name)”
$embeddedproperty.Value2 = “SMS_DP$”
$SMS_SCI_ADDRESS.Props += $embeddedproperty

$embeddedproperty = $null
$embeddedproperty_class = [wmiclass]””
$embeddedproperty_class.psbase.Path = “ROOT\SMS\Site_$($site_code):SMS_EmbeddedProperty”
$embeddedproperty = $embeddedproperty_class.createInstance()
$embeddedproperty.PropertyName = “LAN Login”
$embeddedproperty.Value = “0”
$embeddedproperty.Value1 = “”
$embeddedproperty.Value2 = “”
$SMS_SCI_ADDRESS.Props += $embeddedproperty

$SMS_SCI_ADDRESS.Put() | Out-Null
}
#In case your executionpolicy is restricted and you can’t modify it, paste these lines before calling the script
#Copyright Oisin Grehan
#START (remove #’s)
#function Disable-ExecutionPolicy {
#($ctx = $executioncontext.gettype().getfield(“_context”,”nonpublic,instance”).getvalue($executioncontext)).gettype().getfield(“_authorizationManager”,”nonpublic,instance”).setvalue($ctx, (new-object System.Management.Automation.AuthorizationManager “Microsoft.PowerShell”))
#}
#Disable-ExecutionPolicy
#END