Tuesday, December 18, 2007

Windows scheduled tasks, backup/restore/administer

Recently I had to make an analysis of scheduled tasks on about 50 servers, mixed Windows 2000 and 2003. Some of the tasks was to be recreated on new Windows 2003 servers. Same project as the shares analysis.

I first turned to schtasks.exe which can be used for query (and create on 2003) , for example:
schtasks.exe /S server /delete /f /tn "calc"
schtasks.exe /S server /CREATE /SC ONSTART /TN "calc" /TR "command" /RU:"domain\user" /RP:pass
schtasks.exe /S server /run /tn "calc"

The query output gives information that can be parsed, eg:
schtasks /query /v /fo table
HostName TaskName Next Run Time Status Last Run Time Last Result Creator Schedule Task To Run Start In Comment Scheduled Task State Scheduled Type Start Time Start Date End Date Days Months Run As User Delete Task If Not Rescheduled Stop Task If Runs X Hours and X Mins Repeat: Every Repeat: Until: Time Repeat: Until: Duration Repeat: Stop If Still Running Idle Time Power Management

server calc Never 16:30:00, 12-12-2007 0 user At 16:30 every Mon, Tue, Wed, Thu, Fri of every week, starting 06-12-2007 C:\WINDOWS\system32\calc.exe calc.exe N/A Disabled Weekly 16:30:00 06-12-2007 N/A MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY N/A runasdomain/user Enabled 72:0 Disabled Disabled Disabled Disabled Disabled Disabled

But as schtasks.exe does not work on Windows 2000 I turned to jt.exe from Windows 2000 resource kit:
ftp://ftp.microsoft.com/reskit/win2000/jt.zip
3104f01eb01ce8b482bf895db60d7e8e jt.exe

I looked at some jt.exe examples, and created a parser in perl. The basic usage of jt.exe was pretty much limited to:
joblist from: jtbin /sm \"$myserver\" /se p
credentials: jtbin /sm \"$myserver\" /sac \"$jobname\" /gc

Here are some more examples of create commands, generated from parsing the jt.exe output:
Example of mon-fri 8-18, every minute:
schtasks.exe /create /SC WEEKLY /RI 1 /ST 08:00 /ET 18:00 /D MON,TUE,WED,THU,FRI /TN "task" /TR "cmd" /RU:domain\user
Every morning, mon-fri:
schtasks.exe /CREATE /SC Weekly /D MON,TUE,WED,THU,FRI /ST 07:00:00 /TN "task" /TR "command"

Later i found that i can patch SCHTASKS.EXE for Windows 2000 usage, and i turned out to actually work perfect. But i had already used jt.exe output for parsing, and it did do everything i needed. Here are the checksums of the files i tested patching with:

4D918C96C3306DF5F460801437BF24FC schtasks_w2k_5.1.2600.2180_patched.exe 86E33A8D9174DB2DB5001D0FD5DCFB8D schtasks_w2k3_5.1.2600.2180_orig.exe

Some of the problems i have or had while working with scheduled tasks:

Parsing more that the first trigger for a task.

How to make create a task or modify the default task property: "Stop Task If Runs X Hours and X Mins: 72:0". This is a problem if the task is created as ONSTART, but we want it to keep running for ever.

Worked around this by calling a cmd wrapper so the task it self is not running, but a wrapper which loops.

I did not try using "jt /? /sj" option which might be what I needed:

/SJ - set task's properties

Change one or more properties on the in-memory task object.

...

MaxRunTime = (in milliseconds)

...

Example: /sj command = notepad.exe Priority=idle DeleteWhenDone=1

How to make sure a schtask program is started in session 0?

That is, if a terminal service session 1 or 2 exists, the remote schtask /run command will sometimes(not always) start the program in session 1 or 2, which is not always what we want.

Only workaround was to manually logging into terminal services /console and starting task.

So this problem is not solved :-)

If the task is set for ONSTART it will of course start in session 0 if you reboot the server.

If there is a session 1 or 2, it does not work to use psexec eg. like this:

psexec \\server -i 0 -e cmd /C "schtasks.exe /RUN /TN calc"

Psexec -i 0 (default) and -i 2 works fine if it is not a scheduled task that is started:
psexec \\server -d -e calc.exe
psexec \\server -d -i 2 calc.exe


The jt /? /sj does not seem to have a property for what session a scheduled task starts in:

The property list has the form = ...

The task properties and the form of their values:

ApplicationName =
Parameters =
WorkingDirectory =
Comment =
Creator =
Priority = { Idle Normal High Realtime }
MaxRunTime = (in milliseconds)
Idle = (wait & deadline, in minutes)
Interactive = { 1 0 }
DontStartIfOnBatteries = { 1 0 }
KillIfGoingOnBatteries = { 1 0 }
RunOnlyIfLoggedOn = { 1 0 }
SystemRequired = { 1 0 }
DeleteWhenDone = { 1 0 }
Suspend = { 1 0 }
HaltOnError = { 1 0 }
StartOnlyIfIdle = { 1 0 }
KillOnIdleEnd = { 1 0 }
RestartOnIdleResume = { 1 0 }
Hidden = { 1 0 }
TaskFlags = (in decimal)

- must be surrounded by double quotes if it contains spaces
- { m/d/y TODAY }
- any integer

Case is not significant (i.e., IDLE and Idle are both legal).

1 comment:

daspeac said...

I have heard about another way of dbf corrupted recovery. Besides, you can visit my blogs at: http://daspeac.livejournal.com/ or http://daspeac.blogspot.com/ where I’m trying to share my experience with regard to data corruption issues.