How to compare two time string in batch file - batch-file

I want to get the last two line and compare their time, and judge whether the time difference more than 20 seconds. Below is My batch file script and test file. I have successfully got the last two line and print out. When I split the time and compare it, I found the time will leading zero. How could I comare the two time? thanks in advance!
My test file:
08:00:05 I 0-ChecK Loop = 0 Start
08:00:05 I 8124-ChecK Loop = 8124 Start
08:00:15 I 8125-ChecK Loop = 8125 Start
08:00:25 I 8126-ChecK Loop = 8126 Start
08:00:35 I 8127-ChecK Loop = 8127 Start
08:00:42 I 8128-ChecK Loop = 8128 Start
My batch file:
#echo off
setlocal enabledelayedexpansion
for %%A in (C:\Users\Howard\Desktop\test.txt) do (
set "firstline="
set "secondline="
for /f "delims=" %%B in ('type "%%A"') do (
set firstline=!secondline!
set secondline=%%B
)
echo %%A !secondline!
)
for /f "tokens=1,2,3" %%i in ("!firstline!") do (
set time1=%%i
set I1=%%j
set count1=%%k
)
echo %time1%
::set /A T1="%time1:~1,2% * 24"
::set /a T1=(%time1:~0,2% * 24) + (%time1:~3,2% * 60) + (%time1:~6,2% *60)
::echo %T1%
echo %I1%
echo %count1%
for /f "tokens=1,2,3" %%i in ("!secondline!") do (
set time2=%%i
set I2=%%j
set count2=%%k
)
echo %time2%
echo %I2%
echo %count2%
pause
output:

Here's a small extension of my commented example which should simply report whether the timespan was over twenty seconds:
#%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "$Content = Get-Content -LiteralPath '%UserProfile%\Desktop\test.txt' -Tail 2; If ((New-TimeSpan -Start ($Content[0] -Split ' ')[0] -End ($Content[1] -Split ' ')[0]).TotalSeconds -GT 20) {Exit 2}"
#If ErrorLevel 2 Echo Timespan is over twenty seconds.

Related

Select info from txt in bat file

