Adding names to an IP address without failing the batch file - windows

I want to use a batch file to ping a set of servers. The batch file works and reports ok or failed. All I want is to have it display a name of the server in the check.
This is what I use in the batch file:
#echo off
for /f "delims=" %%a in (C:\List of IPs.txt) do ping -n 1 %%a >nul && (echo %%a ok) || (echo %%a failed to respond)
pause
In the text file it points to is just a list of IPs, how do I make it so I can see a name next to the IP?
Thank you in advance!

just insert another for /f loop to get the name:
#echo off
SetLocal
for /f "usebackq" %%a in ("List of IPs.txt") do (
for /f %%b in ('"ping -n 1 %%a >nul && (echo ok) || (echo failed to respond) "') do (
for /f "tokens=1*" %%m in ('nslookup %%a ^|findstr /b "Name:"') do (
echo %%a %%n %%b
)
)
)

One option is to format your file to have the IP and the name you are interested in.
192.168.1.200 server1
192.168.1.201 server2
192.168.1.202 printer1
192.168.1.203 that one stupid printer in the back
Then you can read both from the file.
One thing I'll note -- your method of checking pings is not consistent. You can get an errorlevel 0 even if the ping actually fails (from a valid response of "unreachable"). Instead (in English) a successful ping always includes "ttl=". Thus you would do this:
untested
#echo off
for /f "usebackq tokens=1* delims= " %%a in ("C:\List of IPs.txt") do ping -n 1 %%a ^|find /i "ttl=" >nul && (echo %%b at %%a is ok) || (echo %%b at %%a failed to respond)
pause
nslookup and/or ping -a can be leveraged if you have dns working with everything you're trying to access.
Based on comment, I've added the following solution that works on my English Windows 10 computer with the text file above:
#echo off
for /f "usebackq tokens=1* delims= " %%a in ("C:\temp\List of IPs.txt") do ping -n 1 -w 1500 %%a |find /i "ttl=" >nul &&echo %%b at %%a is ok||echo %%b at %%a failed to respond
pause
Note there is a space between the equal sign and the double quote at delims= "
Output:
server1 at 192.168.1.200 is ok
server2 at 192.168.1.201 is ok
printer1 at 192.168.1.202 is ok
that one stupid printer in the back at 192.168.1.203 failed to respond
Press any key to continue . . .

Related

Windows batch: combining start and FOR /f "tokens=1" with | escape coded symbols

I am trying to execute this command from standard windows batch file.
start /B for /f "tokens=1" %%a in ('Query SESSION ^| find /i "rdp"') do (echo yes |reset session %%a)
and it throws an error:
"| was unexpected at this time."
I just found that it fails because start in the beginning.
What's wrong with it?
From a batch file it's a bad idea to try to build a valid one line solution with start, it's very tricky to escape/quote a complex expression.
But it's quiet easy to use start and jump to a label in the same batch file.
#echo off
REM *** Thread redirector
for /F "tokens=3 delims=:" %%F in ("%~0") do goto %%F
REM *** Start a new thread in this batch file at the label :myThread
start "" /b cmd /c "%~d0\:myThread:\..\%~pnx0"
echo Main
for /L %%n in (1 1 10) DO (
echo MainThread doing some stuff %%n
ping localhost -n 2 > nul
)
exit /b
:myThread
for /f "tokens=1" %%a in ('Query SESSION ^| find /i "rdp"') do (
echo myThread: Resetting session %%a
echo yes | reset session %%a
)
exit /b

Windows Batch - How to get the external IP into a batch-file variable

