Get Scheduled Task Path in VBScript

Summary

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.

Scheduled Task Path Example

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:

 
Name             Pid
wininit          484
  services       592
    svchost      988
      taskeng    7224  <---
        cscript  8716

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:

Comments

Leaving comments has been disabled for this post.

Copyright © 2018 - 2021 thecliguy.co.uk
For details, see Licences and Copyright