Displaying Windows Task Scheduler Tasks with PHP

In building Dante, my task scheduler application, I have come across quite a bit of information about dealing with COM through PHP.  Once I gained a simple understanding of the COM system in PHP I learned the rest from Win32 and COM Development on MSDN.  I hope to share a bit of what I have learned.  The focus of Dante will be on Windows first. Later I want to be able to support UNIX systems too, so I will keep that in mind as I build my class. As I never have enjoyed VBS so implementing it in PHP will make for a much more enjoyable experience scripting.  My intention is to take everything I work on and bringing it into my framework.  Hopefully you find this information helpful, or if you just want to use this functionality check out the Crossley Framework.  Dante PHP Job Scheduler will have a project page soon, so stay tuned.

So the first piece of Dante that will always be important is displaying the tasks that are scheduled to run.  A Factory method is used with COM objects in PHP or VBS.  As discussed earlier, it is called COM() in PHP.  A quick trip over to the Task Scheduler MSDN refrence tells us there are four high-level steps we need to take.

  1. Create a TaskService object (using COM())
  2. Get a task folder (tasks are organized into a directory tree)
  3. Get the collection of tasks from that folder
  4. Count, Iterate and perform any other operations on the tasks.

These are mostly obvious.  So the first thing I need to do is checkout the TaskService object.  This will be the means for managing registered tasks.  From the documentation you can see that the TaskService object has a limited number of methods: Connect(), NewTask(), GetFolder() and GetRunningTasks().  My goal  will be to completely obfusticate the functionality passing these calls onto the instance.

On the simplest level I want to be able to call my class like this:

$oTaskService = new X_Scheduler_Win_Service();
$aTasks = $oTaskService->getTasks();
print "<ul>";
foreach ($aTasks as $oTask)
{
print "<li><b>{$oTask->sName}</b>
print "{$oTask->sPath} : {$oTask->sNextRunTime}</li>"
}
print "</ul>";

I will try to place all the connect logic in the constructor.  I will allow for D-COM pass through, but I am not going to be worried about making it work this go arround.   If you decide to experiment with it, you should know that it needs to be enabled in your php.ini.  D-COM basically allows you to connect to a different server to run COM.

One of your best friends is com_print_typeinfo().  However it can leave you high and dry if the COM object doesn’t support the introspection from com_print_typeinfo().  Sadly this seems to be the case with ‘IRegisteredTaskCollection’.  In this case you just have to trust the MSDN documentation.  If I had one wish for PHP on Windows it would be that this function be improved.  The other qualm I have is that it outputs directly and does not return a string.  I think it should at least have the option like print_r().

So lets take the first step and get a count of tasks.

