Category Archives: Powershell

O365Uploader V0.4

Due to popular request,  I’ve added an analyze function to the O365Uploader. After choosing your folder to be uploaded, a popup will ask you if you wish to see an analysis of potential issues and suggested fixes for your content. Everthing will both be written to the Powershell console in the background and a detailed log file which can be used in MS Excel.

You can download the new version here.

Other changes:

  • Added check for period in folder/file name
  • Added check for various illegal suffixes in filenames
  • Added verification prompt before upload to log all issues to a file beforehand so it can be fixed in advance
  • Added warning for 5000+ items
  • Added warning for hidden files (start with an _ )

Elevating powershell scripts, and staying in the script folder

Sometimes you want to be able to just double click your powershell scripts and see them work….putting this code at the top of your script will do just that by detecting if the script is running as administrator with administrative priviledges. If not, the script will launch a new instance of itself with an elevation prompt.

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
{
 $arguments = "& '" + $myinvocation.mycommand.definition + "'"
 Start-Process powershell -Verb runAs -ArgumentList $arguments
 Break
 }
 cd $scriptPath
<rest of your code>

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