Configuration Manager Phased Deployments with PowerShell
Published Jun 11 2020 09:43 AM 4,922 Views
Microsoft

 

With the release of Microsoft Endpoint Configuration Manager version 2002 came several new PowerShell cmdlets, including those that relate to phased deployments. The phased deployments feature has been out of pre-release since version 1806, with the ability to use them for software updates being added in version 1810. More information on the phased deployments feature can be accessed using the phased deployments link above, as well as details on monitoring and control over progress here. The focus of this post will be around using the new cmdlets for phased deployments, rather than the phased deployments feature in general.

 

Disclaimer

NOTE: Script examples in this post are intended to help illustrate the syntax and use of specific PowerShell cmdlets, and do not include all of the usual exception handling or other standard scripting practises that should be used in production scripts. Some values are “hard-coded” from my lab environment for illustration purposes. The following disclaimer applies to all script code contained within this post:

 

This sample script is not supported under any Microsoft standard support program or service.

The sample script is provided “AS IS” without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.

 

With that out of the way…

 

Automatic vs. Manual

Although the focus of this post is the cmdlets and not the feature in general, because there are different cmdlets for creating automatic and manual phased deployments, it’s worth a brief explanation before we go any further.

 

Automatic phased deployments

When creating an automatic phased deployment, you are opting for a two-phase deployment to 2 collections of your choosing. Automatic phased deployments are currently the only option available for applications, where you would have the manual option disabled:

 

Paul_Ivey_0-1591884463448.png

 

When you opt for this approach, you define success criteria based on percentage or number of devices successfully deployed to, and then specify how many days after the first successful phase (based on the aforementioned criteria) the next and final phase should begin. You still have control to suspend/resume each phase, but the progression happens automatically based on your settings rather than requiring you to manually progress to the next phase:

 

Paul_Ivey_1-1591884463453.png

 

Manual phased deployments

When creating a manual phased deployment, you can create more deployment phases with the same settings as previously mentioned, but with greater control over the user experience in some cases, plus the ability to set the phase progression to be manual:

 

Paul_Ivey_2-1591884463456.png

 

Basic examples

Below are some very basic examples of using the PowerShell cmdlets to create automatic and manual phased deployments before a more advanced demonstration. These examples primarily focus on creating the phased deployments, but note that there are also “Get-“ cmdlets to obtain the details/objects of phased deployments.

 

Automatic phased deployments

The structure of the automatic phased deployments is essentially the same for applications, software updates and task sequences:

 

 

 

 

 

Cmdlet-Name -ObjectName "YourObjectName" -Name "YourPhasedDeploymentName" `
-FirstCollectionID "<CollectionID>" -SecondCollectionID "<CollectionID>" `
-CriteriaOption Compliance or Number -CriteriaValue 95 `
-BeginCondition AfterPeriod -DaysAfterPreviousPhaseSuccess 2 `
-ThrottlingDays 3 -InstallationChoice AfterPeriod or AsSoonAsPossible `
-DeadlineUnit Hours or Days or Weeks or Months -DeadlineValue 4 `
-Description "YourDescription"

 

 

 

 

 

Here’s a breakdown of each element and – where possible – how they relate to the GUI experience:

  • Cmdlet-Name is the name of the cmdlet. Available options for automatic phased deployments are:
    • New-CMApplicationAutoPhasedDeployment for applications
    • New-CMSoftwareUpdateAutoPhasedDeployment for software updates
    • New-CMTaskSequenceAutoPhasedDeployment for task sequences
  • -ObjectName is a parameter that changes depending on what you’re deploying, and the value is the name/Id/object of the object. Available options are:
    • -Application or -ApplicationId or -ApplicationName
    • -SoftwareUpdates or -SoftwareUpdateIds or -SoftwareUpdateNames or -SoftwareUpdateGroup or -SoftwareUpdateGroupId or -SoftwareUpdateGroupName
    • -TaskSequence or -TaskSequenceId or -TaskSequenceName
  • -Name is the name you wish to give to your new phased deployment

Paul_Ivey_3-1591884463457.png

 

  • -FirstCollectionID is the CollectionID for the desired phase 1 collection
  • -SecondCollectionID is the CollectionID for the desired phase 2 collection