There is a text file that stores a log of processed files in the following format:
Name: kn-25.txt Date: 01.02.2013 Time: 14:50
The task is to write a batch file which will make a selection from this file for a given month (mm) and year (yyyy) into the file result.txt.
#echo off
chcp 1251 >nul
setlocal EnableDelayedExpansion
echo Введіть початковий файл:
set /p in_file=%~nx1
if not exist %in_file% goto end
del D:\result.txt
set /a count=0
set /a con=0
set /a min=101
set /p month=Введіть місяць:
if [%month%] == [] goto end
set /p year=Введіть рік:
if [%year%] == [] goto end
goto start
:start
if count equ 0 (
set /a con=0
) else (
set /a con=0-!count!
)
for /f "tokens=*" %%i in (%in_file%) do (
for /f "tokens=1-6" %%a in ("%%~i") do (
for /f "delims=. tokens=1-3" %%u in ("%%~d") do (
if "%%v"=="%month%" if "%%w"=="%year%" (
set /a con=!con!+1
if "%%u" leq "!min:~-2!" (
set /a min1=!min!-1
if "%%u" neq "!min1:~-2!" (
set /a count=!count!+1
echo !count!. %%i>>D:\result.txt
)
)
)
)
)
)
if %con% neq %count% (
set /a min=!min!+1
goto start
) else (
type D:\result.txt
echo
#pause
endlocal
exit /B
)
:end
echo Ви не ввели параметр!
echo
#pause
endlocal
exit /B
I wrote this code, but got an error:
Cannot find the file Name:.
Any suggestions?
Note: information in the generated file must be sorted by date
Example:
Initial file content:
Name: kn-25.txt Date: 07.03.2013 Time: 14:50
Name: kn-26.txt Date: 02.03.2013 Time: 23:50
Name: MyFil.txt Date: 03.08.2012 Time: 12:00
Name: ca-21.txt Date: 28.03.2013 Time: 01:00
Name: ca-25.txt Date: 01.30.2012 Time: 10:05
Input: 03.2013
Output:
Name: kn-26.txt Date: 02.03.2013 Time: 23:50
Name: kn-25.txt Date: 07.03.2013 Time: 14:50
Name: ca-21.txt Date: 28.03.2013 Time: 01:00
a slightly different approach (slower than the other ones, but working as intended):
#echo off
setlocal EnableDelayedExpansion
set in_file=t.txt
set month=03
set year=2013
(for /l %%a in (100,1,131) do (
set "day=%%a"
findstr "!day:~-2!.%month%.%year%" %in_file%
))>result.txt
For sorting we ignore the first 22 characters sort command.
#echo off
chcp 1251 >nul
setlocal EnableDelayedExpansion
echo Введіть перший параметр:
set /p in_file=%~f1
if not exist %in_file% goto end
set /p month=Введіть місяць:
if [%month%] == [] goto end
set /p year=Введіть рік:
if [%year%] == [] goto end
findstr /C:"%month%.%year%" %in_file% | sort /+22 > D:\result.txt
type D:\result.txt
pause
exit /B
:end
echo Ви не ввели параметр!
pause
exit /B
We can use findstr /O if we want an offset on each line.
If you are on a supported Windows machine, it will have PowerShell on it. Here is one way to do it. This assumes that the date is in DD.MM.YYYY format.
Since it has already parsed out the date and time with a regex, it creates a [DateTime] to associate with the log file line. It then uses this [DateTime] to sort the file, but only outputs the log file line.
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,Position=0)]
[string]$LogFile
,[Parameter(Mandatory=$true,Position=1)]
[int]$Year
,[Parameter(Mandatory=$true,Position=2)]
[int]$Month
)
Get-Content -Path $LogFile |
ForEach-Object {
if ($_ -match 'Name: .* Date: ((\d*).(\d*).(\d*)) Time: ((\d*):(\d*))') {
#$Matches
$fday = [int]$Matches[2]
$fmonth = [int]$Matches[3]
$fyear = [int]$Matches[4]
$fhour = [int]$Matches[6]
$fminutes = [int]$Matches[7]
if (($fmonth -eq $Month) -and ($fyear -eq $Year)) {
[PSCustomObject]#{
Line = $_
Timestamp = Get-Date -Year $fyear -Month $fmonth -Day $fday `
-Hour $fhour -Minute $fminutes -Second 0
}
}
}
} |
Sort-Object -Property Timestamp |
ForEach-Object { $_.Line }
Invoke it using the following command. If you do not provide the parameters, PowerShell will prompt for them. That is like using SET /P in a cmd.exe bat file script.
.\logparse.ps1 -LogFile '.\logparse.in.txt' -Year 2013 -Month 2
If you must run it from a cmd.exe shell, use:
powershell -NoLogo -NoProfile -File ".\logparse.ps1"
The following code uses a temporary file containing the lines from the input file filtered by the given date information (month and year), but with each line prefixed by year, month and day as well as the time value, which allows easy alphabetic sorting that is fine for your fixed-width date/time formats:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "IN_FILE=%~1"
set "OUT_FILE=D:\result.txt"
set "TMP_FILE=%TEMP%\%~n0_%RANDOM%.tmp"
set "MONTH=03"
set "YEAR=2013"
rem /* Filter lines for given month and year, then write them
rem to temporary file, preceded by year, month, date and `:`: */
> "%TMP_FILE%" (
for /F usebackq^ delims^=^ eol^= %%L in ("%IN_FILE%") do (
for /F "tokens=3-5 delims=:" %%D in ("%%L") do (
for /F "tokens=1-3 delims=. " %%A in ("%%D") do (
if "%%B" == "%MONTH%" if "%%C" == "%YEAR%" (
echo(%%C%%B%%A%%E%%F:%%L
)
)
)
)
)
rem /* Sort content of temporary file, remove prefix
rem up to the (first) `:` and write to result file: */
> "%OUT_FILE%" (
for /F "tokens=1* delims=:" %%E in ('sort "%TMP_FILE%"') do (
echo(%%F
)
)
rem // Clean up temporary file:
del "%TMP_FILE%"
endlocal
exit /B

Batch: list available hard drives and work with chosen option

I would like to list all available, removable hard drives in a batch script and continue to work with the chosen option. I know there are options like
wmic logicaldisk get caption,volumename
to list the hard drives and
SET /P M=Type 1 or 2 then press ENTER:
IF %M%==1 GOTO One
IF %M%==2 GOTO Two
to create a menu. But how do I store the volumes in variables and list them in a menu?
Something like:
Choose from list:
1) D:\Harddrivename1
2) E:\Harddrivename2
Enter option: 2
Any help is appreciated!
Here's a function that'll let you create an array of drives that are not of type 3 (fixed):
rem // populates arrayname, arrayname.length, and arrayname.ubound
:getRemovableDrives <arrayname>
rem // unset array if exists
for /f "delims==" %%I in ('2^>NUL set %~1') do set "%%~I="
setlocal enabledelayedexpansion
set /a %~1.length = 0, %~1.ubound = -1
rem // note: nested for /f loops convert UCS-2 encoded WMI results to ANSI
for /f "skip=2 delims=" %%# in (
'wmic logicaldisk where "DriveType <> 3" get caption^,volumename /format:csv'
) do for /f "tokens=2,3 delims=," %%I in ("%%~#") do (
set "%~1[!%~1.length!].caption=%%~I"
set "%~1[!%~1.length!].volumename=%%~J"
set /a %~1.ubound = %~1.length, %~1.length += 1
)
rem // Trick to make private variables public
for /F "delims=" %%I in ('set %~1') do (
if defined %~1.ubound endlocal
set "%%~I"
)
exit /b
Here's a full example illustrating how to use the function:
#echo off & setlocal enabledelayedexpansion
:begin
call :getRemovableDrives drives
if %drives.length% equ 0 (
echo No removable drives found.
exit /b 1
)
set choices=
echo Removable drives:
echo;
for /L %%I in (0, 1, %drives.ubound%) do (
set "choices=!choices!%%I"
echo(%%I^) !drives[%%I].caption! (!drives[%%I].volumename!^)
)
echo(X^) exit
set "choices=%choices%x"
echo;
choice /C %choices% /N /M "Press a number (or X to quit): "
set /a choice = %ERRORLEVEL% - 1
if not defined drives[%choice%].caption exit /b 0
echo You chose !drives[%choice%].caption! (!drives[%choice%].volumename!^)
goto :begin
goto :EOF
rem // populates arrayname, arrayname.length, and arrayname.ubound
:getRemovableDrives <arrayname>
rem // unset array if exists
for /f "delims==" %%I in ('2^>NUL set %~1') do set "%%~I="
setlocal enabledelayedexpansion
set /a %~1.length = 0, %~1.ubound = -1
rem // note: nested for /f loops convert UCS-2 encoded WMI results to ANSI
for /f "skip=2 delims=" %%# in (
'wmic logicaldisk where "DriveType <> 3" get caption^,volumename /format:csv'
) do for /f "tokens=2,3 delims=," %%I in ("%%~#") do (
set "%~1[!%~1.length!].caption=%%~I"
set "%~1[!%~1.length!].volumename=%%~J"
set /a %~1.ubound = %~1.length, %~1.length += 1
)
rem // Trick to make private variables public
for /F "delims=" %%I in ('set %~1') do (
if defined %~1.ubound endlocal
set "%%~I"
)
exit /b
Hopefully you can use this to get you started. In case I guessed incorrectly about the drive type detection, see this page, Ctrl + F and find DriveType on the page.
This might get you started. It is in PowerShell. It gets a list of all removable (non-floppy) drives and presents a list for the user to chose from. If there is only one drive, it does not present the menu.
There is much to be done. There is no range or error checking on the user's input. And, of course, it is not stated what you want to do with the drive.
$drivelist = #(Get-WMIObject Win32_LogicalDisk -Filter "MediaType = 11")
if ($drivelist.Count -eq 0) { Write-Host 'There are no removable drives.'
} elseif ($drivelist.Count -eq 1) { $thedrive = $drivelist[0]
} else {
Write-Host 'Removable drives'
$i = 1
foreach ($drive in $drivelist) {
Write-Host $('{0}. {1} {2}' -f $i, $drive.DeviceId, $drive.VolumeName)
$i += 1
}
$dn = Read-Host -Prompt 'Enter the drive number.'
$thedrive = $drivelist[$dn - 1]
}
# At this point, $thedrive is a System.Management.ManagementObject#root\cimv2\Win32_LogicalDisk
# ready to be used for something.
$thedrive | Format-List * -Force

Batch to output a list of dates from given for /L parameter

Please consider the following codes:
#echo off
setlocal enabledelayedexpansion
FOR /L %%G IN (0,1,19) DO (
set /a "Dday=%_day%+%%G"
if %mth% equ sml (
if !Dday! gtr 30 (
set "_day=1"
set /a "_month+=1"
)
if !_month! gtr 12 (
set "_month=1"
set /a "_year+=1"
)
) else (
if %mth% equ big (
if !Dday! gtr 31 (
set "_day=1"
set /a "_month+=1"
)
if !_month! gtr 12 (
set "_month=1"
set /a "_year+=1"
)
)
)
echo !Dday!/!_month!/!_year!.txt
)
Consider the following date: 20/04/2016
_day = 20; _month = 04; _year = 2016; mth=sml;
and my output is this:
It increases the day from 30 instead of changing it to 1. Can I know what have I done wrong? Please advise. Thanks
There are two problems in this script. First as #SomethignDark pointed out, you need to use !_day! instead of %_day%.
Second when Dday is greater than 30, %%G is 12. So you expression of !_day!+%%G will be 13 instead of 1.
So you need something like
...
FOR /L %%G IN (0,1,19) DO (
set /a "Dday=!_day!+%%G"
if !_day! equ 1 set /a "Dday=!_day!+%%G-12"
...
You know, pure batch is really cumbersome with date math. What will you do for months with 31 days? For February? During leap year? You should consider, if not altogether switching to another language with a proper date object, then at least borrowing from one. Here's a Batch + PowerShell hybrid example:
<# : batch portion
#echo off & setlocal
if "%~1"=="" (
echo usage: %~nx0 startdate
goto :EOF
)
set "startdate=%~1"
set "daysToAdd=19"
rem # evaluate PowerShell hybrid code and capture output as %%I
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
rem # do something useful with %%I here
echo %%I.txt
)
goto :EOF
: end batch / begin PowerShell hybrid code #>
# cast "startdate" environment variable value as a datetime object
[datetime]$d = $env:startdate
for ($i = 0; $i -le $env:daysToAdd; $i++) {
$d.addDays($i).toString("dd-MM-yyyy")
}
Or if you prefer the speed of VBScript, here's a Batch + VBScript hybrid example. Its allowed date input is perhaps not quite as flexible as that of PowerShell, but it does execute nearly instantly.
<!-- : batch portion
#echo off & setlocal
if "%~1"=="" (
echo usage: %~nx0 startdate
goto :EOF
)
set "startdate=%~1"
set "daysToAdd=19"
rem # evaluate VBScript hybrid code and capture output as %%I
for /f "delims=" %%I in ('cscript /nologo "%~f0?.wsf" "%startdate%" "%daysToAdd%"') do (
rem # do something useful with %%I here
echo %%I.txt
)
goto :EOF
: end batch / begin VBScript -->
<job>
<script language="VBScript">
if not IsDate(WSH.Arguments(0)) then
WSH.StdErr.WriteLine("Not a valid date.")
WSH.Quit(1)
end if
d = CDate(WSH.Arguments(0))
For i = 0 to WSH.Arguments(1)
d2 = DateAdd("d", i, d)
WSH.Echo(Day(d2) & "-" & Month(d2) & "-" & Year(d2))
Next
</script>
</job>
Or if you're more comfortable with JavaScript syntax, you could do a Batch + JScript hybrid solution.
#if (#CodeSection == #Batch) #then
#echo off & setlocal
if "%~1"=="" (
echo usage: %~nx0 startdate
goto :EOF
)
set "startdate=%~1"
set "daysToAdd=19"
rem // evaluate VBScript hybrid code and capture output as %%I
for /f "delims=" %%I in (
'cscript /nologo /e:JScript "%~f0" "%startdate%" "%daysToAdd%"'
) do (
rem // do something useful with %%I here
echo %%I.txt
)
goto :EOF
#end // end batch / begin JScript
Date.prototype.addDays = function(num) {
this.setDate(this.getDate() + num);
return this;
}
for (var i=0; i<WSH.Arguments(1); i++) {
var d = new Date(WSH.Arguments(0)).addDays(i);
WSH.Echo([d.getDate(), (d.getMonth() + 1), d.getFullYear()].join('-'));
}
Either way, VBScript, JScript, and PowerShell will all let you add n days to a date object, and that date object automatically handles calendar quirks without your explicitly needing to script for them.

How to check a string does not start with a number in Batch?

How can I check that the first character of a string is a letter and so that it is not a number, or rather a cipher? There are no spaces or special characters in this string.
#ECHO OFF
SETLOCAL
SET /a num=5678
CALL :initnum
SET "num=hello"
CALL :initnum
SET "num=4ello"
CALL :initnum
SET "num=hell0"
CALL :initnum
SET "num=he8lo"
CALL :initnum
SET "num="
CALL :initnum
ECHO(==============
SET /a nam=7654
SET "nem=hello"
SET "nim=4ello"
SET "nom=hell0"
SET "num=he8lo"
SET "nzm="
CALL :initnum2 nam
CALL :initnum2 nem
CALL :initnum2 nim
CALL :initnum2 nom
CALL :initnum2 num
CALL :initnum2 nzm
GOTO :EOF
:initnum
IF NOT DEFINED num ECHO NUM is empty, so it doesn't begin with a numeric&GOTO :EOF
FOR /l %%a IN (0,1,9) DO IF %num:~0,1%==%%a ECHO %num% Begins with numeric&GOTO :EOF
ECHO %num% Does NOT begin with a numeric
GOTO :eof
:initnum2
IF NOT DEFINED %1 ECHO %1 is empty, so it doesn't begin with a numeric&GOTO :EOF
CALL SET "$1=%%%1%%"
FOR /l %%a IN (0,1,9) DO IF %$1:~0,1%==%%a ECHO %1 (%$1%) Begins with numeric&GOTO :EOF
ECHO %1 (%$1%) Does NOT begin with a numeric
GOTO :eof
You should be able to get what you want from this demo.
#echo off
setlocal enableextensions disabledelayedexpansion
set "var=1hello"
for /f "tokens=* delims=0123456789" %%a in ("%var%") do (
if not "%%a"=="%var%" echo var starts with a number
)
If the var contents starts with a number, the token/delim management in the for command will remove it.
edited just to include the usual (included the previous code) and some less used options just in case someone is interested
#echo off
setlocal enableextensions disabledelayedexpansion
set "var=1hello"
echo(%var%
rem Option 1 - Use the for command to tokenize the string
rem A dot is added to handle empty vars
for /f "tokens=* delims=0123456789" %%a in ("%var%.") do (
if not "%%a"=="%var%." (
echo var starts with a number
) else (
echo var does not start with a number
)
)
rem Option 2 - Use set arithmetic and detect errors
rem This will fail if the string starts with + or -
set "%var%_=0"
set /a "test=%var%_" 2>nul
if not errorlevel 1 (
echo var does not start with a number
) else (
echo var starts with a number
)
rem Option 3 - Use substring operations and logic operators
set "test=%var%."
if "%test:~0,1%" GEQ "0" if "%test:~0,1%" LEQ "9" set "test="
if defined test (
echo var does not start with a number
) else (
echo var starts with a number
)
rem Option 4 - Use findstr
rem This is SLOW as findstr needs to be executed
echo(%var%|findstr /b /r /c:"[0-9]" >nul && (
echo var starts with a number
) || (
echo var does not start with a number
)
I think this is the simplest way:
#echo off
setlocal EnableDelayedExpansion
set digits=0123456789
set var=1something
if "!digits:%var:~0,1%=!" neq "%digits%" (
echo First char is digit
) else (
echo First char is not digit
)
The first character of var is tried to be removed from digits string. If such a char was a digit, digits string change; otherwise, digits string remains the same.
#echo off
setlocal
set "the_string=a23something"
for /l %%a in (%the_string% ; 1 ; %the_string%) do set "cl_string=%%~a"
if %the_string:~0,1% neq 0 if "%cl_string%" equ "0" (
echo does not start with number
) else (
echo starts with number
)
endlocal
Another approach is with FINDSTR which eventually will be slower as it is an external for cmd.exe command.
#echo off
set "the_string=something"
echo %the_string%|findstr /b /r "[0-9]" >nul 2>&1 && (
echo starts with number
) || (
echo does not start with number
)
This will work in your situation:
echo %variable%|findstr "^[a-zA-Z]" >nul && echo it starts with an alpha character
Using findstr with regexp :
#echo off
set "$string=2toto"
echo %$string:~0,1%|findstr /i "^-*0*x*[0-9][0-9]*$">nul && echo is NUM || echo Is not NUM
in place of echo is NUM or echo is not NUM you can use a goto to redirect your script the way you want it.
#echo off
set "$string=2toto"
echo %$string:~0,1%|findstr /i "^-*0*x*[0-9][0-9]*$">nul && goto:isnum || goto:isnotnum
:isnum
echo is NUM
exit/b
:isnotnum
echo is not NUM
You have to set the string as a variable; in this way you are able to extract substrings from a main string. Here is an example:
#echo off
set EXAMPLESTRING=12345abcde
set FIRSTCHARACTERSTRING=%EXAMPLESTRING:~0,1%
The result of this short script should be 1 in this case.
Then, you can set a series of conditions to verify whether the first character is a number or not:
if %FIRSTCHARACTERSTRING%==0 goto NUMBER
if %FIRSTCHARACTERSTRING%==1 goto NUMBER
if %FIRSTCHARACTERSTRING%==2 goto NUMBER
if %FIRSTCHARACTERSTRING%==3 goto NUMBER
if %FIRSTCHARACTERSTRING%==4 goto NUMBER
if %FIRSTCHARACTERSTRING%==5 goto NUMBER
if %FIRSTCHARACTERSTRING%==6 goto NUMBER
if %FIRSTCHARACTERSTRING%==7 goto NUMBER
if %FIRSTCHARACTERSTRING%==8 goto NUMBER
if %FIRSTCHARACTERSTRING%==9 goto NUMBER
goto LETTER
:NUMBER
echo The first character is a number!
goto EOF
:LETTER
echo The first character is a letter!
goto EOF
Maybe this is not the most efficient solution but it works fine and it is easier to understand.

Add random number to batch file that generates temp passwords

I would be very grateful if some one could help me fix my script, I want to add a 4 digit random number to the end of a string, in essence it is a script that reads a csv file for an email address then creates a powershell file for me to run but the part im having issues with is the random 4 digit number appended to the password string, please see below, if I run the script now it runs without errors but no 4 digit random number appended, can anyone help im sure its something small im missing thanks
Spud
#echo off & setlocal EnableDelayedExpansion
for /F "delims=" %%j in ('type "Input.csv"') do (
set /A RND=%RANDOM% %% 8889 + 1111
echo.Set-MsolUser -UserPrincipalName %%j -StrongPasswordRequired $false
echo.Set-MsolUserPassword -userPrincipalName %%j -NewPassword "TTech%RND%*" -ForceChangePassword $false
echo.Set-MsolUser -UserPrincipalName %%j -PasswordNeverExpires $true
echo.
) >> "Output.txt"
You need to change %var% to !var! to access the dynamic value of a variable with delayedexpansion in effect.
set /A RND=!RANDOM! %% 8889 + 1111
would set your variable RND to 1111..9999
echo.Set-MsolUserPassword -userPrincipalName %%j -NewPassword "TTech!RND!*" -ForceChangePassword $false
would then append the resultant value to TTech
Alternatively, try
set RND=000!RANDOM!
...
echo.Set-MsolUserPassword -userPrincipalName %%j -NewPassword "TTech!RND:~-4!*" -ForceChangePassword $false
which would construct a string 000+0..32767 and then use the last 4 characters after TTech so you'd get leading-zero-filled 4-digit numerics.
Use this for your random number:
Set max=9999
Set min=1000
Set /A rand=%random% %% (max - min + 1)+ min
Echo %rand%
Keep in mind, inside of a for loop, you'll need to use delayedexpansion and escape the parenthesis.
Set max=9999
Set min=1000
for /l %%a in (1,1,10) do (
Set /A rand=!random! %% ^( max - min + 1 ^) + min
Echo.!rand!
)
exit /b
Based on Magoo's answer, you know the issue was with using delayed variable syntax instead of standard parens. I wrapped up his answer and mine into a couple of little functions that are easily reusable.
call :RandomRange 1000 9999 ret
Echo %ret%
call :RandomRange2 ret
echo %ret%
exit /b
:RandomRange min max ret
#echo off & setlocal enabledelayedexpansion
Set /A rand=!random! %% (%2 - %1 + 1) + %1
endlocal & set %3=%rand%
exit /b
:RandomRange2 ret
#echo off & setlocal enabledelayedexpansion
set rnd=000!random!
set rnd=!rnd:~-4!
endlocal & set %1=%rnd%
exit /b
Hope that helps
This will give you a random 4 digit number:
set num=%random%%random%%random%%random%
set num=%num:~-4%
Or with delayed expansion enabled inside a loop:
set num=!random!!random!!random!!random!
set num=!num:~-4!

Resources