Share via


Secure a Task Sequence with a Password

Introduction

Configuration Manager has very limited built-in functionalities to protect a Task Sequence from being executed. Sure you can define the scope of a certain task sequence deployment with deploying it only to certain collections. You also can set an PXE / Media Password to protect deployed task sequences from being executed.

But there are certain situation where you might have several available Task Sequences deployed to one collection or the Machine is member of a number of collection having Task Sequences deployed. For example, if your process allows to deploy against "unknown computers" and you are having your Prod TS and your Test TS deployed to that Collection.

 

Solution

To get around this problem, I wrote a little Powershell Scripts called OSD_PasswortChecker. This Scripts creates in the WinPE at the begin of the Deployment an Password Prompt.

Entering the correct Password allows to run the rest of the Steps in the Task Sequence.

Script

 

The Function of the OSD_PasswordChecker is simple, it protects your Task Sequence with a specified Password within a Task Sequence.

Here is the code of the Script:

 # Script OSD_PasswordChecker.ps1 - Version 1802
# ***** Disclaimer *****
# This file is provided "AS IS" with no warranties, confers no 
# rights, and is not supported by the authors or Microsoft 
# Corporation. Its use is subject to the terms specified in the 
# Terms of Use (https://www.microsoft.com/info/cpyright.mspx).
#

# -----------------------------------------------------------------------------------
# Function Section
# -----------------------------------------------------------------------------------
function ok-button {
 <#
 .SYNOPSIS
 Compares the entered Password with the OSDPassword 
 .DESCRIPTION
 Function to compare the Task Sequence Varibale "OSDPassword" with the entered Password
 #>

if($tsenv.Value("OSDPassword") -eq $MaskedTextBox) {
 $tsenv.Value("OSDPasswordChecked")=$True 
 }
}

# -----------------------------------------------------------------------------------
# Worker Section
# ----------------------------------------------------------------------------------- 
# Construct TSEnv object
try {
 $TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Stop
}
catch [System.Exception] {
 Write-Warning -Message "Unable to construct Microsoft.SMS.TSEnvironment object" ; exit 1
}

#GUI Creation
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "OSD PasswordChecker"
$objForm.Size = New-Object System.Drawing.Size(300,200) 
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True

$objForm.Add_KeyDown({
 if ($_.KeyCode -eq "Enter") {
 ok-button;$objForm.Close()
 }
})
$objForm.Add_KeyDown({
 if ($_.KeyCode -eq "Escape") {
 $objForm.Close()
 }
})

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({
 ok-button;$objForm.Close()
})
$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({
 $objForm.Close()
})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Please enter the information in the space below:"
$objForm.Controls.Add($objLabel)

$MaskedTextBox = New-Object System.Windows.Forms.MaskedTextBox
$MaskedTextBox.PasswordChar = '*'
$MaskedTextBox.Location = New-Object System.Drawing.Size(10,40) 
$MaskedTextBox.Size = New-Object System.Drawing.Size(260,20) 
$objForm.Controls.Add($MaskedTextBox) 
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})

[void] $objForm.ShowDialog()

You can download the Script + ServiceUI.exe (later described) here

Implementation

Please add the following steps at the beginning of your Task Sequence

 

Step: Set OSDPassword

Create a Step "Sets the Task Sequence Variable" in which you set the Task Sequence Variable "OSDPassword". The Value of this Variable will be used to check against the Input in the OSDPasswordChecker Script.

Step: Run OSDPasswordChecker

This Steps executes a Command Line to run the OSDPasswordChecker Powershell.

To create a GUI with Powershell in WinPE there are two Prerequisites needed:

  • Enable Powershell Feature in the Boot WIM
  • ServiceUI.exe needed to create a GUI in WinPE. By the way, we are using the same technique to launch the well known MDT UDI wizard.

The Command Line you need to run:

 ServiceUI.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File OSDPasswordChecker.ps1

 

Deployment Start Folder

The rest of the Task Sequence should be in a separate Folder Structure. In my case "Deployment Start".

Add on this folder the following Condition:

Comments

  • Anonymous
    February 24, 2018
    Interesting one! Though, this might be more a compliance feature than a security feature. Nevertheless, it will mitigate unallowed installations!All the best,David
  • Anonymous
    April 17, 2018
    Great post David! This was just what I was looking for to prevent accidental launch of our Windows 10 reimage task sequence. I did have a bit of trouble getting it to work in my environment though. It would not create the TS variable "OSDPasswordChecked" until I changed the IF statement to "if($tsenv.Value("OSDPassword") -eq ($MaskedTextBox).text) . Without that it seemed like it was comparing apples to oranges. I am kinda new at PowerShell, so I am not sure if it is just my implementation of your script that causes the need for that change.John
  • Anonymous
    April 17, 2018
    Sorry Y.Perrenoud I am giving credit to the wrong person! It's been a long day!
  • Anonymous
    April 27, 2018
    Great stuff. Some feedback: I would encourage to use a Dynamic variable for the OSDPassword so it is at least not visible in clear text when editing the TS.
  • Anonymous
    April 27, 2018
    Nice addition with this in TP1804 https://docs.microsoft.com/en-us/sccm/core/get-started/capabilities-in-technical-preview-1804#improvements-to-os-deployment
  • Anonymous
    June 29, 2018
    where does one get ServiceUI.exe? is it already part of the winpe image? i'm trying to use this to password protect my win10 in-place upgrade TS (runs in production windows, not winpe), but it's not working since it can't find serviceui.exe. suggestions?
    • Anonymous
      July 09, 2018
      You can download the ServiceUI here