Hi All,
I am currently facing an issue while executing an action through BigFix and would appreciate your guidance in understanding the observed behavior.
I have created the attached below action script to uninstall Notepad++ and subsequently remove all related files with extensions such as .exe, .msi, and .zip. The script executes successfully without any issues when run using the BigFix Fixlet Debugger. However, when the same script is deployed through BigFix, it fails during execution—specifically at the file creation step, with the error “Substitution failed while writing file.”
For reference, I have included: The complete Action Script, Execution logs from Fixlet Debugger (successful run), Execution logs from BigFix Client (failure observed)
--------------------------------Action Script--------------------------------
// Script to uninstall Notepad++
if {exists file "C:\Program Files\Notepad++\uninstall.exe"}
waithidden cmd.exe /c "C:\Program Files\Notepad++\uninstall.exe" /S
endif
if {exists file "C:\Program Files (x86)\Notepad++\uninstall.exe"}
waithidden cmd.exe /c "C:\Program Files (x86)\Notepad++\uninstall.exe" /S
endif
// Pause for 10 seconds
Parameter "timeout" = "{now}"
pause while {( now-parameter "timeout" as time ) < 10 * second}
// Script to delete all Notepad++ *.msi, *.zip, *.exe files
delete "C:\Windows\Temp\DeleteNotepad++.bat"
delete __createfile
createfile until __EOF @echo off
{ "del /f /q %22" & concatenation ("%22%0d%0adel /f /q %22") of (pathnames of files whose ((name of it as lowercase contains "notepad++" or name of it as lowercase contains "npp")and (name of it as lowercase ends with ".zip" or name of it as lowercase ends with ".msi" or name of it as lowercase ends with ".exe")) of descendant folders of root folders of drives whose (type of it = "DRIVE_FIXED")) & "%22" }
__EOF
move __createfile "C:\Windows\Temp\DeleteNotepad++.bat"
waithidden cmd.exe /c "C:\Windows\Temp\DeleteNotepad++.bat"
delete "C:\Windows\Temp\DeleteNotepad++.bat"
-------------------------------Via Fixlet Debugger------------------------------------
STATUS: Running action...
Command started - waithidden cmd.exe /c "C:\Program Files\Notepad++\uninstall.exe" /S
Command succeeded (Exit Code=0) waithidden cmd.exe /c "C:\Program Files\Notepad++\uninstall.exe" /S
Command succeeded parameter "timeout" = "Fri, 03 Apr 2026 12:31:17 +0530"
Paused pause while True
Not paused pause while False
Command succeeded delete No 'C:\Windows\Temp\DeleteNotepad++.bat' exists to delete, no failure reported
Command succeeded delete No 'C:\Program Files (x86)\BigFix Enterprise\BES Client\__BESData\__FixletDebugger\__createfile' exists to delete, no failure reported
Command succeeded createfile until
Command succeeded move __createfile "C:\Windows\Temp\DeleteNotepad++.bat"
Command started - waithidden cmd.exe /c "C:\Windows\Temp\DeleteNotepad++.bat"
Command succeeded (Exit Code=0) waithidden cmd.exe /c "C:\Windows\Temp\DeleteNotepad++.bat"
Command succeeded delete "C:\Windows\Temp\DeleteNotepad++.bat"
--- Result ---
Evaluation completed successfully!
------------------------------------Via BigFix-----------------------------------------
Command started - waithidden cmd.exe /c "C:\Program Files\Notepad++\uninstall.exe" /S
Command succeeded (Exit Code=0) waithidden cmd.exe /c "C:\Program Files\Notepad++\uninstall.exe" /S
Command succeeded parameter "timeout" = "Fri, 03 Apr 2026 12:03:17 +0530"
Paused pause while True
Not paused pause while False
Command succeeded delete No 'C:\Windows\Temp\DeleteGoogleFiles.bat' exists to delete, no failure reported
Command succeeded delete No 'C:\Program Files (x86)\BigFix Enterprise\BES Client\__BESData\CustomSite_OOUSER\__createfile' exists to delete, no failure reported
Command failed (Substitution failed while writing file) createfile until __EOF
The client log you posted doesn't appear to match the action script. The client log shows a delete of "DeleteGoogleFiles.bat" that is not part of the action script you posted.
That said, using the "descendant folders" inspector to recourse through every directory on every drive is likely to be problematic. The action could take hours to run, if it ever finishes at all.
Better to use one command to recurse the disk, with a "dir /s /b" or powershell script, save the output to a file, and then read that file to find things to delete.
appendfile { "del /f /q %22" & concatenation ("%22%0d%0adel /f /q %22") of (pathnames of files whose ((name of it as lowercase contains "notepad++" or name of it as lowercase contains "npp")and (name of it as lowercase ends with ".zip" or name of it as lowercase ends with ".msi" or name of it as lowercase ends with ".exe")) of descendant folders of root folders of drives whose (type of it = "DRIVE_FIXED")) & "%22" }
move __appendfile "C:\Windows\Temp\DeleteNotepad++.bat"
waithidden cmd.exe /c "C:\Windows\Temp\DeleteNotepad++.bat"
delete "C:\Windows\Temp\DeleteNotepad++.bat"
@shabircse While the script occasionally executes as intended, we are experiencing frequent intermittent failures. Specifically, the system is returning a "relevance substitution failed" error. It appears the process is failing during the output retrieval phase, preventing the files from being cleared. It might be a timeout issue or a syntax error within the relevance evaluation.
I used to get erratic results using relevance substitution in an action for file searchs, for the reason @JasonWalker mentions. Maybe someone in HCL can advise if the following is true but many versions ago I recall it being mentioned that if, at the client level, a relevance expression didn't get its answer within 10 seconds, it would abort the inspection to avoid hanging the client for extended durations of time. While the expression may work in the local fixletdebugger, that isn’t using the client and doesn’t have the same safety features to avoid client lock out from expression that may take minutes to run.
I would recommend the approach @JasonWalker suggested and offload the file search to something outside of native Bigfix ActionScript that outputs to a file, then use relevance substitution to parse the file.
This was the method I used for searching for files. It was way back in 2014 so with WMIC being deprecated, may not be suitable for modern day use.
// Turn off wow redirection otherwise System32 folder search gets skipped due to redirection
action uses wow64 redirection false
parameter "outfile"="{expand environment string of "%25TEMP%25" as string & "\name_of_file.txt"}"
parameter "ImRunning"="{expand environment string of "%25TEMP%25" as string & "\searching.txt"}"
delete {parameter "outfile"}
delete {parameter "ImRunning"}
// Create a marker file which is then uses by the property relevance to avoid "class FileIOError" errors when trying to list lines of a file locked for write access
// Run the DIR command after creating the marker file then delete the marker file so the property can read the file contents error free
createfile until EOF
echo. > {parameter "ImRunning"}
for /f "tokens=2 delims==:" %%d in ('wmic logicaldisk where "drivetype=3" get name /format:value') do @dir %%d:\name_of_file.exe /s /b >> {parameter "outfile"}
del {parameter "ImRunning"}"
EOF
delete FindFiles.cmd
copy __createfile FindFiles.cmd
runhidden FindFiles.cmd
Very much agree with this approach.
One other thing I'd point out, on the original action script, in addition to the potential long directory traversal and relevance timeouts, I'd also expect errors in that substitution if there aren't any file matches - if after scanning all that directory path, nothing is found, it's still building a partial command line with a "del" statement and no matching files.
I've used Find Files from the file system objects inspectors for this sort of thing in the past, though its much better if you can narrow down the scope of folders that your searching in. WMI always feels like it has a lot of overhead, so i'm not sure which is more efficient, using the inspector or wmi, but I thought i'd offer another option.
if{not exist folder "C:\temp"}
folder create "C:\temp"
endif
if{not exist folder "C:\temp\Cleanup"}
folder create "C:\temp\Cleanup"
endif
//Cleanup Files
action uses wow64 redirection false
delete __appendfile
appendfile {concatenation "%0d%0a" of ("del /q %22" & it & "%22") of pathnames of find files ("*notepad++*.zip";"*npp*.zip";"*notepad++*.msi";"*npp*.msi";"*notepad++*.exe";"*npp*.exe") of (it) of (descendant folders of root folders of drives whose (type of it = "DRIVE_FIXED"))}
move __appendfile C:\temp\Cleanup\RemoveFiles.cmd
waithidden cmd /c C:\temp\Cleanup\RemoveFiles.cmd
Nice. Never hurts to have a number of options to choose which one works best for the use case. Totally agree that narrowing down the folder depth is key for optimizing.
The approach I used only used WMIC to find drive letters for fixed drives (we had systems with multiple local fixed drives to cater for) which was then looped by a recursive DIR command so very little WMI overhead. Depending on the use case, maybe no need to use WMIC and just hardcode the C: drive for the DIR command.