I am using a loop script and I was wondering how I can make the variable add 1 to each number as it goes here's what I have (this is just a snip):
for /f "tokens=1,2 delims=:" %%a in (C:\bot\userpass.txt) do (
set /a Number=%Number%+1
Echo Starting Bot #%Number%
START Client.exe %Config% %%a %%b %Server%
PING 1.1.1.1 -n 1 -w %DelayTime% >NUL
)
Only when it echos it doesn't display the correct number, how do I fix this?
You should enable delayed expansion and use !!:
setlocal enabledelayedexpansion
for /f "tokens=1,2 delims=:" %%a in (C:\bot\userpass.txt) do (
set /a Number=!Number!+1
Echo Starting Bot #!Number!
START Client.exe !Config! %%a %%b !Server!
PING 1.1.1.1 -n 1 -w !DelayTime! >NUL
)
Related
I'm trying to make a .bat file that pings arbitrary hosts, but my options are not working. Maybe someone can help with this question
Why not scan all devices at once? You can do it in seconds
Create a file named Scan.bat
#echo off
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
arp -d
setlocal
setlocal enabledelayedexpansion
for /f "usebackq tokens=*" %%a in (`ipconfig ^| findstr /i "192"`) do (
for /f delims^=^:^ tokens^=2 %%b in ('echo %%a') do (
for /f "tokens=1-4 delims=." %%c in ("%%b") do (
set _o1=%%c
set _o2=%%d
set _o3=%%e
set _o4=%%f
set _3octet=!_o1:~1!.!_o2!.!_o3!.
for /L %%a in (1,1,254) do (start /min ping /n 1 /l 1 !_3octet!%%a)
)))
endlocal
Run the above file every time before typing the command below
arp -a | findstr 192 | findstr dynamic
You can then view all the devices connected to your network with this command
I am using the code below to list ip addresses from a list of computer names on list.txt, but they have to be pinging to list. How can I edit the code to show these IP addressess that do not ping also?
#echo off
Echo Pinging list...
set ComputerList=list.txt
Echo Computername,IP Address>Final.csv
setlocal enabledelayedexpansion
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3" %%B in ('ping -n 1 -l 1 %%A ^|findstr Reply') do (
set IPadd=%%B
echo %%A,!IPadd:~0, -1!>>Results.csv
))
pause
list.txt contains the following:
and
Results.csv will populate
but it will not populate IP address for PCWINDATA103 because it is not pinging but I know an IP exists
Force a custom output in case findstr doesn't find Reply (take care of "tokens=3"):
...
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3 delims=: " %%B in ('ping -4 -n 1 -l 1 %%A ^|findstr "Reply" ^|^|echo x x offline') do (
echo %%A,%%B
)
)
The code runs a very simple process of pinging multiple addresses endlessy and outputting the results to a log file until manually stopped.
#echo off
title ping_logger
set d1=%date:~4%
set d2=%d1:/=-%
set t1=%time::=.%
set t2=%t1: =%
set host=X.X.X.1;X.X.X.162
set hostname=%host:;=+%
set pinghostname=%host:;= and %
set logfile=Log_%hostname%_%ComputerName%_%d2%_%t2%.csv
setlocal enableextensions ENABLEDELAYEDEXPANSION
set counter=0
for %%A IN (%host%) DO (
set /a counter+=1
)
endlocal && set counter=%counter%
echo Target Host(s) = %host%>%logfile%
echo Pinging %pinghostname% with 32 bytes of data: >>%logfile%
timeout %counter% >NUL
:Ping
FOR %%A IN (%host%) DO (
for /F "tokens=* skip=2" %%A in ('ping %%A -n 1 ') do (
echo %date:~4%, %time:~0,2%:%time:~3,2%:%time:~6,2%, %%A>>%logfile%
echo %date% %time:~0,2%:%time:~3,2%:%time:~6,2%, %%A
)
)
IF (%counter% LSS 2) timeout 1 >NUL
GOTO Ping
The output is capturing too much into the log file. I'm looking to only get the first line from each response such as the highlighted lines
:DoPing
FOR %%A IN (%host%) DO (
set "pung="
for /F "tokens=* skip=2" %%A in ('ping %%A -n 1 ') do if not defined pung (
echo %date:~4%, %time:~0,2%:%time:~3,2%:%time:~6,2%, %%A>>%logfile%
echo %date% %time:~0,2%:%time:~3,2%:%time:~6,2%, %%A
set "pung=Y"
)
)
IF (%counter% LSS 2) timeout 1 >NUL
GOTO DoPing
(I'm allergic to using keywords/executable names as labels)
Simply set a flag value pung to nothing so that it is undefined when the pings start. On reporting the first line, set pung to non-empty, so it is then defined and the remining report lines are suppressed.
Next loop of %%A clears pung before issuing the ping for the next host...
Another way:
:DoPing
FOR %%A IN (%host%) DO (
for /F "tokens=1* skip=2" %%A in ('ping %%A -n 1 ') do if "%%A" == "Reply" (
echo %date:~4%, %time:~0,2%:%time:~3,2%:%time:~6,2%, %%A %%B>>%logfile%
echo %date% %time:~0,2%:%time:~3,2%:%time:~6,2%, %%A %%B
)
)
IF (%counter% LSS 2) timeout 1 >NUL
GOTO DoPing
This time, see whether the first token is the string Reply and only write the report if this is so.
I'm stuck on this one, I've managed to create a batch file that imports list of IPs & hostnames but when I test for success or failure, I'd like to output how long it took. I don't know how to capture this and include it in the output. I'm trying to hide the default ping.exe output. Here's my code
#echo off
for /F "tokens=1,2 delims= " %%A in (computers.txt) do (
rem ping -n 1 %%A | findstr /i "TTL=" | find "Reply" > nul
if %errorlevel% == 0 (
echo %%B %%A successful ping in ?? Seconds
echo %%B %%A successful ping [%date%, %time%] >> log.txt
)
)
Pause
I've figured it out:
#echo off
setlocal enableDelayedExpansion
for /F "tokens=1,2 delims= " %%A in (computers.txt) do (
for /f "tokens=7 delims== " %%G in ('ping -n 1 %%A') do (
ping -n 1 %%A >nul
if errorlevel 1 (
echo %%B %%A unsuccessful ping
echo %%B %%A unsuccessful ping [!date!, !time!] >> log.txt
) else if "%%~G" NEQ "of" if "%%~G" NEQ "0" (
set ms=%%~G
set ms=!ms:ms=!
for /f %%Z in ('powershell !ms!/1000') do set second=%%~Z
echo %%B %%A successful ping in !second! seconds
echo %%B %%A successful ping [!date!, !time!] >> log.txt
)
)
)
Pause
Using FOR /F, it is possible to process command output.
As you may see, I have 2 ping -n 1 %%A. It is because FOR /F doesn't capture the ERRORLEVEL generated by the processing command. The first command gets the output, the second gets ERRORLEVEL.
if "%%~G" NEQ "of" if "%%~G" NEQ "0" filters out the unneeded results.
The powershell command converts milliseconds to second(batch file does not support decimal numbers)
I/O example
I don't have any other computers on my network, therefore I tested it with URLs.
Input -> Output
www.google.com A A www.google.com successful ping in 0.002 seconds
www.yahoo.com B B www.yahoo.com successful ping in 0.032 seconds
a.a.a C C a.a.a unsuccessful ping
I currently have a batch file that reads a list of computer names and pings each of these and outputs the ones that reply to a csv file with the computer name and ip address.
I now need to edit this to also find out the user of the machine. I need to contact users which are online to arrange some work done to their computer. Their can be over a hundred machines in the batch file so to manually find out each user takes time. Is there a way to do this?
`IF EXIST C:\test\new.csv (del C:\test\new.csv)
IF EXIST C:\test\final.csv (del C:\test\final.csv)
set ComputerList=C:\test\ClientList.txt
Echo Computer Name,IP Address>Final.csv
setlocal enabledelayedexpansion
echo please wait...
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3" %%B in ('ping -n 1 -l 1 %%A ^|findstr Reply') do (
set IPadd=%%B
echo %%A,!IPadd:~0,-1!>>final.csv
)
)
findstr /V "IPAddress" final.csv >> C:\test\new.csv
echo identified machines for Install
start excel C:\test\new.csv
echo opened csv file`
The command I want to use to get the username is:
`wmic.exe /NODE: %%A COMPUTERSYSTEM GET USERNAME`
Thanks
Mark
Here is a function I wrote to do just what you are trying to do:
:GetLoggedInUser comp user
for /f %%u in (
'wmic /NODE:"%1" Computersystem get username^|find "\"') do (
if not errorlevel 1 ( for /f "tokens=2 delims=\" %%a in (
'wmic /NODE:"%1" Computersystem get username^|find "\"' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
) ELSE (for /f "skip=1" %%a in (
'wmic /NODE:"%1" Computersystem get username' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
))
Exit /b
Here is my function for pinging. It returns a 0 if the ping succeeded and a 1 otherwise.
:IsPingable comp
ping -n 1 -w 3000 -4 -l 8 "%~1" | Find "TTL=">nul
exit /b
Usage example:
for /l %%a in (1,1,255) do (
call:IsPingable 10.6.1.%%a && (
echo ping 10.6.1.%%a used )||( echo ping 10.6.1.%%a unused )
)
And here is for if you're pinging IP's and want to return the hostname as well:
:IsPingable2 comp ret
setlocal
for /f "tokens=2" %%a in (
'"ping -a -n 1 -4 "%~1" | Find "Pinging" 2>nul"') do set name=%%a
endlocal & set %~2=%name%
ping -n 1 -w 3000 -4 -l 8 "%~1" | Find "TTL=">nul
exit /b
Usage example:
#echo off
setlocal enabledelayedexpansion
for /l %%a in (1,1,255) do (
call:IsPingable2 10.6.1.%%a host && (
echo ping !host! - 10.6.1.%%a used )||( echo ping !host! - 10.6.1.%%a unused )
)
I just posted these because they just might come in handy for this type of thing in the future. You can use the :IsPingable now though.
You would use it like this in your code:
IF EXIST C:\test\final.csv (del C:\test\final.csv)
set ComputerList=C:\test\ClientList.txt
Echo Computer Name,IP Address,Logged In User>Final.csv
setlocal enabledelayedexpansion
echo please wait...
echo.
for /f "usebackq tokens=*" %%A in ("%ComputerList%") do (
for /f "tokens=3" %%B in ('ping -n 1 -l 1 %%A ^|find "TTL="') do (
if not errorlevel 1 (
set IPadd=%%B
call :GetLoggedInUser %%B uname
echo %%A,!IPadd:~0,-1!,!uname!>>final.csv
)
)
)
echo identified machines for Install
start excel C:\test\final.csv
echo opened csv file
goto :eof
:GetLoggedInUser comp user
for /f %%u in (
'wmic /NODE:"%1" Computersystem get username^|find "\"') do (
if not errorlevel 1 ( for /f "tokens=2 delims=\" %%a in (
'wmic /NODE:"%1" Computersystem get username^|find "\"' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
) ELSE (for /f "skip=1" %%a in (
'wmic /NODE:"%1" Computersystem get username' ) do (
For /f %%b in ("%%a") do (set %2=%%b))
))
Exit /b
The below code will count the number of lines in two files sequentially and is set to the variables SalaryCount and TaxCount.
#ECHO OFF
echo Process started, please wait...
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set SalaryCount=%%C
echo Salary,%SalaryCount%
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set TaxCount=%%C
echo Tax,%TaxCount%
Now if you need to output these values to a csv file, you could use the below code.
#ECHO OFF
cd "D:\CSVOutputPath\"
echo Process started, please wait...
echo FILENAME,FILECOUNT> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Salary.txt"') do set Count=%%C
echo Salary,%Count%>> SUMMARY.csv
for /f %%C in ('Find /V /C "" ^< "D:\Trial\Tax.txt"') do set Count=%%C
echo Tax,%Count%>> SUMMARY.csv
The > will overwrite the existing content of the file and the >> will append the new data to existing data. The CSV will be generated in D:\CSVOutputPath