Export SCCM task sequence variables with PowerShell

Whenever starting with a new technology or project, I try to gather as much information as possible to get an idea of what I'm working with.  I've recently started working with SCCM task sequences, and similar to MDT, there are built-in task sequence steps that cover the basic tasks that most system administrators need to perform.  However, as environments become more complex and we are asked to do more and to do it efficiently, we sometimes need to get deep into the weeds and pull out a hidden gem.

There is a trove of data that is required to perform actions in a task sequence that is hidden from view. SCCM uses this data to determine which servers to talk to, where packages are located, which step is currently running, and much more.  If we want to be able to use it, we need to know what is there. There are blog posts from years ago explaining how to export this information using VBscript, but this is 2017 and we deserve a PowerShell way to do it!  This code will export all task sequence variables, including those defined on collections and devices.

With the line below, we are creating a new PowerShell object based on the SCCM task sequence COM object and storing it in $TSEnv.
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
There are a few interesting methods to explore on this object, but for now we will focus on two of them:

  1. GetVariables()
  2. Value()
The first method allows us to query the currently running task sequence for the names of all available task sequence variables.  The second method returns the value of the variable specified inside the parenthesis.  By using both of them together in a loop, we can return a list of every variable and it's respective value and store it in a variable.  We then use Out-File to write the variables to a text file on the system drive (X: if run in WinPE).

Now we need to add the script to a task sequence and run it.  There are a few of ways to invoke PowerShell code in a task sequence:
  1. Run PowerShell Script step and providing a script name that exists within a package
  2. Run Command Line step and invoking PowerShell.exe with the -File parameter
  3. Run Command Line step and invoking PowerShell.exe with the -Command parameter
There are plenty of guides on how to use items 1 and 2 above, so let's play with the third.  To do this, we need to concatenate all of the commands so that they run in one PowerShell instance.  This can be done by using a semi-colon, which tells PowerShell to expect more code before exiting.  When done, it looks like this:

We can then paste this code into a Run Command Line step in the task sequence and deploy it to an SCCM client.  

After the task sequence completes, you will find a file in $ENV:SystemDrive\Windows\Temp named TSVariables.txt that contains a key=value listing of the variables.  One word of caution is that this exports ALL task sequence variables, including sensitive and masked variables such as the SCCM client push credentials (noted by a variable name starting with "_SMSTSReserved").  If you want to avoid exporting these, you can update the GetVariables code to match the code below.
$Vars = $TSEnv.GetVariables() | Where-Object {$_ -notmatch 'Password' -OR $_ -notmatch 'Reserved'}
You can add as many -OR statements to the code to filter sensitive information.  In a later post we'll go through some of the interesting variables and what they can be used for.