Cron-like system for Windows? - windows

I'm looking for an equivalent to a Cron system for Windows. The idea is to able to schedule a trigger and monitor whether it has run successfully or not.
What the system need to do is the following:
It should be able to trigger Win32 COM objects and/or executables.
It should be able to trigger .NET COM objects and/or .NET executables.
It should be able to trigger scripts written in any language, either based on native framework (Python, Perl, Ruby) or based on the DLR (IronPython, Ruby.NET, whatever)
The scripts should range between simple scripts that take a few seconds to fairly heavy ones that can take up to half an hour.
The monitoring aspect is critical. So basically I'm looking for the following:
If the script or executable fails then an e-mail should be sent or some other notification mechanism.
Every trigger should be logged so that we can look back and see when the code has failed.
The failure should easily be traced either through some sort of debug output or stack trace.
Are there any Windows developers out there who have created such a system? I know in the UNIX world there is Cron but what about in the Windows world?

At command prompt type 'at'
> at /?
The AT command schedules commands and programs to run on a computer at
a specified time and date. The Schedule service must be running to use
the AT command.
AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]
AT [\\computername] time [/INTERACTIVE]
[ /EVERY:date[,...] | /NEXT:date[,...]] "command"
\\computername Specifies a remote computer. Commands are scheduled on the
local computer if this parameter is omitted.
id Is an identification number assigned to a scheduled
command.
/delete Cancels a scheduled command. If id is omitted, all the
scheduled commands on the computer are canceled.
/yes Used with cancel all jobs command when no further
confirmation is desired.
time Specifies the time when command is to run.
/interactive Allows the job to interact with the desktop of the user
who is logged on at the time the job runs.
/every:date[,...] Runs the command on each specified day(s) of the week or
month. If date is omitted, the current day of the month
is assumed.
/next:date[,...] Runs the specified command on the next occurrence of the
day (for example, next Thursday). If date is omitted, the
current day of the month is assumed.
"command" Is the Windows NT command, or batch program to be run.

You should be able to use the scheduled task for all the above.

I would suggest looking at revised Task Scheduler 2.0 in Vista/Server 2008. It is much more powerful than 1.0 in previous versions of Windows, now able to
Event based triggers, e.g. every time an Application event code 1053 is caused
Triggers on failed tasks (the biggest addition for me)
More built in actions, such as sending emails instead of calling blat.exe
Looking over your list, I believe that everything you are looking for is already there.

Have you looked at Windows Scheduler? It seems to meet most, if not all, of your requirements, and is already included in the OS. You can find it documented at MSDN

If you want a script to "trigger Win32 COM objects and/or executables", "trigger .NET COM objects and/or .NET executables", log failures and notify of failures by email, that sounds to me like a job for PowerShell.
PowerShell doesn't have logging and emailing done for you, rather it's a programming language where you can log or send email (or whatever) fairly easily.
I have scheduled PowerShell scripts to run using the "at" / "Task Scheduler" service, with success. It's a good combination.

Take a look at nnCron. I'm using a Lite version. It has a unix crontab syntax. There is a log file but as for more advanced monitoring aspects, it's up to your script/application to provide details, eg. return Result code (that will be logged). nnCron Lite was the best cron clone for windows (free, no perl requirement, crontab, missed tasks, run as hidden window, set enviroment variable - useful for postgres "dump all" tool, etc.) that I found.

Have a look here: Cron for Windows. There also was some Cron-like software ported for (Free)DOS that should work on Windows, but I can't remember the name.

Have you tried JIT-Scheduler in combination with PowerShell?
http://shareme.com/download/jit-scheduler.html

Related

How can I find out, from within a .bat- (or .ps1-) script, if it was started by the task scheduler?

I'm actually interested as the question is stated, but what I'm after is a mechanism for temporarily disable the scheduled run (on multiple servers, whith shared disk), while still being able to run it interactively (if the script can be made to tell if it's started from task-scheduler or not). An external flag (the existence of a file) seemed like a simple approach to do that.
First option was using "%SESSIONNAME%" which seems to be empty when started from the scheduler, although that's also the case when started from powershell (with Start-Process, which might be an option for allowed usage while disabled).
EDIT: A second option, using the whoami cmd-command seems more promising, it reports the user as belonging to the group NT AUTHORITY\BATCH when run from task scheduler (but not when run interactively). Could I shoot myself in the foot using this - can a user be added to that group "permanently" behind my back?
We're on Windows Server 2012 R2. PowerShell solution would be interesting, as a wrapper could probably be used (or even modification/rewrite from .bat to .ps1).
Per #Alex K.: passing a separate argument to signal that we're running in a scheduled context works fine. Simple, reliable techniques that don't require you to know anything about third-party components -- in my neck of the woods we call those "wins" rather than "cheats".
If you really want, you can check for what you're literally asking -- if we're running from Task Scheduler -- by checking the properties of our parent process. From PowerShell this is quite doable, don't know about plain old batch files:
$parentpid = (gwmi "win32_process where (ProcessId = $pid)").parentprocessid
$parentname = (gwmi "win32_process where (ProcessId = $parentpid)").name
if ($parentname -eq 'taskeng.exe') {
"I think this is Task Scheduler, or maybe something else a hacker named taskeng.exe, who knows?"
} else {
"This is not Task Scheduler. Probably."
}
Of course, this might break if one day MS renames the process, or indeed if you want to use something else than TS to run the script automatically, or even if the script invokes another process which in turn invokes a script.
Personally, I would definitely go with the explicit flag. If you forget to apply it, it will be obvious, it can't suddenly break one day, and best of all, you can test if your script works correctly without actually having to schedule it first.

Turning on a specific program at a specific time and turning off the computer at another specific time

I decided to write a program in RUBY in which the following things should be done:
1 - this program must run a specific program (for example utorrent) at a specific time (for example 1 pm).
2 - this program must turn off my computer at another specific time.
I don't have any idea about the algorithm and manner of writing such program.
One of the easiest ways to do this is to simply send kill signals to the processes, requesting the app shut down normally (Linux), or in Windows use taskkill.
To shutdown a machine in Windows, you can use shutdown /s /f which forcibly closes any programs that are running, and turns the computer off.
No matter which way you do it, you'll basically be running the enter link description heresystem() command in Ruby, which runs command line commands. To make your app portable, you simply look up how to do these tasks in each target OS, and you're done.
Two more alternatives that work the same as your Ruby proposal, but which are not as easily portable:
Write a batch file in Windows that calls taskkill, or a bash script on Linux. Unless the program in question provides a specific way to shut it down via its own command-line parameters, this should work for any/all applications.
You can also use Task Scheduler in Windows, or cron in Linux to do the same thing.

Scripting for safe file backup under windows

I need to back up some large files that are being written to disk by a process. The process is perpetually running, and occasionally dumps large files that need to be moved over the network. Having the process do this itself is not an option, as the process locks out users whilst it is doing file dumps.
So, this runs under a windows machine, and as a primarily linux user, I am not entirely certain how to do this...
Under linux I would simply use a cron job in the folder (I know the glob that will match the output files), then check lsof, to ensure that the file is not being written to, such that I don't try to copy a partially complete file. Data integrity is critical, so I would normally md5 the files before and after the copy.
So I guess my question is -- how does one do this sort of stuff under windows? I feel like I am kneecapped from the start -- I can use python, but I can't emulate lsof, nor cron to do the task scheduling.
I tried looking at "handle" -- but it needs admin privelidges at execution time, which is also not an option. I can't run the backup process as an admin, it has to run with user privs.
Thanks..
Edit: I just realised I could keep the python instance running, with a sleep, so task scheduling is not a problem :)
For replacing cron you can use the "Task Scheduler" in windows to start your script every few minutes (or specific times).
For lsof the question was discussed here : How can I determine whether a specific file is open in Windows?

How to troubleshoot Windows Scheduled Task not running?

In the process of deploying our .net app, I've got about 20 scheduled tasks set up on a server, all of which basically do the same thing: invoke a small .net console app that pulls data from a SQL db and posts it to a web service. Each task invokes a separate copy of the app, each copy having a different lookup ID value in its config file.
All but two of these tasks run reliably every night. Two of the tasks seem to sporadically stop running from time to time, and it's currently a mystery as to why. When they stop running, the scheduled task interface correctly shows their last run date, which is a day or more behind the other tasks, which have continued to run at the scheduled time. The tasks which stopped running do not run again on their own, despite being indicated as scheduled to run every night. There are no errors recorded in the event log or in the scheduled task interface itself. And here's the strangest part to us: If I manually kick off the scheduled task, it runs fine, it invokes the .net console app and everything finishes without anomaly. And then it continues to run fine at its scheduled time, for days or weeks at a time, only to eventually fail, seemingly out of the blue. It appears both tasks always start to fail on the same night.
There's a "Last Result" column that should give you a code related to the task itself running (it's not going to have any kind of exception data). 0 means the task completed without errors. Anything else you can look up and see why the task won't start. If the task still seems to not be running, but you still see a 0 for the Last Result, that means there's something broken in your code, but it's exiting gracefully.
Did you set "Start in" property?
If these .NET console apps need app.config or some files located into their path, you have to set "Start in" property to "c:\your\app\path\, otherwise they start as if they are in the system directory, and they cannot find files they need!
Taskscheduler assumes on 64 bits systems that the applicaiton is 64 bit.
If it is 32 bit launch it from the 32 bit command line, i.e. if you want to run c:\program files (x86)\Myprogram\Program.exe, tell taskscheduler to launch:
%systemroot%\Syswow64\cmd.exe /C "c:\program files (x86)\Myprogram\Program.exe"
This forces it to launch from the 32 bit command-prompt and hence with 32 bit emulation.
I found this super helpful link :https://windowsreport.com/windows-scheduled-tasks-not-running/ for thorough debugging steps for many use cases.
In my case user account with which scheduler was configured to run was locked that stopped execution of scheduled tasks without any logs or reporting problem.
One reason for Scheduled Tasks not running occurs when associating them with a password-less Windows user account: by default Scheduled Tasks are prevented from running with a blank password. If you want to run a Scheduled Task from an account with no password you have to disable a system variable:
Go to: Start > Administrative Tools > Local Security Policy > Security Settings > Local Policies > Security Options
Select: "Accounts: Limit local account use of blank passwords to console logon only"
Disable this variable
Disclaimer: It´s not recommended to have accounts with no password.
The answer to the below SO question may also be highly relevant to people reading this question (but, NB, it describes only one possible specific problem with Scheduled Tasks and I believe neither of these questions is a duplicate of the other):
Why is my Scheduled Task updating its 'Last Run Time' correctly, and giving a 'Last Run Result' of '(0x0)', but still not actually working?
The summary of the answer given to that other question is that Windows 2012 Scheduled Tasks do not see the correct environment variables, including PATH, for the account which the task is set to run as.
In terms of more general Scheduled Task troubleshooting (as asked about in this question), you can test for this particular issue (e.g. running SET > test.txt in the task, as suggested in that answer), and once you can see it happening, you can work around it if it is affecting you.
In my case, the scheduled task wouldn't run even though it said last run was successful (0). It turned out to be that the windows user account that was running the jobs had become locked out. I only realized this because I tried editing the existing scheduled task, set the user account to the same one, then hit OK and it gave me an error about the account being locked out.
Maybe they hung and were still running?
You can click on the extras-menu and choose the menu entry to view the log, then notepad will open a log file from the task planner
I found this page helpful when I was trying to trouble-shoot a misbehaving Scheduled Task:
http://support.microsoft.com/kb/308558
Select View->Details to show the additional information, like Last Run Time, and Status, and this page gave me the meaning of the status/error code:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
I discovered a similar issue February 23 2023 but my logs reveal it started mid January 2023.
My tasks had been working for many months without issue. The I began seeing the same error: The system cannot find the file specified. After all day testing and searching I found that a Windows update on Jan 10 2023 changed the way white space is handled. Formerly only needed one set of quotes. The command line help explains:
C:\> schtasks /create /?
==> Spaces in file paths can be used by using two sets of quotes, one
set for CMD.EXE and one for SchTasks.exe. The outer quotes for CMD
need to be double quotes; the inner quotes can be single quotes or
escaped double quotes:
SCHTASKS /Create
/tr "'c:\program files\internet explorer\iexplorer.exe' \"c:\log data\today.xml\""

How do you schedule a daily script run on Windows XP?

I wrote a script in Ruby. I'd like to run it every day at a certain time. How do you do that on a Windows XP system?
I poked around on the machine and discovered the "scheduled tasks" control panel, but it doesn't seem to have anything to do with running scripts, as far as I can tell from the options offered by the "wizard".
Scheduled Tasks. Sometimes, you have to make a batch file call the script, and schedule the batch.
say you have "script.vbs" you want to run, you will have to create this batch:
cscript script.vbs
cscript is the windows script host which interprets the vbs script. I'm sure ruby has something similar.
You can do it with scheduled tasks, just browse for the program or script you want to run if it isn't listed (in this case, the ruby interpreter I guess, and add the name of the script to run as an argument).
Use the Windows task scheduler.
Under Control Panel > Schedule Tasks.
You can set it up to run any application or file executable from the command line.
Update: (1/15/09)
A good point from Wouter van Nifterick, remember to take care that the process finishes before the next one runs (in comments).
This can be done by going into the advanced options and adjust the allowed amount of time the task may run.
If the task is already configured open it and click the Settings tab. At the top of this tab you will see a checkbox followed by 'Stop the task if it runs for:' then there are two text boxes to enter hours and minutes. If your script runs once a day you will want this set to 23 hours or so.
The 'at' command is a nice command line version of a scheduler.

Resources