1

The script in its current form

@echo on

setlocal EnableDelayedExpansion

set /p ipAddress="enter ip address: "

rem right now the loop is set to (1,1,50) for the sake of testing

for /l %%i in (1,1,50) do (
ping -n 1 %ipAddress%.%%i | find "TTL" > nul

if !errorlevel! == 0 (
deploy_mir.bat %ipAddress%.%%i

)
)

endlocal

and then the result of running it on a known to be online host (10.167.194.22) is

C:\DOCUME~1\socuser2\MIR>test.bat

C:\DOCUME~1\socuser2\MIR>setlocal EnableDelayedExpansion

C:\DOCUME~1\socuser2\MIR>set /p ipAddress="enter ip address: "
enter ip address: 10.167.194

C:\DOCUME~1\socuser2\MIR>for /L %i in (22 1 50) do (
ping -n 1 10.167.194.%i   | find "TTL"  1>nul
if !errorlevel! == 0 (deploy_mir.bat 10.167.194.%i )
)

C:\DOCUME~1\socuser2\MIR>(
ping -n 1 10.167.194.22   | find "TTL"  1>nul
if !errorlevel! == 0 (deploy_mir.bat 10.167.194.22 )
)
"Mir Agent deployment to: 10.167.194.22"

Now that last line there means that !errorlevel! == 0 (ie, "TTL" was indeed found) so up to this point it looks like the script is working. However on the next loop, 10.167.194.23 (alive) got skipped as well as .30 and .46 . I decided to add

echo %errorlevel% 

at the end of the loop to see whats going on here. Apparently, after every ping %errorlevel% was 0 so clearly

ping -n %ipAddress%.%%i | find "TTL" >nul

is where my issue is. According to this statement, "TTL" is being found after every ping, which is false, between 10.167.194.22-.50 only 3 machines are alive.

by the way, when i do

!errorlevel! == 0

what does that mean?

Everything below this line is as of 4/26/12

So my new script looks like this 

@echo on


set /p ipAddress="enter ip address: "


set i=
for /l %%i in (1,1,255) do (
ping -n 1 %ipAddress%.%%i> test.txt
find "TTL" test.txt
if %errorlevel% == 0 (
deploy_this.bat %ipaddress%.%%i
)

i first tried the script without the if errorlevel check, and it worked fine. It started pinging the ip address that i provided and proceeded to .2 .3 .4 .5 and so on.

once i added this however...

if %errorlevel% == 0 (
deploy_this.bat %ipaddress%.%%i
)

this is what happens

C:\DOCUME~1\socuser2\MIR>test.bat
C:\DOCUME~1\socuser2\MIR>set /p ipAddress="enter ip address: "
enter ip address: 10.167.201
C:\DOCUME~1\socuser2\MIR>set i=
C:\DOCUME~1\socuser2\MIR>

and the script just stops dead. any ideas?

user1336749
  • 15
  • 1
  • 8
  • You forgot to add `call` before `deploy_mir.bat`. The first loop calls `deploy_mir.bat` and never comes back. – ixe013 Apr 27 '12 at 14:09
  • that is something i tried before but took out, now it seems to be what i need. ill try it – user1336749 Apr 27 '12 at 15:28
  • Awesome man, adding "call" as you said (which has been suggested before, /facepalm) did exactly what you said it would do. – user1336749 Apr 27 '12 at 15:39
  • Now the apparent problem is the fact that whenever the loop arrives at an online host and runs deploy_this.bat, psexec (which is used in deploy_this.bat) gets its /? contents spilled into the cmd prompt. – user1336749 Apr 27 '12 at 16:19
  • If this problem is solved, I suggest you accept the answer and ask a new question. See you there ;) – ixe013 Apr 27 '12 at 16:56

3 Answers3

2

There are a few issues :

  • A batch file will never return unless you use the call statement
  • You are missing a parenthesis
  • Inside a FOR loop, you must enabledelayedexpansion and use !ERRROLEVEL!

I suggest you look at this code, it has a few improvements :

  • It use setlocal to keep its variable to itself
  • It does not produce a temp file
  • Can take the ip address from the command line or prompt for it
  • It is indented
  • It is less verbose in its output

Here it is :

@echo off

setlocal EnableDelayedExpansion

set ipAddress=%1

