Get Scheduled Task Path in VBScript
26 Sep 2020 · Comments: · Tags: VBScript, ScheduledTask, WindowsTaskSchedulerSummary
I’ve a number of VBScripts that run as scheduled tasks. Whenever these scripts logged an error, it would take me some time to identify exactly which task invoked the script. I therefore wanted to update the scripts error logging to capture the scheduled task path.
I wanted to avoid hardcoding the task path into each script, so I looked for a way to acheive this dynamically.
Problem
VBscript has access to the Schedule.Service
COM Object which can return
details of scheduled tasks. One of the properties of a running scheduled task is
EnginePID
. If a scheduled task calls a VBScript interpreter (cscript.exe or
wscript.exe) then the task’s EnginePID
is populated with the interpreter’s
process ID (PID).
It’s therefore possible to identify the task that triggered a VBScript by
matching the interpreter’s PID with the EnginePID
of a running task. However,
I couldn’t find a reliable means of obtaining an interpreter’s PID using
VBScript.
Solution
I resorted to having VBScript call PowerShell which runs a command to obtain its own PID from which it can derive the PID of the caller.
I wrapped this solution in a function, see GetScheduledTaskPath.
Example Usage
The screenshot below shows a scheduled task called TestTask
within the folder
TheCliGuy
, it invokes the VBScript C:\Bitbucket\TestScript.vbs
.
The script calls the GetScheduledTaskPath
function, the output of which can
be seen in the console window.
Caveats
Windows 7
The GetScheduledTaskPath function has been tested on Windows 7 and I found that it doesn’t work. I took the decision that it wasn’t worth complicating the code to accommodate Windows 7 since the OS went end-of-life on 14th January 2020.
The reason it doesn’t work is because on Windows 7 a scheduled task spawns a
process as a child of taskeng.exe
. Consequently, the EnginePID
property of a
RunningTask
object returns the PID of taskeng.exe
. So in the example illustrated below,
EnginePID
would return 7224
rather than the PID of the cscript
interpreter:
Script Invocation
This function will only work in scripts where a VBScript interpreter is invoked directly by a scheduled task (scheduled task -> interpreter). It will not work in scripts where the interpreter is invoked indirectly, such as a task that invokes a batch file which in turn invokes a VBScript interpreter (scheduled task -> batch file -> interpreter).
Resources
Whilst working on this problem I needed to see the relationships between different processes. I found the following tools to be useful for this purpose:
- Get-ProcessAndChildProcesses (PowerShell function)
- PsList (Sysinternals Tool)
Comments