Question

I need to create a script that will run via a .bat file on Windows 7 machines. The batch file will create a scheduled task that runs at a random time between 11am and 9pm on Sunday. I am currently using this command that I know works but only at a specific time:

schtasks /create /tn "task" /tr c:\task.vbs /sc WEEKLY /d SUN /st 21:00:00 /ru ""

I want to randomize the time, so that I can run the same exact batch file across all 400 systems and have each of them get a different time within that range, so they aren't running the task at the same time. I don't care if a few of them get identical times, but I don't want all 400 running within the same few minutes. Once I have a single batch file that works as intended, it would be pushed out to all systems and run one time to schedule that task.

Based on searching other answers here, I've tried using the following scripts, for now just trying to generate a random hour, but I am not getting the results I need:

Option 1)

set /a num=%random% * (21 - 11 + 1) / 32768 + 11

That command will generate a number within the correct range, but it's not really random, it seems to be based on the clock or something, because if I run it several times real quick, I get the same number and then it increments up as time passes, this wont work.

Option 2)

@echo off & setlocal EnableDelayedExpansion

for /L %%a in (1 1 20) do (
        call:rand 11 21
        echo !RAND_NUM!
) >> random2.txt

goto:EOF

REM The script ends at the above goto:EOF.  The following are functions.

REM rand()
REM Input: %1 is min, %2 is max.
REM Output: RAND_NUM is set to a random number from min through max.
:rand
SET /A RAND_NUM=%RANDOM% * (%2 - %1 + 1) / 32768 + %1
goto:EOF

That code, generates the random number correctly, but I don't know how to insert that number into the command like I want. I have tried replacing the ">> random2.txt" with the schtasks command, but it doesn't work, and I'm not getting and feed back to a log file to see why, I've tried it like this:

@echo off & setlocal EnableDelayedExpansion

for /L %%a in (1 1 1) do (
        call:rand 11 21
        echo !RAND_NUM!
)
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st %RANDOM%:00:00 /ru "" > task.txt 2>&1
goto:EOF

REM The script ends at the above goto:EOF.  The following are functions.

REM rand()
REM Input: %1 is min, %2 is max.
REM Output: RAND_NUM is set to a random number from min through max.
:rand
SET /A RAND_NUM=%RANDOM% * (%2 - %1 + 1) / 32768 + %1
goto:EOF

So in that I've tried to use the %RANDOM% var as the hour component of the command.

The perfect solution would generate a random two digit number between 11 and 21 for the hours section and then a two digit number between 00 and 59 for the minutes section of the command with a colon in between them as required by the format of the command so the time section of the schtasks command would look something like this:

%hour11-21%:%min00-59%:00

I hope I have given enough detail here, can anyone tell me what am I doing wrong? Is there an easier way to do this? Thank you in advance!

Was it helpful?

Solution

Try this:

@echo off
setlocal enabledelayedexpansion
call :rand 1 1 dummy
call :rand 11 21 ret
call :rand 0 59 ret2
if %ret2% LSS 10 set ret2=0%ret2%
echo schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st %ret%:%ret2%:00 /ru "" > task.txt 2>&1
exit /b

:rand
setlocal
SET /A RAND_NUM=%RANDOM% * (%2 - %1 + 1) / 32768 + %1
endlocal & set %~3=%RAND_NUM%
exit /b

Output:

schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 11:00:00 /ru ""

U:\Scripts\Batch>RandomNumBetween.cmd
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 16:7:00 /ru ""

U:\Scripts\Batch>RandomNumBetween.cmd
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 17:46:00 /ru ""

U:\Scripts\Batch>RandomNumBetween.cmd
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 19:35:00 /ru ""

U:\Scripts\Batch>RandomNumBetween.cmd
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 13:54:00 /ru ""

U:\Scripts\Batch>RandomNumBetween.cmd
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 14:51:00 /ru ""

U:\Scripts\Batch>RandomNumBetween.cmd
schtasks /create /tn "task" /tr c:\task.vbs /d SUN /sd 10/28/2012 /st 21:48:00 /ru ""

OTHER TIPS

If you schedule the task with schtasks and want the start time to vary every time the task is run, you can use this in a batch file:

:: Delay for up to 5 minutes (300 seconds)
set /A DELAY=%RANDOM% %% 301
ping /n %DELAY% /w 1000 localhost > NUL

You could use timeout instead of ping on Windows 7/Server 2008+.

I solved it with:

set /a H=%random% * (21 - 11 + 1) / 32768 + 11

set /a M=%random% * (59 - 11 + 1) / 32768 + 11

H = Hour

M = Minute

then the scheduled task created with

SCHTASKS /Create /RU "NT AUTHORITY\SYSTEM" /SC WEEKLY /D FR /ST %H%:%M%

Greets, Dan.

Way too complex set /a commands. Use % = "remainder" which works like "modulo" for positive values. Even if it is counting "up" by only one digit in the short time, avoiding / 32768 makes it more random since I had that seemingly "not as random as I thought" effect too. You need to use double % when using modulo in a .CMD, therefore we end up with triple %

:hour 11:00 until 21:00
set /a HOUR=%RANDOM%%%11+11
:minute 0-59
set /a MINUTE=%RANDOM%%%60
schtasks /create /tn "task" /tr c:\task.vbs /sc WEEKLY /d SUN /st %HOUR%:%MINUTE%:00 /ru ""
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top