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 trying to store my local ip into a system variable but I am struggling with that batch file. I am already able to parse my IP and extract the right substring. However declaring the variable and passing it to SETX seems to be harder than I thought....
Any help would be very much appreciated. :)
#echo off
setlocal enabledelayedexpansion
::just a sample adapter here:
set "adapter=Ethernet-Adapter VirtualBox Host-Only Network"
set adapterfound=false
echo Network Connection Test
for /f "usebackq tokens=1-2 delims=:" %%f in (`ipconfig /all`) do (
set "item=%%f"
if /i "!item!"=="!adapter!" (
set adapterfound=true
) else if not "!item!"=="!item:IPv4-Address=!" if "!adapterfound!"=="true" (
echo %%g | cut -d"(" -f 1 | tr -d "[:space:]" <-- this echos my ip correctly
set ipadress=%%g | cut -d"(" -f 1 | tr -d "[:space:]"
echo %ipadress% <-- this echos empty string
setx MY_IP %ipadress% <-- this doesnt work as well
set adapterfound=false
)
)
Improved script (might be locale-dependent):
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
::just a sample adapter here:
set "adapter=Ethernet-Adapter VirtualBox Host-Only Network"
set "adapterfound=false"
echo Network Connection Test
for /f "usebackq tokens=1-2 delims=:" %%f in (`ipconfig /all`) do (
set "item=%%f"
if not "!item!"=="!item:%adapter%=!" (
set "adapterfound=true"
echo %adapter%
) else if not "!item!"=="!item:IPv4 Address=!" if "!adapterfound!"=="true" (
rem ↑↑↑↑↑↑↑↑↑↑↑↑ might be locale-dependent
for /F "delims=( " %%G in ("%%g") do set "ipadress=%%G"
echo !ipadress!
rem setx MY_IP !ipadress!
set "adapterfound=false"
)
)
echo %ipadress%
Another approach:
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
:: just a sample adapter here:
set "adapter=Ethernet-Adapter VirtualBox Host-Only Network"
echo Network Connection Test
:: get adapter index
set "_where=where "NetConnectionID = '%adapter%'""
for /F "tokens=1,* delims==" %%G in ('
wmic path Win32_NetworkAdapter %_where% get InterfaceIndex /value ^| findstr "="
') do for /F %%g in ("%%H") do set "_ii=%%~g"
:: get adapter's IP addresses
set "_where=where "InterfaceIndex = '%_ii%'""
for /F "tokens=1,* delims==" %%G in ('
wmic path Win32_NetworkAdapterConfiguration %_where% get IPAddress /value ^| findstr "="
') do for /F "tokens=1,2 delims={,}" %%g in ("%%H") do (
set "_IPv4=%%~g"
set "_IPv6=%%~h"
)
set _ip
Here the for loops are
%%G to retrieve the desired value;
%%g to remove the ending carriage return in the value returned: wmic behaviour: each output line ends with 0x0D0D0A (<CR><CR><LF>) instead of common 0x0D0A (<CR><LF>).
See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem
What I am trying to do, is speed up my reading results of batch file.
Am trying to get different values using netsh commands and then present them in my script console but it takes to long.
See below a small part of my script to get the idea. (this is just a small part, I'm actually getting around 50 different values and using more netsh commands)
Does anybody know a way to speed up the process?
.
.
.
netsh interface ipv4 show config %AdapterLAN% >temp
for /f "tokens=3" %%i in ('findstr "IP Address" temp') do set ip=%%i
echo. IP Address : %ip%
for /f "tokens=5 delims=) " %%i in ('findstr "Subnet Prefix" temp') do set mask=%%i
echo. Mask : %mask%
for /f "tokens=3" %%i in ('findstr "Gateway:" temp') do set gateway=%%i
echo. Gateway : %gateway%
for /f "tokens=1,5,6" %%a in ('findstr "DNS" temp') do set dns1=%%a&set dns5=%%b&set dns6=%%c
If "%dns1%"=="Statically" set dns=%dns5%
if "%dns1%"=="DNS" set dns=%dns6%
echo. DNS Server : %dns%
for /f "tokens=3" %%i in ('findstr "Gateway Metric" temp') do set GMetric=%%i
for /f "tokens=2" %%i in ('findstr "InterfaceMetric" temp') do set IMetric=%%i
set /a metricLAN=Gmetric + imetric
echo. Metric : %metricLAN%
for /f "tokens=3" %%i in ('find "DHCP enabled" temp') do set LANDHCP=%%i
If "%dns1%"=="Statically" set xx=Static
if "%dns1%"=="DNS" set xx=DHCP
If /i %LANDHCP%==No set LANDHCP=Static
if /i %LANDHCP%==YES set LANDHCP=DHCP
echo. Obtained IP : %LANDHCP%
echo. Obtained DNS : %xx%
for /f "tokens=3 delims=," %%a in ('getmac /v /fo csv ^| find """%AdapterLAN-without-Q%""" ') do set macLAN=%%a
echo. MAC-Addres : %macLAN%
del temp
.
.
.
netsh wlan show profile >temp
.
Do a similar process of getting values from another netsh command sent them
in the temp file …echo the one I want on the screen ..delete the file etc.
Next approach could be a bit faster (no temporary file(s), updated no multiple findstr):
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
set "AdapterLAN=wiredEthernet"
set "IMetric="
set "GMetric="
for /F "tokens=1,2* delims=:" %%G in ('
netsh interface ipv4 show config "%AdapterLAN%"^|findstr /N /R "^"
') do (
rem echo G="%%G" H="%%H" I="%%I"
if "%%I"=="" (
rem line 1 skip
rem line 2 = Configuration for interface
rem line 10 = DNS server #2 etc.
) else (
set "hh=%%H"
set "xx=!hh:IP Address=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "ip=%%i"
set "xx=!hh:Subnet Prefix=!"
if not "!hh!"=="!xx!" for /F "tokens=3 delims=) " %%i in ("%%I") do set "mask=%%i"
set "xx=!hh:Default Gateway=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "gateway=%%i"
set "xx=!hh:Gateway Metric=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "GMetric=%%i"
set "xx=!hh:InterfaceMetric=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "IMetric=%%i"
)
)
echo( IP Address : [%ip%]
echo( Mask : [%mask%]
echo( Gateway : [%gateway%]
set /a metricLAN=Gmetric + IMetric
echo( Metric : [%metricLAN%]
ENDLOCAL
goto :eof
Output:
==>D:\bat\SO\31356115.bat
IP Address : [192.168.1.100]
Mask : [255.255.255.0]
Gateway : [192.168.1.1]
Metric : [20]
==>
Edit
Here is another approach: unlike netsh, parsing the wmic command output seems to be a bit easier when used get verb together with /value switch as it's well defined and well structured. You could find here all the info as from netsh: next code snippet should read and make public a huge range of information about all enabled NIC adapter(s) in a defined local or remote computer:
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
set "NetCount=0"
set "compName=%computername%" :: local or remote computer name
set "compIDXs="
for /F "tokens=2 delims==" %%N in ('
wmic /node:"%compName%" NIC where "NetEnabled=TRUE" get InterfaceIndex /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%n in ("%%N") do (
for /F "tokens=*" %%G in ('
wmic /node:"%compName%" NIC where "InterfaceIndex=%%n" get /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%g in ("%%G") do set "_%%n%%g"
for /F "tokens=*" %%I in ('
wmic /node:"%compName%" NICCONFIG where "InterfaceIndex=%%n" get /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%i in ("%%I") do set "_%%n_%%i"
set /A "NetCount+=1"
set "compIDXs=!compIDXs! "%%n""
)
set _
rem sample of it:
echo compName=%compName% NetCount=%NetCount% compIDXs=%compIDXs%
for %%x in (%compIDXs%) do (
echo enabled InterfaceIndex=%%~x NetConnectionID=!_%%~xNetConnectionID!
for /F "tokens=1,2 delims={}," %%i in ("!_%%~x_IPAddress!") do echo ipv4=%%~i ipv6=%%~j
)
Read Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem to see why any wmic command output is parsed via a couple of nested for loops.
I am very new to batch programming, I am trying to write a batch file that is a fake virus. I need to obtain the IP address from the previous command IPCONFIG into the variable VarIP. Can you help me?
My code:
echo off
echo Trying to hack your computer
ipconfig
echo Now hacking your IP
ping -t VarIP
echo on
pause
It's pretty simple to extract part of the output from any console command by using find to eliminate the lines in the output that you do not want, then using the for command to extract a portion of the line found by find:
#echo off
setlocal ENABLEDELAYEDEXPANSION
for /f "tokens=2 delims=:" %%i in ('ipconfig ^| find /i "IPv4 Address"') do (set VarIP=%%i&set VarIP=!VarIP: =!)
ping -t !VarIP!
endlocal
Hopefully you are just creating a practical joke on a friend and aren't up to anything more nefarious.
Another Version without "Tokens" for NT :
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('ipconfig ^| find /i "IPv4 Address"') do (set VarIP=!%%a%!)
ping -t %VarIP%
This is a useful method to get IP info:
#echo off
for /f "tokens=2,3 delims={,}" %%a in ('"WMIC NICConfig where IPEnabled="True" get IPAddress /value | find "I" "') do echo IPv4 %%~a IPV6 %%~b
pause
So I have to use batch only for this. Basically, the server HOSTNAMES are all listed in a txt file. I used the following code to ping all the servers and display their results in a txtfile.
For /f %%i in (testservers.txt) do ping -n 1 %%i >>pingtest.txt
The above pinged all the servers. Now, I want to output the IP addresses and the HOST Names in a separate file. How can I do this?
I know that I can run a for loop searching for words like "TTL" and then look for the 3rd token (for the IP) and words like "PINGING" for the second token(HOSTNAME). But I am having errors and cant display it properly. The reason why I want to output IPs and Hostnames in a different file is to make a list of the DOWN and UP servers.
Help will be appreciated. :)
EDIT: Just so it isn't confusing, wanted to let you guys know there are 3 different files, testservers.txt has the HOSTNAMES in it, pingtest.txt has ping results, and result.txt will have the IPs along with Hostnames with their current status as DOWN or UP.
Well, it's unfortunate that you didn't post your own code too, so that it could be corrected.
Anyway, here's my own solution to this:
#echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=result.txt
>nul copy nul %OUTPUT_FILE%
for /f %%i in (testservers.txt) do (
set SERVER_ADDRESS=ADDRESS N/A
for /f "tokens=1,2,3" %%x in ('ping -n 1 %%i ^&^& echo SERVER_IS_UP') do (
if %%x==Pinging set SERVER_ADDRESS=%%y
if %%x==Reply set SERVER_ADDRESS=%%z
if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
)
echo %%i [!SERVER_ADDRESS::=!] is !SERVER_STATE! >>%OUTPUT_FILE%
)
The outer loop iterates through the hosts and the inner loop parses the ping output. The first two if statements handle the two possible cases of IP address resolution:
The host name is the host IP address.
The host IP address can be resolved from its name.
If the host IP address cannot be resolved, the address is set to "ADDRESS N/A".
Hope this helps.
Parsing pingtest.txt for each HOST name and result with batch is difficult because the name and result are on different lines.
It is much easier to test the result (the returned error code) of each PING command directly instead of redirecting to a file. It is also more efficient to enclose the entire construct in parens and redirect the final output just once.
>result.txt (
for /f %%i in (testservers.txt) do ping -n 1 %%i >nul && echo %%i UP||echo %%i DOWN
)
I worked on the code given earlier by Eitan-T and reworked to output to CSV file. Found the results in earlier code weren't always giving correct values as well so i've improved it.
testservers.txt
SOMESERVER
DUDSERVER
results.csv
HOSTNAME LONGNAME IPADDRESS STATE
SOMESERVER SOMESERVER.DOMAIN.SUF 10.1.1.1 UP
DUDSERVER UNRESOLVED UNRESOLVED DOWN
pingtest.bat
#echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=result.csv
>nul copy nul %OUTPUT_FILE%
echo HOSTNAME,LONGNAME,IPADDRESS,STATE >%OUTPUT_FILE%
for /f %%i in (testservers.txt) do (
set SERVER_ADDRESS_I=UNRESOLVED
set SERVER_ADDRESS_L=UNRESOLVED
for /f "tokens=1,2,3" %%x in ('ping -n 1 %%i ^&^& echo SERVER_IS_UP') do (
if %%x==Pinging set SERVER_ADDRESS_L=%%y
if %%x==Pinging set SERVER_ADDRESS_I=%%z
if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
)
echo %%i [!SERVER_ADDRESS_L::=!] !SERVER_ADDRESS_I::=! is !SERVER_STATE!
echo %%i,!SERVER_ADDRESS_L::=!,!SERVER_ADDRESS_I::=!,!SERVER_STATE! >>%OUTPUT_FILE%
)
the problem with ping is if the host is not alive often your local machine will return an answer that the pinged host is not available, thus the errorcode of ping will be 0 and your code will run in error because not recognizing the down state.
better do it this way
ping -n 4 %1 | findstr TTL
if %errorlevel%==0 (goto :eof) else (goto :error)
this way you look for a typical string ttl which is always in the well done ping result and check error on this findstr instead of irritating ping
overall this looks like this:
#echo off
SetLocal
set log=path/to/logfile.txt
set check=path/to/checkfile.txt
:start
echo. some echo date >>%log%
:check
for /f %%r in (%check%) do (call :ping %%r)
goto :eof
:ping
ping -n 4 %1 | findstr TTL
if %errorlevel%==0 (goto :eof) else (goto :error)
:error
echo. some errormessage to >>%log%
echo. some blat to mail?
:eof
echo. some good message to >>%log%
Try this
$servers = Get-Content test.txt
$reg=""
foreach ($server in $servers)
{
$reg=$reg+$server+"`t"+([System.Net.Dns]::GetHostAddresses($server) | foreach {echo $_.IPAddressToString})+"`n"
}
$reg >reg.csv
#echo off
set workdir={your working dir. for example - C:\work }
set iplist=%workdir%\IP-list.txt
setlocal enabledelayedexpansion
set OUTPUT_FILE=%workdir%\result.csv
>nul copy nul %OUTPUT_FILE%
echo HOSTNAME,LONGNAME,IPADDRESS,STATE >%OUTPUT_FILE%
for /f %%i in (%iplist%) do (
set SERVER_ADDRESS_I=UNRESOLVED
set SERVER_ADDRESS_L=UNRESOLVED
for /f "tokens=1,2,3" %%x in ('ping -a -n 1 %%i ^&^& echo SERVER_IS_UP') do (
if %%x==Pinging set SERVER_ADDRESS_L=%%y
if %%x==Pinging set SERVER_ADDRESS_I=%%z
if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
)
echo %%i [!SERVER_ADDRESS_L::=!] !SERVER_ADDRESS_I::=! is !SERVER_STATE!
echo %%i,!SERVER_ADDRESS_L::=!,!SERVER_ADDRESS_I::=!,!SERVER_STATE! >>%OUTPUT_FILE%
)
This worked great I just add the -a option to ping to resolve the
hostname. Thanks https://stackoverflow.com/users/4447323/wombat
#echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=result.csv
>nul copy nul %OUTPUT_FILE%
echo HOSTNAME,LONGNAME,IPADDRESS,STATE >%OUTPUT_FILE%
for /f %%i in (testservers.txt) do (
set SERVER_ADDRESS_I=UNRESOLVED
set SERVER_ADDRESS_L=UNRESOLVED
for /f "tokens=1,2,3" %%x in ('ping -n 1 -a %%i ^&^& echo SERVER_IS_UP') do (
if %%x==Pinging set SERVER_ADDRESS_L=%%y
if %%x==Pinging set SERVER_ADDRESS_I=%%z
if %%x==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
)
echo %%i [!SERVER_ADDRESS_L::=!] !SERVER_ADDRESS_I::=! is !SERVER_STATE!
echo %%i,!SERVER_ADDRESS_L::=!,!SERVER_ADDRESS_I::=!,!SERVER_STATE! >>%OUTPUT_FILE%
)
This works for spanish operation system.
Script accepts two parameters:
a file with the list of IP or domains
output file
script.bat listofurls.txt output.txt
#echo off
setlocal enabledelayedexpansion
set OUTPUT_FILE=%2
>nul copy nul %OUTPUT_FILE%
for /f %%i in (%1) do (
set SERVER_ADDRESS=No se pudo resolver el host
for /f "tokens=1,2,3,4,5" %%v in ('ping -a -n 1 %%i ^&^& echo SERVER_IS_UP')
do (
if %%v==Haciendo set SERVER_ADDRESS=%%z
if %%v==Respuesta set SERVER_ADDRESS=%%x
if %%v==SERVER_IS_UP (set SERVER_STATE=UP) else (set SERVER_STATE=DOWN)
)
echo %%i [!SERVER_ADDRESS::=!] is !SERVER_STATE! >>%OUTPUT_FILE%
echo %%i [!SERVER_ADDRESS::=!] is !SERVER_STATE!
)