Monthly Archives: September 2009

Fun with scheduled tasks in Windows

Fun with scheduled tasksAs many people know, Microsoft Windows has a built-in task scheduler (like *nix cron) to run programs at particular times. Recently at work, I’ve had to start using the Microsoft Windows Server 2008/Vista Task Scheduler (2.0) which is fairly different from the Windows Server 2003/Windows XP (1.0) Task Scheduler (2.0). Read on…

For those who haven’t used the Task Scheduler 2.0, it’s actually pretty handy, especially compared to the original Task Scheduler. Here are some benefits:

The Good

Triggers
Instead of just being able to run the task at a specific time, you now have the ability to trigger a task to start with several events called triggers:

  • On a schedule
  • At log on
  • At startup
  • On idle
  • On an event
  • At task creation/modification
  • On connection to user session
  • On disconnect from user session
  • On workstation lock
  • On workstation unlock

The first option, “On a schedule”, gives you the classic task scheduler… scheduling. And on top of that, you can define multiple triggers on a given task. So if you need a task to run at multiple times a day, you no longer need to define multiple jobs in the task scheduler, just define one job with multiple triggers.

Actions
Similar to the enhancements regarding triggers, you have the ability to define actions for a task now, instead of just a program to run. Actions include:

  • Start a program
  • Send an e-mail
  • Display a message

The first option, “Start a program”, gives you the classic task scheduler option of specifying the program to start when the scheduler fires for that task. And much like triggers, you can define multiple actions for a given task.

Import/Export
You can now export your job definitions from the Task Scheduler as plain ol’ XML. This is useful for doing things like putting your job definitions in version control (I still need to put together a tool to do that for me automatically :-)). And you can then import those XML definitions back into the Task Scheduler.

So if you need to create multiple jobs that are very similar to each (just have some different command args, names, etc.), I’ve found it easy to create one task as a sort of template, export it to XML, copy the XML for each other job I need, modify each XML for whatever little tweak it needs, rename the file (the Task Scheduler uses the XML file name as the imported Task name), then import the file back in. Personally I’m faster at doing that than clicking through all the Create Task screens.

Folders
You can define a folder hierarchy to organize tasks, much like on your hard drive you create a directory hierarchy to organize files. This is really useful on machines that have dozens of various tasks defined.

The Bad

Renaming Objects… or not
Maybe this is just a permission problem on my specific machine, but I have yet to find a way to rename folders in the Task Scheduler, or Tasks themselves! Right now my workaround is to export the Task to XML, rename the file, then import it back in. Similarly, I just remove folders and recreate them with the new name. Pretty tedious stuff, especially when it needs to be done for lots of tasks.

The Ugly

No Migration Utilities
Maybe I didn’t look hard enough, but I spent some time Googling around for a way to convert the Windows Server 2003/XP .job scheduled task files into the Windows Server 2008/Vista XML scheduled task files. After I stumbled across this, I gave up: http://social.technet.microsoft.com/Forums/en-US/ itprovistamigration/thread/76b6276b-49f2-41e2-b4ea- f537e0eb88a8. From a Microsoft moderator in this thread:

We cannot import .job files to Task Scheduler into Windows Vista . In addition, we have no way to convert .job files to .xml files. Therefore, we cannot run schedule tasks created on previous systems on Windows Vista/Server 2008.

Why does this not surprise me. (don’t answer that)

Well, at work I had the task to move about 100+ scheduled tasks from one machine to another. Unfortunately, the source machine was Windows Server 2003, and the target machine was Windows Server 2008, and I was not about to recreate 100+ scheduled tasks by hand. Forutnately, I was able to script the process. While I can’t give away the code verbatim, I’ll give you a rough idea as to what I did:

First, I used the Windows Server 2003/XP schtasks (with the /query /fo csv /v args) to get a nice little CSV file of all the scheduled tasks on the source machine.

Then, I exported a dummy scheduled task from a Windows Server 2008 box and created a sort of template job definition file. I put in place holders for things like the user to run the job as, the command line, the schedule, etc.

Then, I whipped up a little Perl script, using Text::CSV_XS for CSV parsing, to read in the CSV, massage the data a little, and used my template XML job definition to create the 100+ job XML files. The whole process runs in less than a minute, not too shabby.

Now, today I just need to find a way to automatically import these jobs. So if you too are looking for a way to convert Windows Server 2003/XP .job files into Windows Server 2008/Vista XML task definition files, hopefully this helps. I haven’t really looked into a C# API for the Task Scheduler 2.0, but this looks promising. Happy task scheduling!

Ruby gives me heartburn

Ruby gives me thisDisclaimer: this is not meant to be a “Ruby sucks” post. It’s just me publically ranting about some pains I’ve had with Ruby recently.

Override everything

As Ruby Tips points out, In Ruby you can easily extend classes and modules. This means that nothing in Ruby (including built in classes and modules) are closed!
While admittedly, the hacker in me thinks this is really slick, the developer in me can’t stand it. I’ve lost so much time at work hunting down method definitions and overrides across an existing Ruby codebase. Maybe there’s a tool or IDE out there that would help make it more obvious where these methods are defined (currently I use a mix of GVim andTextPad), but hunting across dozens of Ruby scripts between RakefilesRuby on Rails scriptsCruiseControl.rb scripts, and custom Ruby code to find the actual method definition is not my idea of a good time.

Implicit returns

Again, as Ruby Tips points out, Value of the last expression in a method becomes the return value of the method. In Ruby return keyword is optional.
Being relatively new to Ruby, this was really confusing at first. For example, in the following Ruby method definition, what does the following method return if the regex matches?

def dummy_method
    input = "Hi there, I'm almost 30"
    if /almost (\d+)/ =~ input
        $1
    end
end

It’ll return “30”, obviously! 😉 Once you understand more about what Ruby is doing there it’s not as bad, but it took me a while to get the hang of implicit returns.

Helpful links

Some links that have helped me limp along through my Ruby experiences: