Batch script to ping range of IPs

Hello fellas,

I'm trying to write a script to scan a range of IPs 192.168.1.1-255 and as output,would like a csv file, something like this,

column A        column B          Column C     Column D
IPADDRESS        PCNAME           STATUS       LASTUSER
192.168.1.1       workstation1      online       NTID
192.168.1.2       doesnotexist       offline       DOESNOTEXIST      

Column D is not really a must, but be it would be if it was there, I know this would require the following commands for /a , ping  /find "" , psloggedon, I just don't know how to put it all together

I leave a sample in the attach for better perspective of the project

Any thoughts?
example.csv
LVL 3
ivan rosaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

deroodeSystems AdministratorCommented:
To get you started i have put together  a simple script to do the FOR part and the ping;

set prefix=192.168.1.

REM write header 
echo IPADDRESS,PCNAME,STATUS,LASTUSER > result.csv

for /L %%A IN (1,1,254) do call :subping %%A

exit /b

rem Subping subroutine
:subping

ping %prefix%%1 -n 1| find /i "reply"

IF errorlevel 1 (
  echo %prefix%%1,offline >> result.csv
) ELSE (

  echo %prefix%%1,online >> result.csv
)

exit /b

Open in new window


If the errorlevel is 1 the string "reply" is not found, and the pc is probably offline (or the firewall is configured not to respond to ping)

I have not yet added the name resolution; Are your pc's in DNS?
Name resolution can be done either by NSlookup on an IP address to get a name, or via nbtstat -A. Which one works best in your environment?
oBdACommented:
This should do the trick. You can  either pass it a file with IP addresses to scan, and/or define one or more ranges to scan in the script itself.
If the ReportFile variable is defined, it will create a csv file, otherwise it will just report to the console.
It will scan in several processes to finish faster; you can change the QueueSize variable to your CPU's needs if required.
psloggedon.exe must be in the same folder as the script.
@echo off
setlocal enabledelayedexpansion
set ReportFile=C:\Temp\report.csv
REM Format of IP range definition: </24 subnet> <first index> <last index>
set IPRange[1]=192.168.1 1 254
set QueueSize=20

set RegKeyResult=HKCU\Software\Acme\MassPing
set ScriptFolder=%~dp0
set ScriptFullName=%~f0
if /i "%~1"=="/ping" goto StartPing
if "%~1"=="" (
	set HostFile=%Temp%\%~n0.txt
	echo Creating host file '!HostFile!' ...
	(for /f "tokens=2-4 delims== " %%a in ('set IPRange[') do (
		for /l %%i in (%%b, 1, %%c) do (
			echo %%a.%%i
		)
	)) >"!HostFile!"
) else (
	if not exist "%~1" (
		echo Host name file not found: '%~1'
		exit /b 1
	)
	set HostFile=%~1
)
for /f %%a in ('find.exe /c /v "" ^<"%HostFile%"') do (set HostsTotal=%%a)
echo [%Time%] Pinging %HostsTotal% hosts ...
set /a HostCount = 0
reg.exe delete "%RegKeyResult%" /f >NUL 2>&1
reg.exe add "%RegKeyResult%" /f >NUL
for /f %%a in ('type "%HostFile%"') do (call :Queue "%%a")
:ResultLoop
for /f %%a in ('reg.exe query "%RegKeyResult%" ^| find.exe /c /i "Running"') do (set QueueCount=%%a)
if %QueueCount% gtr 0 (
	ping.exe -n 2 localhost >NUL
	goto ResultLoop
)
echo [%Time%] Done; collecting results ...
if defined ReportFile (>"%ReportFile%" echo "IP","Host","Status")
for /f "tokens=1,3,4,5 delims=:; " %%a in ('reg.exe query "%RegKeyResult%" ^| findstr.exe ":OK: :OFFLINE:" ^| sort.exe') do (
	echo %%a	%%c	%%b	%%d
	if defined ReportFile (>>"%ReportFile%" echo "%%a","%%c","%%b","%%d")
)
if defined ReportFile (echo Report written to '%ReportFile%')
REM reg.exe delete "%RegKeyResult%" /f >NUL 2>&1
goto :eof

:Queue [Host]
set Host=%~1
set /a HostCount += 1
echo [%HostCount%/%HostsTotal%] Queuing %Host% ...
:QueueLoop
for /f %%a in ('reg.exe query "%RegKeyResult%" ^| find.exe /c /i "Running"') do (set QueueCount=%%a)
if %QueueCount% lss %QueueSize% (
	reg.exe add "%RegKeyResult%" /v "%Host%" /t REG_SZ /d "Running" /f >NUL
	start "MassPing %Host%" /min cmd.exe /c "%ScriptFullName%" /ping %Host%
	goto :eof
)
ping.exe -n 2 localhost >NUL
goto QueueLoop

