Pinging to multiple servers via windows batch script - windows

I'm trying to check response from list of n-thousand IPs using ping command via windows batch script and save all results in a file (yes if response and no if don't). Is this even possible via batch script? When I'm using script printed below (pingingN.bat) I'm getting only first IP answer.
#ECHO OFF
SET ServerList="C:\MyPath\ip.txt"
SET LogFile="C:\MyPath\PingResults.txt"
IF EXISTS %LogFile% DEL %LogFile%
FOR %%a IN (%ServerList%) DO (
ping -n 1 %%a | find "TTL=" > NUL
IF %ERRORLEVEL% NEQ 0 (
echo no >> %LogFile%
) ELSE (
echo yes >> %LogFile%
)
)

Based on my comment and using the && and || conditionals, here's how I would do it:
#Echo Off
Set "ServerList=C:\MyPath\ip.txt"
Set "LogFile=C:\MyPath\PingResults.txt"
If Not Exist "%ServerList%" Exit /B
>"%LogFile%" (For /F UseBackQ %%A In ("%ServerList%"
) Do Ping -n 1 %%A|Find "TTL=">Nul&&(Echo Yes [%%A])||Echo No [%%A])
You'll note that I have also included the IP in the output, otherwise your log file will not show you which ones did or didn't pass/fail.

you can use delayed Expansion or if errorlevel (as commented by aschipfl) or use another approach:
(FOR %%a IN (%ServerList%) DO (
ping -n 1 %%a | find "TTL=" > NUL && (
echo %%a, yes
) || (
echo %%a, no
)
)>%LogFile%
where && means "if previous command (find) was successful then" and || "if previous command (find) failed then"
Just redirecting once the whole output instead of each line on it's own gives you a big speed boost.

Create a file (test.txt) and list down all the IPs you want to ping.
Create another bat.file and write this command.
(for /F %i in (test.txt) do ping -n 1 %i 1>nul && echo %i UP || echo %i DOWN ) 1>result.txt
Run this command, It will list down which IP is up and which one is down.

Related

Check if Ping fails to connect and write to log

I have written a batch script that connects to network drives and copies files using a list of IPs in a text document - the script is as below.
TITLE Upgrading Contactless Price Limit
ECHO starting >> UpgradeLog.log
#ECHO on
rem CLS
echo Collect IP Address List
SET ListIP=C:\PMC\30To45Upgrade\tills.txt
echo Sets the folder we will use
SET PMC=C:\PMC\30To45Upgrade\VX820_cont45_Config\
ECHO Begin Mapping and Copying
ECHO.
echo Starts a FOR loop using the selected IP list
FOR /F %%a IN (%ListIP%) DO (
echo This will attempt to log into the C$ share of the target PC.
net use \\%%a\c$ /u:username password >NUL >> UpgradeLog.log
ECHO.
ECHO Copying directory to: %%a... >> UpgradeLog.log
ECHO.
echo Uses the Robocopy command to send the folder to the specified Till
mkdir \\%%a\c$\retailjava\icc\VX820_cont45_Config
C:\robocopy.exe %PMC% \\%%a\c$\retailjava\icc\VX820_cont45_Config /e /r:0 /w:10 /v /z >> UpgradeLog.log
ECHO.
ECHO Disconnecting from %%a... >> UpgradeLog.log
ECHO.
echo Disconnected from the share.
net use \\%%a\c$ /DELETE>NUL >> UpgradeLog.log)
ECHO. >> UpgradeLog.log
pause
However if the IP is offline it takes a long time to fail and move on to the next - I think the best solution if to ping the IP address first and if it does not respond move on to next
So a block of code like this
FOR /F %%a IN (%ListIP%) DO (
ping %%a >> Failed.log
)
However this block would write if it connected or not and I just want the failed pings - so not sure how to do this.
Also if I enter this in my code like this - even if it fails it carries on to the robocopy so it needs some sort of if/else statement as far as I can tell but not sure how to implement this. Any help?
Attempted Fix
TITLE Upgrading Contactless Price Limit
ECHO starting >> UpgradeLog.log
#ECHO on
rem CLS
echo Collect IP Address List
SET ListIP=C:\PMC\30To45Upgrade\tills.txt
echo Sets the folder we will use
SET PMC=C:\PMC\30To45Upgrade\VX820_cont45_Config\
ECHO Begin Mapping and Copying
ECHO.
echo Starts a FOR loop using the selected IP list
FOR /F %%a IN (%ListIP%) DO (
ping %%a | find "TTL=" && (
echo This will attempt to log into the C$ share of the target PC.
net use \\%%a\c$ /u:username password >NUL >> UpgradeLog.log
ECHO.
ECHO Copying directory to: %%a... >> UpgradeLog.log
ECHO.
echo Uses the Robocopy command to send the folder to the specified Till
mkdir \\%%a\c$\retailjava\icc\VX820_cont45_Config
C:\robocopy.exe %PMC% \\%%a\c$\retailjava\icc\VX820_cont45_Config /e /r:2 /w:10 /v /z >> UpgradeLog.log
ECHO.
ECHO Disconnecting from %%a... >> UpgradeLog.log
ECHO.
echo Disconnected from the share.
net use \\%%a\c$ /DELETE>NUL >> UpgradeLog.log
) || (
echo %%a Failed to connect >> failed.log
)
)
ECHO. >> UpgradeLog.log
pause
FOR /F %%a IN (%ListIP%) DO (
ping %%a | find "TTL=" && (
echo %%a is reachable
rem insert your payload here
) || (
echo %%a is not available
)
)
where && acts as "if previous command (find) was successful then" and || acts as "if previous command (find) failed then" (acts as "else" here)

Need to run a command when I get a ping response

The idea is that a new device enters my network and a script running in the background can run a command to back it up, SyncToy for example (cd Program Files/SyncToy SyncToyCmd.exe -r).
I've run into scripts from similiar questions (How to check if ping responded or not in a batch file)
#setlocal enableextensions enabledelayedexpansion
#echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=down
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
)
if not !state!==!oldstate! (
echo.Link is !state!
set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal
However I can't figure out how to run the command when the state changes to "up" as an exception in the loop, I also only want to run it once, adding a condition of once every 12 hours maybe.
Is this as simple as placing the command inside the block that tests for receipt? I do not understand how SyncToy would know the IP address.
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
if "x%%a"=="xReceived" if "x%%b"=="x1," (
set state=up
PUSHD "%ProgramFiles%/SyncToy"
SyncToyCmd.exe -r
POPD
)
)