I am making a program that checks if a user's IP is a certain IP address.
Currently, I created a successful internal IP version:
#echo off
set userIp=192.168.90.100
for /f "tokens=4 delims= " %%i in ('route print ^| find " 0.0.0.0"') do set localIp=%%i
for /f "delims=[] tokens=2" %%a in ('ping %computername% -4 -n 1 ^| findstr "["') do set thisip=%%a
goto :Check
:Check
if %localIp%==%userIp% goto :Good
if %thisip%==%userIp% goto :Good
goto :Bad
And I am trying to make the same thing that works with external IPs.
I researched online, and here is what I got so far.
#echo off
for /f "tokens=2 delims=:" %%a IN ('nslookup myip.opendns.com. resolver1.opendns.com ^| findstr /IC:"Address"') do if /i %%a=="10.11.12.13" goto :Good
goto :Bad
I need a bit of help on how to fix this.
With pure batch/already present tools:
EDIT: changed the batch to properly handle also IPv6 addresses
#Echo off
for /f "tokens=1* delims=: " %%A in (
'nslookup myip.opendns.com. resolver1.opendns.com 2^>NUL^|find "Address:"'
) Do set ExtIP=%%B
Echo External IP is : %ExtIP%
Reference
Another one with powershell:
#Echo off
For /f %%A in (
'powershell -command "(Invoke-Webrequest "http://api.ipify.org").content"'
) Do Set ExtIP=%%A
Echo External IP is : %ExtIP%
And another slightly different powershell variant:
#Echo off
For /f %%A in (
'powershell -nop -c "(Invoke-RestMethod http://ipinfo.io/json).IP"'
) Do Set ExtIP=%%A
Echo External IP is : %ExtIP%
To get your public IP without additional parsing do this:
curl "http://api.ipify.org"
EDIT:
This version is more reliable across windows language versions:
for /f "tokens=3 delims== " %%A in ('
nslookup -debug myip.opendns.com. resolver1.opendns.com 2^>NUL^|findstr /C:"internet address"
') do set "ext_ip=%%A"
First it seems there is a . too much after the first .com.
Second when using your command with simply google.com and echo %a I get the following:
" xx.xx.xx.x" without the quotes and with two leading spaces!
So your if will never be true!
Change it to something like this: if "%%a"==" xx.xx.xx.x" Goto:good and you should be fine.

How do I ping the default gateway without specifying the IP address?

I'm trying to write a batch file that tests network connectivity by pinging the default gateway of the given network.
However, as I want this to be an automated process which then logs the results to a text file, I'd like to be able to ping the gateway on various networks, without having to change/enter the ip address.
Is there a generic term or command to ping the default gateway for the network you're currently connected to?
(I already have the commands for output options etc.)
So far, I have this....
#echo off
goto :NETWORK1
:NETWORK1
ipconfig
echo .
Set /P gateway=PLEASE ENTER GATEWAY IP ADDRESS (shown above):
if /I "%gateway%" EQU "exit" goto :EXIT
if /I not "%gateway%" EQU "exit" goto :NETWORK2
:NETWORK2
echo CLOSING THIS WINDOW WILL ABORT THE CONNECTIVITY TEST.
echo . >> "C:\Network Test Results %date:/=.%.txt"
echo Time: >> "C:\Network Test Results %date:/=.%.txt"
time /t >> "C:\Network Test Results %date:/=.%.txt"
ping %gateway% -n 20 >> "C:\Network Test Results %date:/=.%.txt"
goto :NETWORK2
:EXIT
exit
But I don't want to have to specify the IP address, so that I can take away the need for user input.
smalll fix for Wernfried Domscheit
for /f "tokens=2 delims=:" %%g in ('netsh interface ip show address ^| findstr /c:"Default Gateway"') do ping %%g
pause
just adding /c: before "Default Gateway"
On a command line you can try this one:
for /f "tokens=2 delims=:" %g in ('netsh interface ip show address ^| findstr "Default Gateway"') do ping %g
Note, inside a batch-file you must double the %, i.e.
for /f "tokens=2 delims=:" %%g in ('netsh interface ip show address ^| findstr "Default Gateway"') do ping %%g
According to jimbobomcgee on serverfault who phrased the correct answer for the question How to Extract command-line output into a Variable?
for /f "usebackq tokens=1,2,3 delims=:" %A in (`ipconfig ^| Find "Default Gateway" ^| Findstr/N "." ^| Findstr/B "1:"`) do #if not defined MYVAR set MYVAR=%~C
#echo off
setlocal enableextensions disabledelayedexpansion
set "gateway="
for /f "tokens=1-5" %%a in ('route -4 print 0.*') do #if "%%e"=="" if "%%a"=="%%b" set "gateway=%%c"
if not defined gateway goto :eof
echo CLOSING THIS WINDOW WILL ABORT THE CONNECTIVITY TEST.
:loop
echo %date% %time%
>> "Network Test Results %date:/=.%.txt" (
echo(
echo(Time: %time%
ping -n 20 -4 %gateway%
)
goto :loop
Gateway determination from route information copied from here
edited for a more tolerant parse of the route command use
for /f "tokens=3" %%a in ('route -4 print 0.* ^| find "0."') do set "gateway=%%a"
After help from #MC ND, I have created the following code, which does exactly what I needed....
pings the default gateway with the results being output to a text file
shows a message telling the user not to close the command window
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=3" %%a in ('route -4 print 0.*') do set "gateway=%%a"
:NETWORK
echo CLOSING THIS WINDOW WILL ABORT THE CONNECTIVITY TEST.
echo Time >> "C:\Network Test Results %date:/=.%.txt"
time /t >> "C:\Network Test Results %date:/=.%.txt"
echo . >> "C:\Network Test Results %date:/=.%.txt"
ping %gateway% -n 20 >> "C:\Network Test Results %date:/=.%.txt"
goto :NETWORK

How to get a windows ip address, via code

I need the ppp IP address stored into a variable.
The only way I have found is 'ipconfig > text.txt' into a tmp file and then script a search for the ppp interface. This is very dirty.
Is there an better alternative in windows?
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('ipconfig ^| find /i "IPv4 Address"') do (set VarIP=!%%a%!)
Echo Your PPP IP : %VarIP%
#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
You can also extract using ping:
#echo off
FOR /F "tokens=2,3" %%A IN ('ping %computername% -n 1 -4') DO IF "from"== "%%A" set "IP=%%~B"
echo %IP:~0,-1%

Batch ping a list of computer names and write the results to file

The code below will write the computer name and ip address to file, but I would like it to also write the name of the computers it cannot ping with a fail next to it. I have no idea how I would modify the batch file to do this.
#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
You could use errorlevel set by findstr to substitute return string(s) if 'Reply' is not found:
('ping -n 1 -l 1 %%A ^|findstr Reply ^|^| echo Not found Failed:')
where || (escaped here because of for context with ^) means execute only if previous command failed.
As a side note, you should be aware that ping messages are system language dependent (they are translated to language of OS) so 'Reply' as success indicator works only for English versions.
This may not be directly what you are looking for, but I had a similar task: run ping and report success or failure. I'll leave extracting the IP address to you - seeing as you have already done it.
The problem with ping is that it returns success upon name resolution, whether packets get lost or host is unreachable (will report 0% Loss) is irrelevant.
FOR %%a IN (
google.com
a.b.c.d
) DO #FOR /F "delims=" %%p IN (
'PING -w 100 -n 1 %%a ^| findstr ^"Reply Request fail name^"'
) DO #(
ECHO "%%p" | FINDSTR TTL >2 && echo %%a, success, %%p || echo %%a, failed, %%p
) >> Results.csv
Logic: Ping once, filter only lines with the one of the words listed. If TTL exists in resulting line (output to STDERR or NUL to avoid output pollution) echo success, else echo failed.
I'm on English Windows, words will have to be adjusted for other languages.
EDIT:
FOR %%a IN (
google.com
a.b.c.d
) DO #FOR /F "delims=" %%p IN ('PING -n 1 %%a ^| findstr TTL ^|^| echo Failed') DO #(
ECHO "%%p" | FINDSTR TTL >2 && (for /f "tokens=3" %%b IN ("%%p") do #echo %%a, %%b) || echo %%a, failed, %%p
)
Less dependant on language, works only for IPv4, added IP extraction.
Filter ping output for TTL, set output to "Failed" if TTL not found.
If output string contains TTL, extract IP and echo host and IP, else echo host name and output string.

Resources