TheGeekery

The Usual Tech Ramblings

Powershell, and Importing XML Scheduled Tasks

On Tuesday I detailed a project for upgrading a server to 2008, and one of the tasks of handling all the scheduled tasks on the server. I gave 2 examples on how to export the 2003 task format to something 2008 could handle. This is a follow-up on how to re-import all those tasks again.

schtasks

The first method is with schtasks. Using the schtasks command, you can create scheduled tasks, even better, you can use the same /XML switch as the export command, to re-import the existing command. For example:

1
schtasks.exe /create /RU domain\user /RP password /TN taskname /XML c:\temp\tasks\test.xml

Repeat this command ad nauseum, until all tasks have been re-imported. Or, you can write a quick script using dos, vbscript, or powershell to wrap a loop and update the taskname, and filename for each task. The above command is run on the local box, you can import to remote hosts using the same /S [hostname] switch as before.

Powershell

Using the same com object we used in the previous post, we can also create tasks using the RegisterTaskDefinition. If you’ve ever tried to read any of Microsoft’s developer documentation, it’s very thorough, but quite frequently difficult to wrap your head around, and that was certainly the case here. That being said, PowerShell’s Get-Member function is really handy, and tells us a lot of what we need to know.

1
2
3
$sch = New-Object -ComObject("Schedule.Service")
$sch.Connect("localhost")
$sch | Get-Member

The $sch object has an item called NewTask, which creates an ITaskDefinition interface. A quick look at the MSDN documentation for that, and we see there is a XmlText option. This can be used to import the XML from the previous tasks, and configure all the options for us, instead of having to go through the IRegistrationInfo definitions, and defining it all ourselves. Once we’ve created a task using this interface, we have to tell the schedule service to register it in a folder. This is done using the RegisterTaskDefinition. This function takes 8 arguments, 7 in (with one optional), and a pointer is returned. The order looks like this:

  1. Task Name (even though it’s listed as “path” in the documentation)
  2. Task definition (this is the ITaskDefinition from the NewTask function)
  3. Task creation method (Are we creating, creating/updating, disabling, etc)
  4. Username
  5. Password
  6. Login Type
  7. Security descriptor (optional)
  8. Task pointer

Username and password can be null, as it can read the user definition from the task, depending on what you have set for the login type. For example if you’re using the option that requires the user to already be logged in, you wouldn’t have to define a user/pass. In this case, we have the jobs scheduled as a specific user, and that user may not be logged in, so we’ll use the TASK_LOGIN_PASSWORD (2) option, which requires us to pass in a user/pass.

With that major functionality discussed, it’s just a case of throwing a simple loop around the commands, and fetching all the task information. This is what I ended up with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$task_path = "c:\Temp\tasks\*.xml"
$task_user = "Administrator"
$task_pass = "mypass"

$sch = New-Object -ComObject("Schedule.Service")
$sch.connect("localhost")
$folder = $sch.GetFolder("\")

Get-Item $task_path | %{
  $task_name = $_.Name.Replace('.xml', '')
  $task_xml = Get-Content $_.FullName

  $task = $sch.NewTask($null)
  
  $task.XmlText = $task_xml

  $folder.RegisterTaskDefinition($task_name, $task, 6, $task_user, $task_pass, 1, $null)
  
}

This basically takes all the .XML files in the c:\temp\tasks folder, and loops around them. It uses the file name, with .xml removed, as the task name1, uses the Get-Content function to extract the data, then creates the new tasks, and drops them into the folder.

A quick run, and Windows now shows all 80 something jobs re-imported, and ready to run. It’s worth clicking through, and verifying the information is correct, but it basically did most of the hard work for us, and all in just a few lines of code.

Do you know of another way of batch importing XML specifications for scheduled tasks in Windows 2008?


  1. Remember the export function in the post the other day saved the XML file with the task name as the file name.

Comments