Windows Batch Check Hostname Exists

I want to check if a hostname exists on my PC (ie found in hosts file under C:\Windows\System32\drivers\etc).
Is there a way to find if it exist using a batch command or some other way?
Give a try for this batch file with some extra info :
#echo off
set "SearchString=localhost"
set "LogFile=%userprofile%\Desktop\LogFile.txt"
set "hostspath=%windir%\System32\drivers\etc\hosts"
(
Echo **************************** General info ****************************
Echo Running under: %username% on profile: %userprofile%
Echo Computer name: %computername%
Echo Operating System:
wmic os get caption | findstr /v /r /c:"^$" /c:"^Caption"
Echo Boot Mode:
wmic COMPUTERSYSTEM GET BootupState | find "boot"
Echo Antivirus software installed:
wmic /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName | findstr /v /r /c:"^$" /c:"displayName"
Echo Executed on: %date% # %time%
Echo ********************* Hosts' File Contents with the string "%SearchString%" ************************
)>"%LogFile%"
for /f "delims=" %%a in ('Type "%hostspath%" ^| find /I "%SearchString%"') Do (
echo %%a >> "%LogFile%"
)
Start "" "%LogFile%"
Easier and more robust solution
url.bat:
#echo off
set url=%1
ping -n 1 %url% > nul 2> nul
if "%errorlevel%"=="0" (
echo %url% exists
) else (
echo %url% does not exist
)
Test
> url.bat google.com
google.com exists
> url.bat google.commmmmm
google.commmmmm does not exist
What you possibly can do is pinging the hostname you are looking for and then check for certain strings, that will show you if the hostname could be found or not. Would look like this (I guess):
#echo off
setlocal EnableDelayedExpansion
set /p input= "Hostname"
set hostexists=yes
For /f "tokens=1,2" %%a in ('ping -n 1 !input!') do (
if "x%%a"=="xFOO" if "x%%b"=="xBAR" set hostexists=no
)
If "x!hostexists!"=="xno" (
echo. "Does not exist"
) ELSE (
echo. "Does exist"
Pause
Basic thought is that when you try to ping a hostname that is not available, you will get a specific output from the commandline. Try it yourself: Open the cmd.exe (Hit the Windows-Button +R and type cmd) and in the commandline write ping foobar and wait a bit. You should get a message like: Ping-Request could not find "foobar" [...]. You take the first two words and put them into the code: 1st word to FOO and 2nd to BAR.
The program will look into the output of the ping command and place the first two words (=tokens) in %%a and %%b checking if they are equal to the desired words, marking the host does not exist.
I hope this will help :) Not sure if that is what you wanted :D
Greetings
geisterfurz007

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.

Replacing an Awk statment with Findstr

I am trying to figure out how to utilize findstr so that it will do the same thing as this line in awk:
wk.exe "begin {temp=0}/^stringMarker/{temp=1}{if (temp==1)print$0}" %TEMP%\input.txt >%TEMP%\output.txt
This is all I can think of right now:
#ECHO OFF
findstr /b /c:"Hello" Hello.bat > nul
if errorlevel 1 (
echo Search Failed
) else (
echo Search Sucessful
)
as you can see the latter half of the code is missing. I need help to find out how to get the lines after the stringMarker and then be able to redirect them into a file.
Cheers
I would suggest using a windows port of gawk if possible. If you can't for some reason, maybe a vbscript would work best?
If you must use findstr and cmd, the following should work.
find_thing.cmd "^stringMarket" in.txt > out.txt
find_thing.cmd
#echo off
if "%~1"=="" ((echo no arguments) && exit /b)
if "%~2"=="" ((echo insufficient arguments) && exit /b)
set query=%~1
set file_name=%~2
for /f "tokens=1,2* delims=:" %%a in ('findstr /r /n "%query%" "%file_name%"') do (
echo %%b
more +%%a "%file_name%"
exit /b
)

Resources