Paul_Ivey_4-1591884463457.png

 

  • -CriteriaOption relates to the success criteria, whether that be based on a percentage of successful deployments or number of devices successfully deployed to. Available options are:
    • Compliance
    • Number
  • -CriteriaValue relates to the value you specify either next to the success percentage or the number of devices successfully deployed to

Paul_Ivey_5-1591884463460.png

 

  • -BeginCondition relates to the next section that you would see in the GUI where you specify how soon after the previous phase was deemed successful to begin this phase. For automatic phased deployments, AfterPeriod is the only option to use here
  • -DaysAfterPreviousPhaseSuccess relates to the number of days after the previous phase was deemed successful that you wish to begin this phase

Paul_Ivey_6-1591884463461.png

 

  • -ThrottlingDays relates to the number of days over which you wish to make the software available

Paul_Ivey_7-1591884463462.png

 

  • -InstallationChoice relates to the desired deadline behaviour relative to when the software is made available. Available options are:
    • AfterPeriod
    • AsSoonAsPossible
  • -DeadlineValue is only required if the InstallationChoice is set to AfterPeriod and is the number of hours/days/weeks/months after which you wish to make the installation required from when the software is made available
  • -DeadlineUnit is only required if the InstallationChoice is set to AfterPeriod and relates directly to the value specified in DeadlineValue. Available options are:
    • Hours
    • Days
    • Weeks
    • Months

Paul_Ivey_8-1591884463462.png

 

  • Description is the description you wish to give to your new phased deployment

Paul_Ivey_9-1591884463463.png

 

This is a script example of creating an automatic application phased deployment from my lab:

 

 

 

 

 

New-CMApplicationAutoPhasedDeployment -ApplicationName "Microsoft Edge (81.0.416.72)" `
-Name "Demo Application Phased Deployment" -FirstCollectionID "PS10001B" `
-SecondCollectionID "PS10001C" -CriteriaOption Compliance -CriteriaValue 95 `
-BeginCondition AfterPeriod -DaysAfterPreviousPhaseSuccess 2 -ThrottlingDays 3 `
-InstallationChoice AfterPeriod -DeadlineUnit Hours -DeadlineValue 4 `
-Description "Description for my demo application phased deployment."

 

 

 

 

 

Now within the console we can see a newly created phased deployment with my specified settings, created within seconds:

 

Paul_Ivey_10-1591884463464.png

 

Paul_Ivey_11-1591884463465.png

 

Paul_Ivey_12-1591884463466.png

 

Manual phased deployments

With manual phased deployments the structure differs from the automatic phased deployments in a few ways. The first of which is that you first create the phases, then you create the phased deployment that uses those phases. Another difference is that you use some additional parameters that aren’t available/required in automatic deployments.

 

Create phases

An example of the minimal format for creating a new software update phase is:

 

 

 

 

 

New-CMSoftwareUpdatePhase -CollectionName "<CollectionName>" -PhaseName "YourPhaseName" `
-UserNotificationOption DisplaySoftwareCenterOnly

 

 

 

 

 

An example of the minimal format for creating a new task sequence phase is:

 

 

 

 

 

New-CMTaskSequencePhase -CollectionName "<CollectionName>" -PhaseName "YourPhaseName" `
-UserNotification DisplayAll -AllowRemoteDP $true

 

 

 

 

 

The above examples are very minimal, and some options like CollectionName could be substituted (as explained below). There are a lot of additional parameters available for further control, demonstrated below. The examples I will use from here on are specific to the software updates phases and deployment, as the interest from my customers in these cmdlets has mostly been related to software updates. Note that there are differences in some of the parameters between software updates and task sequences, and you can see the syntax using the usual PowerShell “Get-Help” cmdlet.

 

Here’s a breakdown of the available parameters when using the New-CMSoftwareUpdatePhase cmdlet and – where possible – how they relate to the GUI experience. I will list them in the order in which the relevant settings would appear in the GUI to make it more relatable (remember – this section is the phase creation, not yet the phased deployment itself, so the software updates are not selected during this process – that comes later):

  • -PhaseName is the name you wish to give to the phase
  • -PhaseDescription is the description you wish to give to the phase
  • -CollectionId is the CollectionID of the collection to which you wish to deploy during this phase. Instead of using the CollectionId parameter, you could also use any of the following:
    • Collection is a collection object passed to this parameter
    • CollectionName is the name of the collection

Paul_Ivey_13-1591884463467.png

 

  • -EnableWakeOnLan defines if Wake-on-LAN should be used. This is a Boolean (true/false) parameter
  • -StateMessageVerbosity is the state message details level return by clients. Available options are:
    • OnlyErrorMessages
    • OnlySuccessAndErrorMessages
    • AllMessages

Paul_Ivey_14-1591884463468.png

 

  • -CriteriaOption is the type of criteria you wish to use to deem the previous phase as having been a success. Available options are:
    • Compliance
    • Number
  • -CriteriaValue is the value for the success percentage or number of devices successfully deployed to, depending on the CriteriaOption selected
  • -BeginCondition is how you define if the phase should begin automatically after a period of days or to require manual progression. Available options are:
    • AfterPeriod
    • Manually
  • -DaysAfterPreviousPhaseSuccess is only required if the BeginCondition is set to AfterPeriod, and is how you define the number of days after the previous phase having been deemed a success that this phase is to begin
  • -ThrottlingDays is how you define the number of days over which the software should be gradually made available. Default is 0
  • -InstallationChoice is how you define the deadline behaviour relative to the when the software is made available. Available options are:
    • AsSoonAsPossible
    • AfterPeriod
  • -DeadlineValue is only required if the InstallationChoice is set to AfterPeriod and is the number of hours/days/weeks/months after which you wish to make the installation required from when the software is made available
  • -DeadlineUnit is only required if the InstallationChoice is set to AfterPeriod and relates directly to the value specified in DeadlineValue. Available options are:
    • Hours
    • Days
    • Weeks
    • Months

Paul_Ivey_15-1591884463470.png

 

  • -UserNotificationOption is how you define the user visual experience for the phase. Available options are:
    • HideAll
    • DisplayAll
    • DisplaySoftwareCenterOnly
  • -SoftwareInstallation is how you define whether software updates installation should be allowed outside of maintenance windows. This is a Boolean (true/false) parameter
  • -AllowSystemRestart is how you define whether system restarts should be allowed outside of maintenance windows (if required). This is a Boolean (true/false) parameter
  • -ServerRestartSuppression is how you define whether system restarts should be suppressed on servers (if required). This is a Boolean (true/false) parameter
  • -WorkstationRestartSuppression is how you define whether system restarts should be suppressed on workstations (if required). This is a Boolean (true/false) parameter
  • -WriteFilterCommit is how you define write filter handling for Windows Embedded devices. This is a Boolean (true/false) parameter
  • -RequirePostRebootFullScan is how you define whether systems should run an updates deployment evaluation cycle after a system restart if an update in the deployment requires a system restart. This is a Boolean (true/false) parameter

Paul_Ivey_16-1591884463472.png

 

  • -EnableAlert is how you enable alerts for this phase
  • -AlertThresholdPercentage is how you specify the deployment compliance percentage threshold before generating an alert
  • -AlertDelta is the value that relates to the AlertUnit parameter
  • -AlertUnit is how you specify the offset unit from the deadline before the alert conditions will be evaluated. Available options are:
    • Hours
    • Days
    • Weeks
    • Months
  • -DisableSCOMAlert is how you disable SCOM alerts while software updates run. This is a Boolean (true/false) parameter
  • -GenerateSCOMAlertOnFailure is how you specify if SCOM alerts should be generated in the event of a software update installation failing. This is a Boolean (true/false) parameter

Paul_Ivey_17-1591884463474.png

 

  • -UseNeighborDP is how you specify whether clients should be allowed to download and install the software updates from a distribution point in a neighbour boundary group or the default site boundary group. This is a Boolean (true/false) parameter
  • -UseSiteDefaultDP is how you specify whether clients should be allowed to download and install software updates from distribution points in the site default boundary group. This is a Boolean (true/false) parameter
  • -AllowWUMUFallback is how you specify whether clients should be allowed to download and install software updates from Microsoft Updates, should the content not be available on any distribution points
  • -AllowMeteredConnection is how you specify whether to allow clients to download software updates over a metered internet connection. This is a Boolean (true/false) parameter

Paul_Ivey_18-1591884463476.png

 

Script example creating 3 phases with different settings

Here is a very basic example of me creating 3 phases with different settings. Notice how certain parameters have either been included or excluded depending on other parameters – for example, when the BeginCondition parameter is set to Manually, there is no need to include the DaysAfterPreviousPhaseSuccess parameter, as it will just be ignored anyway. Also, by default, Boolean parameters are set to false if not specified:

 

 

 

 

 

# As this is phase 1, there is no need to specify success criteria or begin condition.
# Adding in the alert options even when the alert isn’t enabled makes the exporting and
# importing process work more smoothly for my scripts, otherwise they wouldn’t be required.
# Boolean parameters that aren't specified are defaulted to $false

$phase1 = New-CMSoftwareUpdatePhase -PhaseName "Demo Phase 1" `
-PhaseDescription "Demo phase 1 description" -CollectionId "PS10001B" `
-EnableWakeOnLan $false -StateMessageVerbosity OnlyErrorMessages `
-ThrottlingDays 2 -InstallationChoice AfterPeriod `
-DeadlineUnit Hours -DeadlineValue 5 -UserNotificationOption DisplaySoftwareCenterOnly `
-SoftwareInstallation $true -AllowSystemRestart $true `
-ServerRestartSuppression $true -WorkstationRestartSuppression $false `
-RequirePostRebootFullScan $true -EnableAlert $false AlertThresholdPercentage 90 -AlertUnit Days -AlertDelta 2

