Sometimes when running an SCCM task sequence, you want to prompt for input, for example to populate a Task Sequence variable that you will use later. In this example, I am encrypting a laptop HDD (SED) using Wave ERAS, and I’m using a command-line tool that populates the pre-boot authentication screen with the AD account of the laptop end-user. This runs during a post-deployment task sequence that provisions the encryption. As each laptop is prepared for a different end user, I needed to prompt for the user account during the task sequence, then pass the input to a script that adds the account to the encryption pre-boot.
To accomplish this I decided to use a Powershell script with ServiceUI.exe to prompt for and set the TS variable, then pass this variable to the encryption script as a parameter. I tested it using SCCM 2012R2 integrated with MDT2013, but I can’t see why it wouldn’t work in older versions that support ServiceUI.exe.
Here’s the ‘how to’:
Create a Package
First, create a package in SCCM that contains the Powershell script below, and the ServiceUI.exe. ServiceUI.exe comes with MDT and allows you to break out of the TS session into the user session, where you can interact. Since I still deploy some x86 OS’s at times, I decided to include both the x86 and x64 version of the executable in the same package, and rename them accordingly, although the x86 version will probably work for both architectures. Then I use a TS condition to create separate steps for x86 and x64.
You can find the ServiceUI.exe here:
C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64, or
C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x86
<# PromptForUsername v1 ----------------- This script prompts for input during a task sequence, and sets the input as a TS variable. #> # Close the TS UI temporarily $TSProgressUI = New-Object -COMObject Microsoft.SMS.TSProgressUI $TSProgressUI.CloseProgressDialog() # Prompt for input [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null $TSUsername = [Microsoft.VisualBasic.Interaction]::InputBox("Enter the username of the end user", "Username prompt", "eg tjones") # Set the TS variable $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $tsenv.Value("TSUsername") = $TSUsername
Distribute your package to your DPs, no program is required for it.
What does the script do?
First, it hides the task sequence UI while the prompt is displayed, otherwise it will appear behind the UI. Second, we prompt for the input. Lastly we pass the input into a new TS variable called %TSUsername%.
Add Task Sequence Steps
Next, we will add a step to the task sequence that prompts for the username. Add a ‘Run Command Line’ step and use the package you created. Call the ServiceUI_x86.exe with the following parameters:
ServiceUI_x86.exe -process:TSProgressUI.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File PromptForUsername.ps1
Do the same for the x64 version of ServiceUI, if you are using both versions. You can set a simple OS version condition on each task to determine the architecture:
Next I update my ‘add user’ step passing the %TSUsername% variable into the parameters of the command:
When the task sequence runs, it will prompt for the username:
It then adds the user into the preboot authentication via the script. We can see from the SMSTS.log that it correctly substitutes the variable when running the command:
This example uses a non-deployment task sequence; it should also work during a deployment, although I didn’t test it yet 🙂 To work during the WinPE phase, you will need to add Powershell support to your boot image. For OS deployment there are more elegant ways of getting input during the WinPE Phase, such as Jason Sandys’ OSD++, or by using an HTA, but that may seem a bit much if just one or two inputs are required, so this is an excellent and easily implemented alternative that can be used during any task sequence.
10 thoughts on “Prompting for Input During a Task Sequence”
Great work here, Trevor. I’m looking at your work here and attempting to modify it to fit my needs for a similar request. We just need to prompt for input for a small string of text during the OSD and after the deployment has completed, write that file the the root of the drive.
Hi, thank you for this great post. I’m wondering is I can do kind of the same process but in different way, let said, instead to prom for “Computer name” could be possible prompt for “Domain user name” store it as a TS variable, then connect to AD to get user name, an so get the user department and from that generate a computer name following standards like e.g. Domain + Laptop or Workstation + department + consecutive number (MSWIT001). I’ll appreciate any help. Thank you,
Yes I’m sure that entirely possible. Once you have the TS variable set, you can pass it to a step that runs a Powershell script for example, which will go ahead and query your AD, determine the computer name, and use it to set the OSDComputerName TS variable.
First of all, congratulation for it’s good post!
I’m looking for a think like that, I need a prompt to the user that is deploying the image that ask him to enter the OS image version and grab the value to the registry. Is that possible?
Thanks. Yes that’s possible, but for something like that I would suggest to take a look at Jason Sandy’s UI++. He also had a script on his blog that will let you write OS deployment info to WMI and the registry,
thanks a lot for sharing and explaining this. I’ve used it to prompt for the old computername in an USMT task sequence.
Can this be leveraged to prompt for all users logged in a system.
Basically, Run the litetouch.vbs via psexec warn logged on user and proceed
I just tried this during a deployment and it works….for the most part. In your testing, did you have a yellow warning screen at the end of the wizard? Everything seems to have worked but I still see the yellow soft-warning screen.
I’ve tried similar script to prompt computer name and check if that computer name exist on server path if not it will pop up the box and ask to re-enter computer name. The issue I run into is that when trying to use USMT loadstate.exe to restore data from that computer name it can’t pick up that computer name again. Checking smsts log file it shows error of not seeing the %OSDComputerrname% in the path. If take away the checking of correct computer name then task sequence runs fine. Here is my code:
# Show input box popup and return the value entered by the user.
function Get-InputBoxDialog([string]$Message, [string]$WindowTitle)
Add-Type -AssemblyName Microsoft.VisualBasic
return [Microsoft.VisualBasic.Interaction]::InputBox($Message, $WindowTitle)
$OSDComputerName = Get-InputBoxDialog -Message “Enter OLD ComputerName” -WindowTitle “Source PC”
$SrcPath = “\\Server\Migfolder\$OSDComputerName”
} until (Test-Path $SrcPath)
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
$tsenv.Value(“OSDComputername”) = $OSDComputername