:StartPing
set Host=%~2
ping.exe -4 -n 2 %~2 | find.exe /i "TTL" >NUL
if errorlevel 1 (
	set Result=:OFFLINE:;^<DOES_NOT_EXIST^>;^<DOES_NOT_EXIST^>
) else (
	set HostName=^<NOT_RESOLVED^>
	for /f "tokens=2" %%a in ('ping.exe -4 -n 1 -a %~2 ^| find.exe "Pinging"') do set HostName=%%a
	set LoggedOn=^<NOT_FOUND^>
	for /f "skip=1" %%a in ('"%ScriptFolder%psloggedon.exe" -accepteula -x -l \\%~2 2^>NUL') do set LoggedOn=%%a
	set Result=:OK:;!HostName!;!LoggedOn!
)
reg.exe add "%RegKeyResult%" /v "%Host%" /d "%Result%" /f >NUL
goto :eof

Open in new window

ivan rosaAuthor Commented:
First off, Thanks for your help to both,

Deroode,
Yes sir, the PCs are in a domain, can you could do it with a nslookup?
SolarWinds® IP Control Bundle (IPCB)

Combines SolarWinds IP Address Manager and User Device Tracker to help detect IP conflicts, quickly identify affected systems, and help your team take near instantaneous action. Help improve visibility and enhance reliability with SolarWinds IP Control Bundle.

deroodeSystems AdministratorCommented:
Yes, you could add a nslookup to the subroutine:

The EnableDelayedExpansion prevents environment variables getting assigned a value only once at the start of the script (see http://ss64.com/nt/delayedexpansion.html)

Setlocal EnableDelayedExpansion

set prefix=192.168.1.

REM write header 
echo IPADDRESS,PCNAME,STATUS,LASTUSER > result.csv

for /L %%A IN (1,1,254) do call :subping %%A

exit /b

rem Subping subroutine
:subping

ping %prefix%%1 -n 1| find /i "reply"

IF errorlevel 1 (
  set status=offline
) ELSE (

  set status=online
)

set pcname=UNKNOWN

for /F "tokens=2" %%P in ('nslookup %prefix%%1 ^| find /i "name"') do set pcname=%%P


echo %prefix%%1,%pcname%,%status% >> result.csv

exit /b

Open in new window

ivan rosaAuthor Commented:
both scripts are very well detailed and organized, although

derode,
I tried the script however it for all IPs the result was the same "online" regardless if the pc existed or not..., can you also make it in a way that I can actually set a computerlist.txt instead of a range perhaps it will eliminate trouble for you?

oBdA,
your script it's pretty awesome too, however can you do it without touching the registry? t is this reg gets created into every machine it pings?
oBdACommented:
The registry access is only required on the machine where the script is running; it's used to monitor the queue.
I only forgot to uncomment the removal of the key after the work is done; just remove the "REM" at the beginning of line 46, and the key will be removed once the script is done.
deroodeSystems AdministratorCommented:
I just realized that in my script i search for "reply" in the result of the ping command. It is possible for a router to respond to ping: "Reply from <router ip>: Destination host unreachable". So instead my script now searches for "TTL"
Setlocal EnableDelayedExpansion

set prefix=192.168.1.

REM write header 
echo IPADDRESS,PCNAME,STATUS,LASTUSER > result.csv

for /L %%A IN (1,1,254) do call :subping %%A

exit /b

rem Subping subroutine
:subping

ping %prefix%%1 -n 1| find /i "TTL"

IF errorlevel 1 (
  set status=offline
) ELSE (

  set status=online
)

set pcname=UNKNOWN

for /F "tokens=2" %%P in ('nslookup %prefix%%1 ^| find /i "name"') do set pcname=%%P


echo %prefix%%1,%pcname%,%status% >> result.csv

exit /b

                                          

Open in new window

If on the other hand you want to get computernames (or better, IP addresses) from a text file make the following modification: Instead of "for /L %%A IN (1,1,254)" i do "for /F %%A IN (computername.txt)" and modified the rest of the script accordingly:

Setlocal EnableDelayedExpansion

REM write header 
echo IPADDRESS,PCNAME,STATUS,LASTUSER > result.csv

for /F %%A IN (computername.txt) do call :subping %%A

exit /b

rem Subping subroutine
:subping

ping %1 -n 1| find /i "TTL"

IF errorlevel 1 (
  set status=offline
) ELSE (

  set status=online
)

set pcname=UNKNOWN

for /F "tokens=2" %%P in ('nslookup %1 ^| find /i "name"') do set pcname=%%P


echo %1,%pcname%,%status% >> result.csv

exit /b

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ivan rosaAuthor Commented:
Deroode/oBdA
They are patient, fast response and he really know what he is talking about, I much appreciate their valuable help

These scripts led me to come up with something very awesome!
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Batch

From novice to tech pro — start learning today.