# As this is phase 2, it makes more sense to specify some additional parameters.
# Boolean parameters that aren't specified are defaulted to $false

$phase2 = New-CMSoftwareUpdatePhase -PhaseName "Demo Phase 2" `
-PhaseDescription "Demo phase 2 description" -CollectionId "PS10001C" `
-EnableWakeOnLan $true -StateMessageVerbosity OnlySuccessAndErrorMessages `
-CriteriaOption Compliance -CriteriaValue 98 `
-BeginCondition AfterPeriod -DaysAfterPreviousPhaseSuccess 1 `
-ThrottlingDays 0 -InstallationChoice AsSoonAsPossible `
-UserNotificationOption HideAll -SoftwareInstallation $true -AllowSystemRestart $true `
-ServerRestartSuppression $false -WorkstationRestartSuppression $true `
-EnableAlert $true -AlertThresholdPercentage 90 -AlertUnit Days -AlertDelta 2 -UseNeighborDP $true

# Phase 3 will have much the same settings as phase 2, but with manual progression being required
# Boolean parameters that aren't specified are defaulted to $false

$phase3 = New-CMSoftwareUpdatePhase -PhaseName "Demo Phase 3" `
-PhaseDescription "Demo phase 3 description" -CollectionId "PS10001D" `
-EnableWakeOnLan $true -StateMessageVerbosity OnlySuccessAndErrorMessages `
-CriteriaOption Compliance -CriteriaValue 98 -BeginCondition Manually `
-ThrottlingDays 0 -InstallationChoice AsSoonAsPossible -UserNotificationOption HideAll `
-SoftwareInstallation $true -AllowSystemRestart $true `
-ServerRestartSuppression $false -WorkstationRestartSuppression $true `
-EnableAlert $true -AlertThresholdPercentage 90 -AlertUnit Days -AlertDelta 2 -UseNeighborDP $true

 

 

 

 

 

Execution of the above code and creation of the 3 demo phases only took a couple of seconds to complete. Now that we have the phases created, we can create the phased deployment and add these 3 phases to it.

 

Create manual phased deployment

An example of the minimal format for creating a new software update manual phased deployment is:

 

 

 

 

 

New-CMSoftwareUpdateManualPhasedDeployment -SoftwareUpdateGroupName "<SoftwareUpdateGroupName>" `
-Name "Your Phased Deployment Name" -AddPhases ($phase1, $phase2, $phase3)

 

 

 

 

 

