Search code examples
windowsbatch-filefor-loopcmdpsexec

Why does FOR /F pick up a space as a valid line when getting data from a file and how do I prevent this?


So I have been working on this batch script for a while now, it's the first one I've ever written. The idea is to connect to remote machines in our domain and gather some information.

I'm using a .txt file with the IP addresses of machines in it, one per line and each separated with a comma like so.

192.168.1.1,

192.168.1.2,

192.168.1.3

For some reason, once the script reaches the last IP address in the file, it queries a blank space. Is this blank space a trailing space character? and how do I prevent this from happening?

The way I've currently got the script setup means that when a computer is unreachable, it echoes a message to the log file. So every time I run the script it will be adding an extra line saying " (BLANK SPACE) Machine was Unreachable" I know it's only a minor thing but it's bugging me.

Here is my Code

@echo off
title Audit Script

for /F %%i in (C:\testlist.txt) DO call :test %%i

:test

ping %1 > out.txt
find "Reply" out.txt > nul
if %ERRORLEVEL%==0 GOTO sysinf
if %ERRORLEVEL%==1 GOTO pingerror

:pingerror
echo %1 Unreachable
echo. >> C:\Computer-Audit.log
echo ########################################################## >> C:\Computer-Audit.log
echo MACHINE %1 was unreachable on the %date% at %time% >> C:\Computer-Audit.log
echo ########################################################## >> C:\Computer-Audit.log
echo. >> C:\Computer-Audit.log
GOTO :eof

:sysinf
psexec \\%1 -u Administrator -p g2m60gy -accepteula -nobanner -low -n 10     systeminfo | findstr "Host OS" >> C:\Computer-Audit.log

if %ErrorLevel% EQU 0 GOTO reg
if errorlevel 1 GOTO test

:reg
FOR /F "tokens=2*" %%A IN (
'psexec \\%1 -u Administrator -p g2m60gy -accepteula -nobanner -low -n 10  reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Betting   Till_is1" /v DisplayVersion 2^> nul'
) DO SET DisplayName=%%B
echo Betting Till Version:     %DisplayName% >> C:\Computer-Audit.log

Here is what I have tried to prevent the FOR /F from querying a blank space.

for /F "tokens=* delims=," %%i in (C:\testlist.txt) DO call :test %%i

This doesn't throw any error messages but it still queries a blank space.

for /F %%i in (C:\testlist.txt ^| findstr /C:" "  /v /r "^$" ) DO call :test %%i

This throws the error message "The system cannot find the file |." and also still queries the blank space.

Also, any tips on how to improve my code would be much appreciated.


Solution

  • You don't have a problem with a space.

    In batch files, when you use a subroutine, you declare a label as the start point, but there is nothing that prevent batch file execution from reaching the code after the label.

    Once your for command has ended processing the file, bat execution continues and the code after the label is executed, but this time %1 is empty (well, or not, now %1 makes reference to the first argument of the batch file), so ping is executed without arguments, shows its help and as it does not contain the Reply string (I can not test, I have a spanish locale), it is handled as a non reachable machine.

    Place a goto :eof before the :test label to avoid execution to enter this code unless called.

    @echo off
    title Audit Script
    
    for /F %%i in (C:\testlist.txt) DO call :test %%i
    
    goto :eof    <- This jumps to the end of the file
    
    :test
    ....
    ....