$oSchedule = new COM("Schedule.Service");
$oSchedule->Connect();
$oFolder = $oSchedule->GetFolder("\");
$oCollection = $oFolder->GetTasks(0);
print "Count: " . $oCollection->Count . "n";

The first two lines you will see repeated constantly when dealing with COM.  We are basically getting an instance of the TaskService object and connecting to the running service.

Then, since the schedule is organized in a directory tree style folder structure we need to get the folder we are going to deal with.  Here we get the root folder, but later we will get organized into our own folder.  Just like dealing with the file syste, tasks concealed within folders are not visible from the parent folder.  The TaskService object also offers the following methods and properties:

TaskService methods:

GetFolder Gets the path to a folder of registered tasks.
GetRunningTasks Gets a collection of running tasks.
Connect Connects to a remote machine and associates all subsequent calls on this interface with a remote session.
NewTask Returns an empty task definition object to be filled in with settings and properties and then registered using the RegisterTaskDefinition method.

TaskService properties:

Connected Read-only Gets a Boolean value that indicates if you are connected to the Task Scheduler service.
ConnectedDomain Read-only Gets the name of the domain to which the TargetServer computer is connected.
ConnectedUser Read-only Gets the name of the user that is connected to the Task Scheduler service.
HighestVersion Read-only Gets the highest version of Task Scheduler that a computer supports.
TargetServer Read-only Gets the name of the computer that is running the Task Scheduler service that the user is connected to.

The parameter passed to GetTasks() signifies what type of tasks to list. To list all the normal tasks we pass ‘0’ (zero).  We can list hidden tasks by passing ‘1’.

Once we have a collection we can get the count from the ‘Count’ attribute.

The next step I want to take is to turn the collection into a native PHP array.  At this point it is good to take note that the first item in this collection is not 0 as with normal PHP arrays.  The first item is thus ‘1’.  Taking this into consideration we form a for loop:

$aTasks = array();
for ($i = 1; $i <= $iCollectionCount; $i++)
{
$aTasks[] = $oCollection ->Item($i);
}

The collection is also iterable in a foreach loop:

$aTasks = array();
foreach ($oTaskCollection as $oItem)
{
$aTasks[] = $oItem;
}

You may ask why I am adding a loop if it is already iterable.  The plan here is to end up with a totally native concrete object.  There may be a way to cast returned objects to PHP classes, but we will save that for later

Now lets take a look at the RegisteredTask object.  One property that seems to have great potential is ‘XML’.  Here are the RegisteredTask Properties:

Definition Read-only Gets the definition of the task.
Enabled Read/write Gets or set a Boolean value that indicates if the registered task is enabled.
LastRunTime Read-only Gets the time the registered task was last run.
LastTaskResult Read-only Gets the results that were returned the last time the registered task was run.
Name Read-only Gets the name of the registered task.
NextRunTime Read-only Gets the time when the registered task is next scheduled to run.
NumberOfMissedRuns Read-only Gets the number of times the registered task has missed a scheduled run.
Path Read-only Gets the path to where the registered task is stored.
State Read-only Gets the operational state of the registered task.
XML Read-only Gets the XML-formatted registration information for the registered task.

Notice that all the properties we mentioned before are present.  Observing the methods of this object we see everything we may ever want to do with a task:

GetInstances Returns all instances of the registered task that are currently running.
GetSecurityDescriptor Gets the security descriptor that is used as credentials for the registered task.
GetRunTimes Gets the times that the registered task is scheduled to run during a specified time.
SetSecurityDescriptor Sets the security descriptor that is used as credentials for the registered task.
RunEx Runs the registered task immediately using specified flags and a session identifier.
Stop Stops the registered task immediately.
Run Runs the registered task immediately.

In building  my class, the instanciation and connection is done in the constructor with the option to pass through the additional options.  The TaskService object also offers a connect in addition to the COM connect methods.  This allows us to use additional user credentials without going the D-COM route.  Thus, I will create a method to neatly take advantage of reconnecting with a different username and password.  Then I will stub out a Task class that we will later use for convience methods.

Next: Scheduling a Task in Windows Task Scheudler with PHP

Advertisements
Displaying Windows Task Scheduler Tasks with PHP

3 thoughts on “Displaying Windows Task Scheduler Tasks with PHP

  1. […] Excellent writeup of a PHP app that interfaces with the Windows Task Scheduler.  I’m going to have to double check on his use of the Task Service object.  I thought it was only COM accessible in Task Scheduler 2.0 (the new version, that comes with Vista or Windows 7, or Server 2008).  I thought in XP (which included the Task Scheduler 1.0 – the schtasks.exe or the good old Scheduled Task’s folder) that either the Task Service COM interface had to be accessed with a lower level language, or possibly the Scheduled Task’s accessible via WMI (but not through the schtask folder interface).  Its possible thats the task scheduler this code uses for access.  If thats the reality, then you may not see all the tasks you may have entered using the GUI interface, using this tool.  More on that later. https://codesnob.wordpress.com/2009/05/18/displaying-windows-task-scheduler-tasks-with-php/ […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s