What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Configuration Manager does not automatically turn task-sequence variables into ordinary PowerShell variables. For a simple input, pass the value through the Run PowerShell Script step’s Parameters field, for example -ComputerName '%_SMSTSMachineName%'. When a script must read, create, or update task-sequence state, use the Microsoft.SMS.TSEnvironment COM object:
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$value = $tsenv.Value('DeployEnvironment')
$tsenv.Value('DeploymentResult') = 'Success'
The methods apply to PowerShell scripts running inside an active Microsoft Configuration Manager task sequence, including Windows PE and the full operating system phases.
Understand the four variable namespaces
A Configuration Manager task-sequence variable is state maintained by the task-sequence engine. It is not automatically a PowerShell variable, a Windows process environment variable, or a script parameter.
- Built-in variables: Engine-created values such as
_SMSTSLogPathand_SMSTSMachineName. - Action variables: Values that may exist only while a particular action is running; their lifetime is step-dependent.
- Custom variables: Administrator- or script-created workflow values.
- Collection and device variables: Values assigned in the Configuration Manager console.
- Array variables: Structured data exposed as flattened names such as
OSDPartitions0FileSystem.
Configuration Manager evaluates collection variables first, device-specific variables override collection values, and values set during the running task sequence take precedence over both. See Microsoft’s task-sequence variable documentation.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →#1 Best Overall
- Book - powershell for sysadmins: workflow automation made easy
- Language: english
- Binding: paperback
Choose the right method
| Need | Use |
|---|---|
| One or two explicit script inputs | Script parameters with %VariableName% in the step’s Parameters field |
| Read or write several values | Microsoft.SMS.TSEnvironment |
| Return one calculated result | Output to task sequence variable |
| Set a fixed value | Set Task Sequence Variable |
| Choose values from rules | Set Dynamic Variables |
Read a task-sequence variable inside PowerShell
Read a custom variable
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$deploymentType = $tsenv.Value('DeploymentType')
Write-Output "DeploymentType: $deploymentType"
Value() is the documented interface for retrieving a task-sequence variable. Do not expect $env:DeploymentType to contain the value; that syntax accesses the Windows process environment instead.
Read built-in values
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$logPath = $tsenv.Value('_SMSTSLogPath')
$machineName = $tsenv.Value('_SMSTSMachineName')
Write-Output "Machine: $machineName"
Write-Output "Task-sequence log path: $logPath"
Validate a required value
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$appChannel = $tsenv.Value('AppChannel')
if ([string]::IsNullOrWhiteSpace($appChannel)) {
throw 'Required task-sequence variable AppChannel is missing or empty.'
}
Check that the spelling matches, that the producing step ran earlier, and that the variable is available in the current scope.
Pass a variable as a script parameter
- Create or populate the variable earlier in the sequence, for example with Add → General → Set Task Sequence Variable, using
AppChannelas the name andPilotas the value. - Add Add → General → Run PowerShell Script.
- Use a parameterized script:
param(
[Parameter(Mandatory)]
[string]$Channel
)
Write-Output "Selected channel: $Channel"
- In the step’s Parameters field, enter:
-Channel '%AppChannel%'
Configuration Manager expands %AppChannel% before PowerShell receives the argument. In this field, use single quotation marks around values that may contain spaces or special characters; Microsoft warns that double quotation marks can be processed incorrectly in this step. See the Run PowerShell Script step documentation.
Rank #2
Inline script example
For an inline script, pass the value through Parameters rather than generating PowerShell source code:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →-SourcePath '%OSDTargetSystemDrive%Installers'
param([string]$SourcePath)
if (-not $SourcePath) {
throw 'SourcePath was not supplied.'
}
Write-Output "Using source path: $SourcePath"
The Parameters field is for arguments consumed by your script. Do not put host options such as -NoLogo -ExecutionPolicy Unrestricted -File MyScript.ps1 there.
Set or update a variable for later steps
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$tsenv.Value('DeploymentResult') = 'Success'
$tsenv.Value('DeploymentTimestamp') = (Get-Date).ToString('s')
Assigning a nonexistent name creates it; assigning an existing name updates it. Subsequent steps can test DeploymentResult with a task-sequence condition such as Task Sequence Variable DeploymentResult equals “Success”. To delete a custom variable, assign an empty string:
Rank #3
$tsenv.Value('DeploymentResult') = ''
Underscore-prefixed variables are generally read-only. Read _SMSTSLogPath, but write a separate custom variable instead of attempting to replace it.
Capture one result with Output to task sequence variable
When a script has one simple result, configure the Run PowerShell Script step’s Output to task sequence variable setting. For example, use this script:
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute(Get-Culture).TwoLetterISOLanguageName
Set the output variable name to CurrentOSLanguage. A later step can use the condition Task Sequence Variable CurrentOSLanguage equals “en”. Standard output becomes the stored value, so do not mix diagnostic text with the result:
Rank #4
# Good: emits only the value
(Get-Culture).TwoLetterISOLanguageName
Use TSEnvironment when you need multiple outputs or precise control over when values are written.
Import all variables (optional)
Microsoft documents this convenience pattern:
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$tsenv.GetVariables() | ForEach-Object {
Set-Variable -Name $_ -Value $tsenv.Value($_)
}
A variable named DeploymentType can then be referenced as $DeploymentType. Explicit retrieval is usually safer: it makes dependencies auditable, avoids collisions with automatic PowerShell variables, and reduces accidental exposure of secrets. Names containing hyphens are also awkward as PowerShell identifiers, so access them through Value('Name-With-Hyphen').
Protect credentials and other secrets
- Do not pass a password as
-Password '%AdminPassword%'unless you have accepted the logging consequences. - Use a hidden task-sequence variable and retrieve it through
TSEnvironmentwhere possible. - Never write secrets to standard output or diagnostic logs.
- Configuration Manager warns that expanded command-line values can appear in
smsts.log. If command-line expansion is unavoidable, Microsoft documentsOSDDoNotLogCommand=TRUEas a mitigation.
Hidden variables are concealed from specified console, log, and debugger surfaces; they are not encrypted or impossible for an executing script to read. Treat them as usable runtime secrets, not as a complete security boundary.
Best Value
Windows PE, full Windows, and standalone testing
The COM-object method requires an active task-sequence context. It is intended for scripts launched by the task-sequence engine in Windows PE or the full operating system. The Setup Windows and ConfigMgr transition changes phases, but the task-sequence environment remains the documented source of variables. Scripts launched manually outside the engine will not have that COM object.
For a reusable script, make the parameter the primary interface and fall back to the task-sequence environment:
param(
[string]$DeploymentType
)
if (-not $DeploymentType) {
try {
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Stop
$DeploymentType = $tsenv.Value('DeploymentType')
}
catch {
Write-Verbose 'Not running inside a Configuration Manager task sequence.'
}
}
if (-not $DeploymentType) {
throw 'DeploymentType was not supplied.'
}
Write-Output "Deployment type: $DeploymentType"
This distinguishes a script parameter from a task-sequence variable and from a normal Windows environment variable.
Variable limits, arrays, and lifetime
- Names may contain letters, numbers, underscores, and hyphens, cannot contain embedded spaces, and are limited to 256 characters.
- The task-sequence environment has an 8 KB total size limit; an individual value cannot exceed 4,000 characters.
- Values can be case-sensitive depending on use; password values are case-sensitive.
- Array data is exposed through flattened member names. For example:
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$filesystem = $tsenv.Value('OSDPartitions0FileSystem')
$size = $tsenv.Value('OSDPartitions0Size')
Do not assume every array is available as a native PowerShell array. If an action variable must survive beyond its step, copy it to a custom variable before the action ends:
$tsenv.Value('SavedWorkingDirectory') = $tsenv.Value('WorkingDirectory')
Troubleshoot common failures
| Symptom | Likely cause and fix |
|---|---|
| Empty value | The variable is misspelled, set later, out of scope, or overridden. Verify ordering, spelling, and precedence. |
Literal %Var% |
The field does not support substitution, or the syntax was placed inside the script body. Use the Parameters field or TSEnvironment. |
| Script parameter rejected | Host options were entered instead of arguments matching the script’s param() block. |
| Value works in one step only | It may be an action variable whose lifetime ended. Copy it to a custom variable. |
Secret appears in smsts.log |
The value was expanded into a command line. Prefer hidden variables and in-script retrieval. |
| COM creation fails | The script is not running inside the expected active task-sequence context, or it was launched manually. |
| Output variable contains extra text | Diagnostics were written to standard output. Emit only the intended value. |
| Runtime value differs from console value | Device or runtime precedence has overridden the collection value. |
Write a safe diagnostic log
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$logPath = $tsenv.Value('_SMSTSLogPath')
$logFile = Join-Path $logPath 'ReadTaskSequenceVariable.log'
"Timestamp: $(Get-Date -Format o)" |
Out-File -FilePath $logFile -Append -Encoding default
"AppChannel: [$($tsenv.Value('AppChannel'))]" |
Out-File -FilePath $logFile -Append -Encoding default
Never include passwords, tokens, or other secrets in this diagnostic output.
Bottom line
Use %VariableName% in the Run PowerShell Script step’s Parameters field for explicit, simple inputs. Use Microsoft.SMS.TSEnvironment when the script must inspect or change task-sequence state. Use output capture for one calculated value, validate required inputs, respect variable scope and ordering, and design secret handling around the fact that command-line expansion can expose values in task-sequence logs.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




