SCCM Deployments with PowerShell

The following script allows to create a deployments on SCCM

  • Deployment of an application (asap)
  • Deployment of a package (asap after an available date/time)
  • Deployment of a task sequence (scheduled using WMI)

The deployments of the application and the package are enforced as soon as possible but it’s also possible to schedule them by setting an available date/time and an enforcement date/time.

The deployments enforce the installation with not overriding the maintenance window.

To work properly, this script must be launched from a server with the SCCM Console installed.

 

##*===============================================
##* IMPORT CONFIGURATION MANAGER MODULE
##*===============================================

Write-Host "Importing SCCM PS Module”
# Import SCCM PS Module
Import-Module ($Env:SMS_ADMIN_UI_PATH.Substring(0,$Env:SMS_ADMIN_UI_PATH.Length-5) + '\ConfigurationManager.psd1')



##*===============================================
##* DECLARATIONS
##*===============================================

Write-Host "Declaring variables...”

# SCCM Server
$SCCMSiteServer = "MySCCMServerName"
$SCCMSiteCode = "MySCCMSiteCode"
$CMSitePath = $SCCMSiteCode+":"

# Collection
$CollectionName = "MyCollection"

# Application
$ApplicationName = "MyApplication"

# Package
$PackageId = "PKG00012"
$ProgName = "InstallProgramName"

# Task Sequence
$TaskSequenceID = "TS000015"

Write-Host "SCCM Server Name is $SCCMSiteServer"
Write-Host "SCCM Site Code is $SCCMSiteCode"
Write-Host "Collection name is $CollectionName"
Write-Host "Application to deploy is $ApplicationName"
Write-Host "Package (ID) to deploy is $PackageId"
Write-Host "Package program to deploy is $ProgName"
Write-Host "Task sequence (ID) to deploy is $TaskSequenceID"



##*===============================================
##* CHECK COLLECTION
##*===============================================

Write-Host “Checking collection..."
# Check if the collection exists
$CollectionExist = Get-CMDeviceCollection -Name "$CollectionName"
If ($CollectionExist) {
    Write-Host "The collection $CollectionName exist"
}
Else {
    Write-Host "Error - The collection $CollectionName does not exist"
    Exit 
}



##*===============================================
##* CREATE APPLICATION DEPLOYMENT
##*===============================================

Write-Host "Checking application...”
# Check if the application exists
$ApplicationNameExist =  Get-CMApplication -Name "$ApplicationName"
If ($ApplicationNameExist) {
    Write-Host "Application exists"
}
Else {
    Write-Host "Error - Application does not exist"
    Exit 
}


Write-Host "Checking deployment...”
# Check if a deployment already exists for the application on the collection
$DeploymentList = Get-CMDeployment -CollectionName "$CollectionName"
ForEach ($CheckDeployment in $DeploymentList) {
    $CheckSoftwareName = $CheckDeployment.SoftwareName
    If ($CheckSoftwareName -eq $ApplicationName) {
        Write-Host "Error - A deployment of the application $ApplicationName on the collection $collectionName already exist"
		Exit
    }
}
Write-Host "No deployment of the application $ApplicationName on the collection $collectionName already exist"


Write-Host "Creating deployment of the application...”
# Create deployment for the application (asap, not overriding the maintenance window)
Try {
	$Deployment = Start-CMApplicationDeployment -CollectionName $CollectionName -DeployAction "Install" -Name $ApplicationName -DeployPurpose Required -UserNotification DisplaySoftwareCenterOnly
	Write-Host "Deployment of the application $ApplicationName on the collection $CollectionName created"
}
Catch {
	Write-Host "Error - Exception caught in creating deployment : $error[0]"
}



##*===============================================
##* CREATE PACKAGE DEPLOYMENT
##*===============================================

Write-Host "Checking package...”
# Check if the package exists
$PackageIdExist = Get-CMPackage -Id "$PackageId"
If ($PackageIdExist) {
    Write-Host "Package exists"
}
Else {
    Write-Host "Error - Package does not exist"
    Exit 
}


Write-Host "Checking deployment...”
# Check if a deployment already exists for the package on the collection
$DeploymentList = Get-CMDeployment -CollectionName "$CollectionName"
ForEach ($CheckDeployment in $DeploymentList) {
    $CheckPackageID = $CheckDeployment.PackageID
    If ($CheckPackageID -eq $PackageId) {
        Write-Host "Error - A deployment of the package $PackageId on the collection $collectionName already exist"
		Exit
    }
}
Write-Host "No deployment of the package $PackageId on the collection $collectionName already exist"


