Overview

This post shows how a script can detect if it is running from inside an SCCM Task Sequence in a way that avoids false positives.

The Problem

At times it’s useful for a script to detect if it is running from an SCCM Task Sequence so it can alter its behaviour accordingly. The most commonly used way to do this involves trying to create an instance of the COM object Microsoft.SMS.TSEnviroment. This COM object is temporarily registered during Task Sequence execution, and then it is unregistered on completion. So in a script if you try to create an instance of the COM object and you succeed then it can be assumed that the script is running inside a Task Sequence.

Or so I thought…

I was involved in a simple Package and Program script deployment recently and I noticed that in around 1% of cases my script was failing. I checked the script logs on the affected machines and found that they were crashing because they were detecting that they were in an SCCM Task Sequence and invoking specific logic. But because they actually weren’t in a Task Sequence the script was crashing. I checked the script on the affected machines and saw that the script was successfully creating the Microsoft.SMS.TSEnvironment COM object and therefore assuming a Task Sequence. On further investigation of the machines I found that they all had a left over C:\_SMSTaskSequence folder on the C: drive and that during an OSD build they not finished cleanly (unrelated issue).

During a successful Task Sequence deployment a clean up task is run on completion. The smsts.log file shows certain folders and COM objects being unregistered, the log entries are as follows:

Successfully unregistered Task Sequencing Environment COM Interface.    TSManager   19/06/2018 12:24:52 2428 (0x097C)
Executing command line: "C:\WINDOWS\CCM\TsProgressUI.exe" /Unregister   TSManager   19/06/2018 12:24:52 2428 (0x097C)
==========[ TsProgressUI started in process 1044 ]==========    TsProgressUI    19/06/2018 12:24:52 1040 (0x0410)
Command line: "C:\WINDOWS\CCM\TsProgressUI.exe" /Unregister TsProgressUI    19/06/2018 12:24:52 1040 (0x0410)
Unregistering COM classes   TsProgressUI    19/06/2018 12:24:52 1040 (0x0410)
Unregistering class objects TsProgressUI    19/06/2018 12:24:52 1040 (0x0410)
Shutdown complete.  TsProgressUI    19/06/2018 12:24:52 1040 (0x0410)
Process completed with exit code 0  TSManager   19/06/2018 12:24:52 2428 (0x097C)
Successfully unregistered TS Progress UI.   TSManager   19/06/2018 12:24:52 2428 (0x097C)
Successfully unregistered Task Sequencing Environment COM Interface.	TSManager	19/06/2018 12:24:52	2428 (0x097C)
Executing command line: "C:\WINDOWS\CCM\TsProgressUI.exe" /Unregister	TSManager	19/06/2018 12:24:52	2428 (0x097C)
==========[ TsProgressUI started in process 1044 ]==========	TsProgressUI	19/06/2018 12:24:52	1040 (0x0410)
Command line: "C:\WINDOWS\CCM\TsProgressUI.exe" /Unregister	TsProgressUI	19/06/2018 12:24:52	1040 (0x0410)
Unregistering COM classes	TsProgressUI	19/06/2018 12:24:52	1040 (0x0410)
Unregistering class objects	TsProgressUI	19/06/2018 12:24:52	1040 (0x0410)
Shutdown complete.	TsProgressUI	19/06/2018 12:24:52	1040 (0x0410)
Process completed with exit code 0	TSManager	19/06/2018 12:24:52	2428 (0x097C)
Successfully unregistered TS Progress UI.	TSManager	19/06/2018 12:24:52	2428 (0x097C)

If a Task Sequence fails to clean up successfully then you can be left with a left over C:\_SMSTaskSequence folder and Microsoft.SMS.TSEnvironment COM object and these can confuse the usual method of detecting a Task Sequence.

The Solution

Although it would be best to avoid machines getting into this state in the first place it can be worked around. The workaround is as follows:

  • Attempt to create the COM object Microsoft.SMS.TSEnvironment
  • If successful, also attempt to read the Task Sequence variable _SMSTSType
  • If _SMSTSType is not blank then we are in a Task Sequence

_SMSTSType is set to 1 or 2 depending on if the current Task Sequence is an OSD or Custom type. If the value is blank then you are not in a Task Sequence.

Script examples are shown below.

VBScript

The code below shows the solution for VBScript:

'
' Function to test if script is running from a Task Sequence. Will return True/False.
'

Function IsInTaskSequence()
 
    ' False by default
    IsInTaskSequence = False
 
    On Error Resume Next
    Dim oTSEnv : Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")
    If Err.Number = 0 Then 
        ' May succeed because of a failed Task Sequence or bad clean-up of COM objects.
        ' Double check by reading the Task Sequence type, if its blank - not in a Task Sequence
        If oTSEnv("_SMSTSType") <> "" Then 
            IsInTaskSequence = True
        End If
    End If
    On Error Goto 0
 
End Function
'
' Function to test if script is running from a Task Sequence. Will return True/False.
'

Function IsInTaskSequence()

	' False by default
	IsInTaskSequence = False

	On Error Resume Next
	Dim oTSEnv : Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")
	If Err.Number = 0 Then 
		' May succeed because of a failed Task Sequence or bad clean-up of COM objects.
		' Double check by reading the Task Sequence type, if its blank - not in a Task Sequence
		If oTSEnv("_SMSTSType") <> "" Then 
			IsInTaskSequence = True
		End If
	End If
	On Error Goto 0

End Function

Cleaning Up Task Sequence Left Overs

If you want to clean-up a machine that has left over Task Sequence COM objects then one method is to advertise a new Task Sequence to it that does nothing except run a dummy command. It should clean itself up on completion.

Alternatively if you want to manually fix up a machine in this state you can unregister the COM components as follows:

regsvr32.exe /s /u C:\Windows\CCM\TSCore.dll
C:\Windows\CCM\TsProgressUI.exe /Unregister
regsvr32.exe /s /u C:\Windows\CCM\TSCore.dll
C:\Windows\CCM\TsProgressUI.exe /Unregister