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.
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…
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.
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:
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:
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:
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.
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:
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:
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):
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:
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:
Phase 1 phase settings:
Phase 2 phase settings:
Phase 3 phase settings:
All other settings from the scripts are visible in the GUI, too.
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:
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):
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”:
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:
After the script runs, we can see the phased deployment was created exactly how we wanted, based on the exported XML:
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
My CIS Tech Community Blog Posts
Senior Customer Engineer (formally PFE)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.