Implementing SCCM detection clauses using scripts allows an administrator to flexibly define detection methods, especially when dealing with manually defined applications and deployment types. The scripting potential and capabilities are virtually limitless. SCCM supports scripting using PowerShell, VBScript or JScript.
I was recently supplied with an application to be distributed though SCCM. The files initially provided did not respond to any command line switches for silent installation. I requested from the supplier to provide setup files capable of being installed without user intervention. They did, though the behavior was erratic:
- The initial application setup is launched by running “Setup.exe /s”
- This setup file in turn launches a setup.exe file located in a subfolder
- This second setup launches in turn an IKernel.exe setup file for InstallShield installer
- Setup file in the first point terminates directly after launching the second setup, even before the actual installation is finished
Moreover, as shown in the bullets, the setup file was an .exe file. I started by creating a package using the Setup.exe file as shown in the guide published previously. I created detection clauses based on File Detection rules. The application was deployed to several test machines.
The setup behavior caused problems with SCCM detection of the installation status since it monitors the return codes of the initial setup file which is terminating before the end of the installation. As shown in the screenshot, SCCM tries to detect the application after five seconds of launching the deployment, which corresponds to when the primary setup file finishes execution:
This is by design since SCCM monitors the return codes for the setup file it launches. This was reflected in the SCCM console showing installation failure due to application files not being detected after deployment. The actual installation however was still running in the background and it finishes successfully. The application deployment will eventually be retried. Two scenarios can occur:
- If the installation is retried while the first one has not finished yet, multiple instances of the setup will now be active causing unpredictable behavior
- If the installation is retried after the entire setup has finished, the application will be detected as already installed causing wrong reporting in the console (Already Compliant status instead of Success)
Knowing that simple file detection will not suffice, I attempted to use a custom script to provide the required file detection. SCCM expects a certain output from the script to properly determine the application state as shown in this Technet article. The most relevant sections are highlighted in red:
In this case, the script needs to exit with a “0” exit code and have some data written to the standard output stream to indicate application presence. Exiting without writing anything to STDOUT or STDERR indicates the absence of the application files.
The script needs to detect the application files and wait for the background setup file to finishes. Starting from this Technet Blog, the following VBScript was written to achieve the needed file detection clause:
‘Declare needed variables
Dim FSO, File, WaitTime, TotalWaitTime
‘ Initialize constants
Const InitialTime = 30000
Const Delay = 60000
Const Timeout = 600000
‘ Set inital values
Set FSO = CreateObject (“scripting.FileSystemObject”)
File = “C:\Users\emmanuel.rached\Desktop\MyFile.txt”
WaitTime = InitialTime
TotalWaitTime = 0
‘ Loop until file is found or timeout exceeded, sleeping for WaitTime between each iteration
Do While TotalWaitTime < Timeout
TotalWaitTime = TotalWaitTime + WaitTime
If fso.fileExists (File) Then
WScript.StdOut.Write “The file was detected”
The script starts by declaring several variables that we will use and by initializing some constants:
- InitialTime will control the sleep interval for the script. WScript.sleep uses the integer defined as milliseconds. It is defined as 30 seconds in the code above
- Delay will control a small sleep delay before exiting the script in case the file is found to allow the background setup to finish and properly exit
- Timeout will define the maximum time that the script is allowed to run. It is defined as 10 minutes on the code above
- WaitTime will be assigned the value of the InitialTime constant and will control the delay in the loop
- TotalWaitTime will be used to monitor the script execution time to exit when the timeout is reached. It is set to zero at first
- FSO will be used to indicate the file to monitor by using CreateObject (“scripting.FileSystemObject”)
The text highlighted in red indicates the full file path that the script will attempt to detect.
The main part of the script is the loop function. It will initially sleep for 30 seconds before attempting to detect the file, controlled by the WaitTime constant and using WScript.sleep. If the file is not found, the script will loop back, will increase the value of TotalWaitTime and will wait another 30 seconds. It will continue to monitor and loop until the TotalWaitTime variable exceeds the Timeout value defined. The script will then exit with an exit code of “0” and will write nothing to STDOUT or STDERR. SCCM will interpret this as “application files not found” and will proceed with the deployment.
If the file is found, the script will sleep for a minute to allow the background setup to properly finish. It will then output to STDOUT a custom message and exit with a “0” code. SCCM will determine that the application deployment was successful. This will also allow subsequent SCCM Agent application discovery to properly detect that the application is already deployed. The script was tested in a standalone environment and performed as expected.
However, when the script was integrated with SCCM detection clauses, it failed to run due to the default timeout that SCCM assigns to scripts. The maximum script execution run time is 60 seconds.
Thanks to Fei Xia who provides a solution to change the default timeout value. The script mentioned in his blog post was ran and successfully updated the ScriptExecutionTimeOut value to 600 seconds:
Following all this configuration, the application was deployed again to the test machines with the updated script. The installation and detection was a success:
Hopefully, the script in this example will help you with custom detection rules in your environment. The variables and constants defined can be changed to values that suit your deployment type. Make sure to test the script before mass deployment.
5 responses to “SCCM Detection Clauses Using Scripts”
This accounts for machines that are already working with an operating system, but what about OSD scenarios?
I have applied the change to the timeout to increase to 1200 seconds which was successful, but client machines that are building are showing in the logs that the timeout is still 60 seconds.
Are you aware of any way to increase the time out in those scenarios?
Are you encountering script timeouts during OSD deployment? If so, which part(s) of the task sequence is(are) timing out?
Can you also post the log entries from the corresponding log files?
I’m attempting to deploy an application that needs a file created in a certain folder after the exe. is executed, which I have successfully done, but I cannot get SCCM to recognized that it worked. I liked your script better then the generic file detection VBSscript because it seems to address the issue with SCCM’s failure to detect file existence because of timing issues. I copied your VBSscript and gave it a try and it wouldn’t work for me. It seems to be a similar time out issue to SSCM where it never executes the if fso.fileexists() – no output is ever achieved. Using Echos its stops outputting after first loop. When I comment out the variables and the loop and run it through cmd it fails due to wscript.stdout. I did a quick google search and it seems that stdout won’t work with wscript because stdout is made available for console script not windows host. A quick change to wscript.echo “some text” and it functions just fine through CMD but that won’t work for SCCM as nothing gets written to stdout. So I’m at a loss on to how to make this work. Would appreciate any thoughts.
Can you share the script you wrote?
Very, very, very helpful.. I don’t know how to thank you guys. This helped me a lot and saved me a lot. God bless you for sharing this.