if "%ipAddress%"=="" SET /P ipAddress="enter ip address: "

for /l %%i in (1,1,2) do (

    rem Remove the > nul at the end if you want to 
    rem see the ping results in the output
    ping -n 1 %ipAddress%.%%i | find "TTL" > nul

    if !ERRORLEVEL! == 0 (
       call deploy_this.bat %ipAddress%.%%i
    )
)

endlocal
ixe013
  • 9,559
  • 3
  • 46
  • 77
  • You are also missing a parenthesis. Try the new code, it [works on my machine](http://www.codinghorror.com/blog/2007/03/the-works-on-my-machine-certification-program.html). – ixe013 Apr 26 '12 at 13:25
  • C:\DOCUME~1\socuser2\MIR>( ping -n 1 10.167.194.5 | find "TTL" 1>nul if 1 == 0 (call deploy_mir.bat 10.167.194.5 ) ) this is the output thats showing up now. Seems to be working, but what is the '1' after 'find "TTL"' ? – user1336749 Apr 26 '12 at 13:46
  • Its as if the logic check always returns a '1', thus the 'deploy_this.bat' never gets called. – user1336749 Apr 26 '12 at 14:21
  • Forgot `EnableDelayedExpansion` in my setlocal, +replace the % with ! in the loop. – ixe013 Apr 26 '12 at 15:57
  • Sorry it does not work for you. You'll have to take it from here. Show us the work you did to fix the problem. Update your question with the details, like a stand alone ping result, and maybe change the title to "Run a batch file for every alive machine in a /24 network" or something that will get others interested in answering. – ixe013 Apr 26 '12 at 18:28
  • @user1336749: If you were asking about `1` in `1>nul`, it is the number of the stream redirected with `>nul`. `1>nul` is an equivalent of the short-hand `>nul` (stream 1, `stdout`, is implied). The command shell always outputs `>nul` like `1>nul` when `ECHO` is `ON` while running the script. On a different note, you could use an alternative method of testing `ERRORLEVEL` with `&&`/`||` instead of using `IF`. Have a look at [this answer](http://stackoverflow.com/questions/6812484/batch-file-test-error-level/6817833#6817833). – Andriy M Apr 27 '12 at 05:09
0

Perhaps I would rewrite your loop like this:

FOR /L %%i IN (1,1,50) DO (
  ping -n 1 %ipAddress%.%%i | find "TTL" >NUL && (
    CALL deploy_mir.bat %ipAddress%.%%i
  )
)
Andriy M
  • 76,112
  • 17
  • 94
  • 154
  • but wouldnt this just deploy_mir.bat on all hosts? – user1336749 Apr 27 '12 at 17:52
  • No. The `CALL` statement is executed only if `find` finds rows. This is an equivalent of `IF !ERRORLEVEL! == 0`, only you don't need to worry about expansion (because you just do not reference `ERRORLEVEL` directly). – Andriy M Apr 27 '12 at 17:55
  • alright, what the heck is expansion??? i asked someone earlier and they said 'just read set /?'...well i tried that and it had a small paragraph on expansion and i still dont know what it means. – user1336749 Apr 27 '12 at 18:59
  • @user1336749: Here's how I understand it. Expansion is replacing the name of a(n environmental) variable with its value, like replacing `%ipAddress%` with what the user typed in. Another term for that is *evaluation*. There are basically two kinds of expansion: `%`-expansion (I often call it *immediate expansion*, not sure if that is the correct term for it) and *delayed expansion* (or `!`-expansion, if you like). The difference between the two is in their availability (usually you first need to issue `SET EnableDelayedExpansion` to, well, enable delayed expansion) and in their timing. ... – Andriy M Apr 27 '12 at 19:43
  • @user1336749: One example where the difference between the two manifests particularly prominently is bracketed blocks (like e.g. loop bodies). Every `%var%`-like expression in the loop body is expanded (evaluated) *before the loop starts*. Every `!var!`-like expression, on the other hand, is evaluated immediately before the very command that contains it, executes. I think, to get a better grip of it, you may just need to practice a bit. – Andriy M Apr 27 '12 at 19:46
0

Language-independent ping reply analysis would be like below:

  ping -n 1 %ipAddress%.%%i
  if errorlevel 1 goto :dead
Nime Cloud
  • 6,162
  • 14
  • 43
  • 75