As with the previous minimal examples, some parameters can be substituted or added – for example, -Description would allow you to set a description for the phased deployment and -SoftwareUpdateGroupName could be substituted for -SoftwareUpdateGroupId. Here’s a breakdown of the available parameters when using the New-CMSoftwareUpdateManualPhasedDeployment cmdlet and – where possible – how they relate to the GUI experience. I will list them in the order in which the relevant settings would appear in the GUI to make it more relatable:

  • Before the phased deployment wizard starts, you would have already selected your update/s, or software update group. Available parameters to specify to which object/s the phased deployment will apply are:
    • -SoftwareUpdates takes an object array containing software update objects
    • -SoftwareUpdateIds takes a string array containing the unique IDs of each software update
    • -SoftwareUpdateNames takes a string array containing the names of each software update
    • -SoftwareUpdateGroup takes an SMS_AuthorizationList object
    • -SoftwareUpdateGroupId takes the CI_ID of the software update group as a string
    • -SoftwareUpdateGroupsName takes the name of the software update group as a string
  • -Name is the name you wish to give to the phased deployment
  • -Description is the description you wish to give to the phased deployment

Paul_Ivey_19-1591884463477.png

 

  • -AddPhases is how you specify which phases to include in this phased deployment and is an array of phases

Paul_Ivey_20-1591884463478.png

 

Script example creating a manual phased deployment including the 3 phases previously created

Here is a very basic example of me creating the manual software updates phased deployment, including the 3 phases created in the last script example:

 

 

 

 

 

New-CMSoftwareUpdateManualPhasedDeployment -SoftwareUpdateGroupId "16781049" `
-Name "Demo Phased Deployment Created with PowerShell" `
-Description "Here's my description, also added with PowerShell" `
-AddPhases ($phase1, $phase2, $phase3)

 

 

 

 

 

The execution of the above code and creation of the phased deployment took only a few seconds, and here we can see it within the console:

 

Paul_Ivey_21-1591884463479.png

 

Paul_Ivey_22-1591884463480.png

 

Phase 1 phase settings:

 

Paul_Ivey_23-1591884463482.png

 

Phase 2 phase settings:

 

Paul_Ivey_24-1591884463483.png

 

Phase 3 phase settings:

 

Paul_Ivey_25-1591884463485.png

 

All other settings from the scripts are visible in the GUI, too.

 

One example from the field

One of my customers wanted to make use of software update phased deployments, but wanted to see if it was possible to have an easily repeatable process for creating a full phased deployment without manually doing it in the GUI each patch cycle. Their specific requirement was to have the phases manually progressed rather than automatically. As a proof-of-concept, I decided to create my own right-click tools – one to export the phase settings from an existing phased deployment to an XML file that can be edited (carefully!) if needed. The other was to select a software update group and create a phased deployment using all the phases and their settings specified within the XML file. This is purely to illustrate one example of how these cmdlets can be used and not a tutorial of how to create right-click tools or the specific script I created for it.

 

Let’s take the phased deployment we just created and export those settings to XML:

 

Paul_Ivey_26-1591884463487.png

 

Paul_Ivey_27-1591884463489.png

 

Opening the resulting XML provides me with similar settings to those we examined earlier, with some differences in wording (these differences needed to be catered for in my script):

 

Paul_Ivey_28-1591884463498.png

 

In production, I would have likely added additional elements for the phased deployment name and description etc. For demonstration purposes, I’ve changed the phase 1 name and ID to “Demo Phase 1 from XML”, and renamed the XML file to “Demo Phased Deployment Created from XML.xml”:

 

Paul_Ivey_29-1591884463507.png

 

Now I can use the second right-click tool to select a software update group and create a manual phased deployment using the settings defined within the XML file:

 

Paul_Ivey_30-1591884463511.png

 

Paul_Ivey_31-1591884463513.png

 

After the script runs, we can see the phased deployment was created exactly how we wanted, based on the exported XML:

 

Paul_Ivey_32-1591884463516.png

 

The above was just one example of how you can use these new cmdlets. This example would allow my customer to have a predefined template from which to create their monthly phased deployments – Not too bad while everybody eagerly awaits phased deployments in ADRs: https://configurationmanager.uservoice.com/forums/300492-ideas/suggestions/36944143-support-phased-d...!

 

I hope this post has been helpful to you, good luck in your scripting!

 

As always, please keep sending suggestions, smiles and frowns to provide us with valuable feedback, which all help towards creation of great features like the one discussed in this blog post.

 

Paul Ivey

@paul_msft

My CIS Tech Community Blog Posts

Senior Customer Engineer (formally PFE)

Co-Authors
Version history
Last update:
‎Mar 22 2022 09:16 AM
Updated by: