Is it possible to make schtasks run at specific times? - scheduled-tasks

Is it possible to create a task using schtasks, such that this task runs at specific times depending on the configuration provided by the user?
Ideally what I want to achieve is this - a user enters the specific times s/he wants the task executed (e.g. generating a report and having it emailed). This string of specific times is comma-delimited, e.g. 08:00, 11:20, 14:00, 17:59 or 09:15, 10:30, 11:45, 13:00.
Currently all I know is that schtasks /create allow you to specify a start time using the /st <hh:mm> but that's only for one specific timing.

You can set the starting time for tasks and set the interval at which it repeats, but that's about it for individual tasks.
If you want to create a single task that runs every 3 hours, starting at 09:00, you could do something like this:
Schtasks /Create /TN example /TR C:\example\report.bat /SC DAILY /ST 09:00 /DU 300 /RI 180
Notice that i set /DU: it's a requirement of schtasks.exe that the duration is more than the run interval.
If you wanted to create several tasks to run at different times, I'd either add one at a time or have them each on a single line of a file that is then passed through a batch file (which is effectively the same). Once you get into delimited lists it gets messy; I haven't found a pretty way to extract data from them yet. It's certainly possible, but feels like the kind of thing that people tell you is "bad practice".
To add several tasks in succession, I'd create a batch file that looked something like this:
set i=1
:top
set /P input=if you want to create a scheduled task, enter the time you want in HH:MM format. otherwise, type "q" :
if (%input%) EQU (q) exit /B 0
Schtasks /Create /TN %username%\%i% /TR C:\example\report.bat /SC DAILY /ST %input% /RU %username%
set /A i+=1
goto top
The tasks created are numbers starting at one and counting up to infinity (as far as the user goes) and filed under a folder titled the same as the username of the person who ran the script. Technically, the name you access them by would be "%username%\1", "%username%\2". This is so that multiple users can use the same script to make multiple tasks without the danger of overwriting each others tasks.
The script can be stopped at any time by entering "q" by itself.
Potentially, you could input a file to this script with one time on each line and a q at the end, and it would run through the entire list and exit.

Related

Netlogo - Behavior Space

I want to run experiments using behavior space. However, the number of experiments needed is depending on the length of a list which is dynamic subject to the external data loaded. Hence , I want to do something like below which is not supported:
what is the correct way to do so? thanks
You note that you do this with a .bat or .sha file. If that's the case, here's a .bat solution. However, I'm not sure what your data looks like- in this example I just used the number of entries in a csv file to determine the number of runs needed.
So, I have a data file called 'example_data.csv' that looks like this:
1
100
1000
10000
I have an .nlogo file with an Input widget that defines a global variable called n_runs. I pulled out the xml for an BehaviorSpace experiment and saved it in a file called "experiment_base.xml"- it looks like:
<experiments>
<experiment name="experiment" repetitions="1" sequentialRunOrder="false" runMetricsEveryStep="false">
<setup>setup</setup>
<go>tick</go>
<timeLimit steps="5"/>
<metric>count turtles</metric>
<steppedValueSet variable="n_runs" first="1" step="1" last="1"/>
</experiment>
</experiments>
I have a .bat file that:
counts the number of entries in my 'example_data.csv"
reads in the 'experiment_base.xml' file and replaces the last="1" with the number read above, then writes this as a new experiment called 'mod_experiments.xml'
runs the experiment using the newly generated experiments file
This entire bat file looks like:
#echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" example_data.csv | find /C ":""
for /f %%a in ('!cmd!') do set number=%%a
powershell -Command "(gc experiment_base.xml) -replace '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"1\"/>', '<steppedValueSet variable=\"n_runs\" first=\"1\" step=\"1\" last=\"%number%\"/>' | Set-Content mod_experiments.xml
echo "Running experiment..."
netlogo-headless.bat ^
--model dynamic_behaviorspace.nlogo ^
--setup-file mod_experiments.xml ^
--table table-output.csv
This outputs results for 4 experiments, since I had 4 values in my data file. If I modify the number of entries in the csv and rerun the .bat file, I get results for a corresponding number of runs.

Is it possible to specifically compare two dates in batch?

I was wondering if it's possible to compare a specific date (in the MM/DD/YY format) to the current system date, and get the difference in minutes?
In my past questions, I've been able to grab the dates of processes and folders and create the conversion to minutes, but I'm stumped.
My project uses Batch/CMD and Powershell, so any of those formats would be more than acceptable.
Here's the code that I use for grabbing dates to minutes with processes:
if exist "C:\Windows\Prefetch\JAVAW*.*" (
for /f "usebackq" %%A in (`
powershell -NoP -C "[int]([datetime]::Now - (gci 'C:\Windows\Prefetch\JAVAW*.*' -Force).LastWriteTime).TotalMinutes"
`) do set "AgeMinutes=%%A"
)
if exist "C:\Windows\Prefetch\JAVAW*.*" echo JAVAW.pf was modified %AgeMinutes% minutes ago.
if not exist "C:\Windows\Prefetch\JAVAW*.*" echo Error: file not found.
Is a comparison to the current date (and outputting it into minutes) possible?

Dynamic date in batch file

i am running the following command in a cmd:
Prog.exe -time Components_2016_04_19_11.ss
I want to write a batch file that will be run hourly and i need the date in the command to change accordingly - the date needs to be in the format above, and the last part of the date is the current hour minus 7 hours
So if the time now is 1/1/2016 20:43 the command will look like this
Prog.exe -time Components_2016_01_01_13.ss
i need help creating the appropriate batch file
Thanks
For future reference, questions resembling "Write this for me. Here are my requirements." aren't well-received around here. But this time, just to prevent any more unhelpful answers from being posted, I'll help you out with a solution.
Pure batch is really cumbersome with date math. Compensating for midnight, month changes, leap years, etc. can be a nightmare. It's much easier to use a different language -- one which has a proper Date object that will handle calendar quirks without having to hack around them.
Here's a PowerShell solution to your problem:
Prog.exe -time ("Components_{0}.ss" -f (Get-Date).addHours(-7).toString("yyyy_MM_dd_HH"))
That's it, just a one-liner. If you require a batch script, you can employ the PowerShell helper to perform the date math heavy lifting.
#echo off & setlocal
for /f "delims=" %%I in (
'powershell -noprofile "(Get-Date).addHours(-7).toString('yyyy_MM_dd_HH')"'
) do (
Prog.exe -time Components_%%I.ss
)
goto :EOF
Get-Date
Get-Date | Get-Member
you can use this:
$GBL = 0
do{
Prog.exe
Get-Date
sleep 3600
}
while($GBL -lt 1)
$GBL it's a infinity variable for the loop. inside of the do execute the program and use the sleep for wait 3600 seconds or 1 hour for execute again. Get-Date it's for mark the date and time when the code it's executed.
I don't understand if you need this or something else.
You can modify the line of Prog.exe with the code you need.
If you answer me i can help you.
Have a good day (:

How do I find last Sunday's date and save it in a variable in a Windows batch file

I have a script that needs to connect to an ftp server and download a file that is only created on Sunday and Sunday's yyyy-mm-dd-hh-mm-ss is appended to the file name. I need to find the last Sunday's date (based on today's date, I assume) and convert it to yyyy-mm-dd (I don't care about the time) so I can construct the filename in my ftp script. I have searched a lot of threads on this and other sites, but I'm kind of a novice at batch syntax. I cannot make assumptions about the date format on the machine that will run this script, but it will be in the same timezone as the ftp server and it will be running at least Windows 7. I thought about using the PowerShell solution in HOW to find last SUNDAY DATE through batch but I've read there are issues with PS script portability. Any help is greatly appreciated. Let me know if I need to provide more detail. Thanks!
(Get-Date).AddDays(-(get-date).dayofWeek.value__)
A couple years ago I wrote a batch script to find yesterday's date. I made it able to calculate 'yesterday' based on today's date. It takes into account months ending on the 30th or 31st, and even the next few leap years. The way I wrote it expects the date to be in the format 'Wed 02/24/2016' or 'ddd MM/DD/YYYY', so it may not be useful to you.
As I look at it now, it's probably more complicated than it needs to be and could probably use some cleanup, but it worked for my purposes. You might be able to modify it somehow to make it find last Sunday, instead of yesterday.
set yearCounter=0
set yyyy=%date:~10,4%
set mm=%date:~4,2%
set dd=%date:~7,2%
::use these to override the actual date values for testing
::set yyyy=xxxx
::set mm=xx
::set dd=xx
if %dd%==01 goto LDoM ::Last Day of Month
set DS=%yyyy%%mm%%dd%
set /A yesterday=%DS%-1
goto endyesterday
:LDoM
set /A lastyyyy=%yyyy%-%yearCounter%
if %yesterday:~4,2%==01 set lastmm=12& set lastdd=31& goto LDoY ::Last Day of Year
if %yesterday:~4,2%==02 set lastmm=01& set lastdd=31
if %yesterday:~4,2%==03 set lastmm=02& goto february
if %yesterday:~4,2%==04 set lastmm=03& set lastdd=31
if %yesterday:~4,2%==05 set lastmm=04& set lastdd=30
if %yesterday:~4,2%==06 set lastmm=05& set lastdd=31
if %yesterday:~4,2%==07 set lastmm=06& set lastdd=30
if %yesterday:~4,2%==08 set lastmm=07& set lastdd=31
if %yesterday:~4,2%==09 set lastmm=08& set lastdd=31
if %yesterday:~4,2%==10 set lastmm=09& set lastdd=30
if %yesterday:~4,2%==11 set lastmm=10& set lastdd=31
if %yesterday:~4,2%==12 set lastmm=11& set lastdd=30
set yesterday=%lastyyyy%%lastmm%%lastdd%
goto endYesterday
:february
set leapyear=n
set lastdd=28
if %yesterday:~0,4%==2016 set leapyear=y
if %yesterday:~0,4%==2020 set leapyear=y
if %yesterday:~0,4%==2024 set leapyear=y
if %yesterday:~0,4%==2028 set leapyear=y
if %leapyear%==y set lastdd=29
set yesterday=%lastyyyy%%lastmm%%lastdd%
goto endYesterday
:LDoY
set /A yearCounter=%yearCounter%+1
set /A lastyyyy=%yyyy%-%yearCounter%
set yesterday=%lastyyyy%%lastmm%%lastdd%
:endYesterday
#echo off
echo %yyyy% %lastyyyy%
echo %mm% %lastmm%
echo %dd% %lastdd%
echo.
echo today = %yyyy%%mm%%dd%
echo yesterday = %yesterday%
Working with date and time using pure batch can be done, but it is not very convenient.
The GetTimestamp.bat utility makes date/time computations and formatting simple within a batch context. It is pure script (hybrid JScript/batch) that runs natively on any Windows machine from XP onward. The previous link points to the most recent version. The utility was first introduced with a number of examples at http://www.dostips.com/forum/viewtopic.php?t=4847.
Full documentation is available from the command line via getTimestamp /?, or getTimestamp /?? for paged output.
With GetTimestamp, the solution can be as simple as:
#echo off
:: Get the current day of the week, with 0=Sunday, 6=Saturday
:: to be used as an offset from today to get the most recent Sunday
call getTimeStamp -f {w} -r offset
:: Use the offset to get the most recent Sunday in YYYY-MM-DD format
call getTimeStamp -od -%offset% -f {iso-dt} -r lastSunday
:: Show the result
echo lastSunday=%lastSunday%
Try the following from a batch file:
for /f "usebackq" %%d in (`powershell -noprofile -command "'{0:yyyy-MM-dd}' -f [DateTime]::Now.AddDays(-1 * [DateTime]::Now.DayOfWeek)"`) do set "lastSunday=%%d"
echo %lastSunday%
:: -> e.g., "2016-02-21", when run on 2016-02-25
To try this directly on the command prompt, replace %%d with %d.
The PowerShell expression at the heart of the command,
[DateTime]::Now.AddDays(-1 * [DateTime]::Now.DayOfWeek),
which calculates the date of the most recent Sunday, was gratefully borrowed from the answer that you link to in your question.
'{0:yyyy-MM-dd}' -f ... applies the desired yyyy-mm-dd formatting to the date.
powershell -noprofile command ... invokes the PowerShell expression and outputs its result to stdout.
for /f "usebackq" %%d in (`...`) do set lastSunday=%%d captures the output from the PowerShell command and assigns it to batch variable lastSunday.
While invoking PowerShell for just one command from a batch file will be slow, being able to calculate the desired date so conveniently probably outweighs performance concerns.

Printing current date and time in DOS script

I have a script that prints the date and time followed by a string in a log.
echo %DATE%_%TIME% Processing %%f >> process.log
The problem is that the date and time is always the date and time when the script is started. I've been running the script overnight, and still has the same date and time. Is there a way to update them so it shows the current date and time when the string is printed to the log file?
The fact that you have %%f indicates your echo command is in a FOR loop. The entire FOR loop is parsed at once, and %DATE% is expanded at parse time. The command is not re-parsed for each iteration, so that is why you get the same value for each iteration. You get the value that existed before the FOR statement is executed!
The solution is delayed expansion. Put setlocal enableDelayedExpansion near the top of your script. Then use !DATE!_!TIME! instead of %DATE%_%TIME%. Delayed expansion means the expansion occurs when the statement is executed, not when it is parsed. There is a good explanation in the HELP system. Type HELP SET or SET /? from a command prompt and look for the section that deals with delayed expansion.