Write-Host "Creating deployment of the package...”
# Create deployment for the package (asap after an available date/time, not overriding the maintenance window)
Try {
    $Time = Get-Date
    $Program = Get-CMProgram -PackageId $PackageId -ProgramName $ProgName
	$Deployment = Start-CMPackageDeployment -CollectionName $CollectionName -PackageId $PackageId -DeployPurpose Required -RerunBehavior RerunIfFailedPreviousAttempt -AllowUsersRunIndependently $true -ScheduleEvent AsSoonAsPossible -DeviceProgramName $($program.programname) -DeploymentAvailableDateTime $Time -StandardProgram
	Write-Host "Deployment of package $PackageId on the collection $CollectionName created"
}
Catch {
	Write-Host "Error - Exception caught in creating deployment : $error[0]"
}



##*===============================================
##* CREATE TASK SEQUENCE DEPLOYMENT
##*===============================================

Write-Host "Checking task sequence...”
# Check if the task sequence exist
$TaskSequenceIDExist = Get-CMTaskSequence -Id "$TaskSequenceId"
If ($TaskSequenceIDExist) {
    Write-Host "Task sequence exists"
}
Else {
    Write-Host "Error - Task sequence does not exist"
    Exit 
}


Write-Host "Checking deployment...”
# Check if a deployment already exists for the task sequence on the collection
$DeploymentList = Get-CMDeployment -CollectionName "$collection"
ForEach ($CheckDeployment in $DeploymentList) {
    $CheckPackageID = $CheckDeployment.PackageID
    If ($CheckPackageID -eq $TaskSequenceID) {
        Write-Host "Error - A deployment of the task sequence $TaskSequenceID on the collection $collectionName already exist"
		Exit
    }
}
Write-Log "No deployment of the task sequence $TaskSequenceID on the collection $collectionName already exist"


Write-Host "Creating deployment of the task sequence..."

# Create deployment for the task sequence (available 01.09.2013 08:00, enforced 25.12.2015 17:00, not overriding maintenance window)
$AvailableDate = "01.09.2016"
$AvailableTime = "08:00"
$EnforcementDate = "25.12.2016"
$EnforcementTime = "17:00"

# Format available date
Write-Host "AvailableDate  is $AvailableDate"
$AvailableDate = $AvailableDate.Split(".")
$AvailableDateFormat = $AvailableDate[2]+"/"+$AvailableDate[1]+"/"+$AvailableDate[0]
Write-Host "AvailableDate formated is $AvailableDateFormat"
# Check available date
If ($AvailableDateFormat -as [DateTime]) {
    Write-Host "AvailableDate ok"
}
Else {
    Write-Host "Error - AvailableDate not ok"
	Exit
}

# Check available time
Write-Host "AvailableTime is $AvailableTime"
If ($AvailableTime -as [DateTime]) {
    Write-Host "AvailableTime ok"
}
Else {
    Write-Host "Error - AvailableTime not ok"
	Exit
}

# Format enforcement date
Write-Host "EnforcementDate is $EnforcementDate"
$EnforcementDate = $EnforcementDate.Split(".")
$EnforcementDateFormat = $EnforcementDate[2]+"/"+$EnforcementDate[1]+"/"+$EnforcementDate[0]
Write-Host "EnforcementDate formated is $EnforcementDateFormat"
# Check enforcement date
If ($EnforcementDateFormat -as [DateTime]) {
    Write-Host "EnforcementDate ok"
}
Else {
    Write-Host "Error - EnforcementDate not ok"
	Exit
}

# Check enforcement time
Write-Host "EnforcementTime is $EnforcementTime"
If ($EnforcementTime -as [DateTime]) {
    Write-Host "EnforcementTime ok"
}
Else {
    Write-Host "Error - EnforcementTime not ok"
	Exit
}

# Format Enforcement date/time for WMI (Schedule object)
$EnforcementTimeWMIformat = Get-Date $EnforcementTime -format t
$EnforcementDateTimeWMIformat = $EnforcementDate[1]+"/"+$EnforcementDate[0]+"/"+$EnforcementDate[2]+" "+$EnforcementTimeWMIformat
Write-Host "EnforcementDateTime formated for WMI (Schedule object) is $EnforcementDateTimeWMIformat"

# Check if availability is before enforcement
$AvailableDateTime = $AvailableDateFormat +" "+$AvailableTime
$EnforcementDateTime = $EnforcementDateFormat +" "+ $EnforcementTime
If ((Get-Date $AvailableDateTime) -lt (Get-Date $EnforcementDateTime)) {
    Write-Host "Availablity is set before Enforcement, schedule ok"
}
Else {
    Write-Host "Error - Enforcement set before availability"
	Exit
}

# Create deployment
$Schedule = New-CMSchedule -Nonrecurring -Start $DeployEnforcementDateTime
Try {
    $Deployment = Start-CMTaskSequenceDeployment -CollectionName $Collection -TaskSequencePackageId $TaskSequenceID -DeployPurpose Required -DeploymentAvailableDay $AvailableDateFormat -DeploymentAvailableTime $AvailableTime -Schedule $Schedule -RerunBehavior RerunIfFailedPreviousAttempt -AllowUsersRunIndependently $True
    Write-Host "Deployment created"
} 
Catch {
	Write-Host "Error - Exception caught in creating deployment : $error[0]"
    Exit
}