How to Migrate Scheduled Tasks Between Windows Server 2003 Machines Using PowerShell and XML Export


2 views

Windows Server 2003 stores scheduled tasks in the %WINDIR%\Tasks directory as individual .job files. However, the most reliable method for migration involves using the built-in SCHTASKS command-line utility combined with PowerShell for automation.

First, let's export all tasks from the source server:

# PowerShell script to export all scheduled tasks
$tasks = schtasks /query /fo list | Where-Object { $_ -match "TaskName:" }
$taskNames = $tasks -replace "TaskName: ",""

foreach ($task in $taskNames) {
    $xmlPath = "C:\TaskBackup\$task.xml"
    schtasks /query /tn $task /xml > $xmlPath
}

After transferring the XML files to the new server, use this import script:

# PowerShell script to import scheduled tasks
$xmlFiles = Get-ChildItem "C:\TaskBackup\*.xml"

foreach ($file in $xmlFiles) {
    $taskName = $file.BaseName
    schtasks /create /tn $taskName /xml $file.FullName /f
}

Check the imported tasks with:

schtasks /query /fo list

Common issues include:

  • Path discrepancies - Update executable paths in XML before import
  • User context - Modify <UserId> elements in XML for new server
  • Trigger times - Verify time zones if servers are in different locations

To maintain security descriptors across servers:

# Export permissions (requires subinacl.exe from Windows Resource Kit)
subinacl /noverbose /output=C:\TaskPermissions.txt /subkey=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache

When migrating scheduled tasks between Windows Server 2003 systems, the most reliable approach is to work with the underlying XML definitions. Each scheduled task is stored as a .job file in the %SystemRoot%\Tasks directory, but these binary files aren't directly portable.

Use SCHTASKS.EXE with the /QUERY and /XML switches to export task definitions:

schtasks /query /tn "\TaskFolder\TaskName" /xml > C:\Exports\TaskName.xml

For batch exporting all tasks:

for /f "tokens=*" %i in ('schtasks /query /fo list ^| find "TaskName:"') do (
    set taskname=%i
    set taskname=!taskname:TaskName: =!
    schtasks /query /tn "!taskname!" /xml > "C:\Exports\!taskname!.xml"
)

Before importing, you may need to modify paths in the XML. Here's a PowerShell snippet to batch update paths:

$xmlFiles = Get-ChildItem "C:\Exports\*.xml"
foreach ($file in $xmlFiles) {
    $content = Get-Content $file.FullName
    $content = $content -replace 'D:\\OldPath\\', 'E:\\NewPath\\'
    $content | Out-File $file.FullName -Encoding UTF8
}

Use SCHTASKS with /CREATE and /XML switches:

schtasks /create /tn "\NewTaskFolder\TaskName" /xml "C:\Imports\TaskName.xml"

After import, verify tasks are properly configured:

schtasks /query /tn "\TaskFolder\TaskName" /v /fo list

For more control, use the Task Scheduler COM API through VBScript:

Set service = CreateObject("Schedule.Service")
service.Connect
Set rootFolder = service.GetFolder("\")
Set task = rootFolder.GetTask("MyTask")
task.Definition.XmlText = "<?xml version=""1.0""?>...</Task>"

Remember to set proper security descriptors if tasks run under specific accounts. Use SCHTASKS with /RU and /RP parameters during creation.