batch file that pulls variables from a txt file

SLPowers
SLPowers used Ask the Experts™
on
I have a list of a few hundred computers.
I have a command I would like to run on each one.  
I have tried psexec but it just will not work and takes hours to give me a output file of errors.
Forgive me I know BAT files a little but not VB.
I would much prefer a bat file if someone has one or can point me in the correct location.
The command is
REG QUERY \\remotepcname\HKLM\SOFTWARE\something\FolderRedirect /v installed >>reginfo.txt
This will tell me the value of a key I need to check on for each pc in the list.
I would like to run this command for every pc listed in a text file I will call pclist.txt.
In the above example the pc name is \\remotepcname.
The text file would be a plain list of pc names in a column
 
Pc1
Pc2
Pc3
Pc4
And so on.
 
Thanks in advance.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Top Expert 2009
Commented:
You can do it like this but it will show a couple of lines from the reg query.
for /f %%a in (computerlist.txt) do REG QUERY \\%%a\HKLM\SOFTWARE\something\FolderRedirect /v installed >>reginfo.txt

Open in new window

Top Expert 2009
Commented:
I would normally do something like this to get PCs into list that the registry value or not. Also I would normally do a ping to test if the computer is online.

Opps. You mentioned your list of computers is pclist.txt


for /f %%a in (pclist.txt) do (
    ping -n 1 %%a | find /i "reply from"
    if errorlevel 1 (
        ECHO %%a>>NotOnline.txt
    ) else (
        REG QUERY \\%%a\HKLM\SOFTWARE\something\FolderRedirect /v installed | find "installed"
        if errorlevel 1 (
            echo %%a>>reginfo(Notinstalled).txt
        ) else (
            echo %%a>>reginfo(Installed).txt
        )
    ) 
)

Open in new window

SLPowersEngineer

Author

Commented:
I could not get the vbs solution to work.  Gave a error code line 1 char 5 but I relay like the bat solution.  I will except it as the solution thanks.  If I could do a follow up as I am trying to add something to it. . For the below line how can I tell the error code.  So if it does ping a pc it will do one thing and if it does not it will do another.

Thanks


for /f %%a in (computerlist.txt) do ping %%a
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

Hi SLPowers

In AmazingTech's absence I will try to clear up the mystery of the FOR statement.

The /f switch just tells it to work with, I suppose the easiest explanation is "files".

The %a is the variable that is replaced.  Straight from a command window you can use %a but in a batch file you must double up the % symbols to %%a.  You don't have to use "a".  You can use any letter of the alphabet, and they are case-sensitive, so if you start off with %%a then you cannot use %%A later in the statement.

The bit in the (brackets" is the "set".  Depending on what you are doing this could be a file name, a set of files like this *.txt (meaning all files with the txt extension), a literal "string" if enclosed in double quotes, or even the output from another command if enclosed in single quotes like this (even though such usage would be overkill when the DIR command could be used alone):

for /f %%a in ('dir *.txt') do @echo %%

In the example you stated:

for /f %%a in (computerlist.txt) do ping %%a

All that would happen is that "computerlist.txt" would be walked through on a line by line basis, with the variable %%a holding whatever was found on each line.  In your case this is the names of computers.  By reusing whatever is held in that variable as the parameter for the PING command, the FOR statement would just ping each line found in the text file sequentially.

If you look again at AmazingTech's code in comment ID 24884484 just above your last comment, you will see that he isn't displaying the results of pinging each computer listed in the text file.  He is sending (piping with the | symbol) the results of each PING to the FIND command and telling it to check for the text string "reply from".  You don't see the results of each ping command.  The FIND command is therefore testing to see which of the computer names in the text file are actually online, but testing requires something else namely the IF command.

The "Errorlevel" is what is then used to determine what to do if the computer is online or offline.  The FIND command has 3 Error Return Codes (this is from memory):
0 = Success
1 = File found but string not found
2 = File not found, or other error.

AmazingTech's batch file splits the test into two parts using this idea:

if true
   then do this
if not true (same as "else")
   then do that

In context with his code, these IF and tests are in brackets which include the whole thing as part of the FOR statement, and there are a few IF and Else tests involved.

First of all he establishes which computers are offline, ie. the FIND command doesn't find the success reply in the results of the PING command.  For each PING command there will always be some text to search, and therefore Error Code 2 shouldn't be encountered.  His batch file looks for the return code of 1 to signify that the computer listed on the current line of the computer list file is offline and outputs this to a text file then ignores that line (and therefore computername).

The 2nd part of the test (the ELSE part) is for those computers that are found online and when the response string is found in the PING reply.  In other words, this ELSE section will be applicable for Error Code returns other than a 1, ie. a Zero for success.

For each instance of a success as the list file of computer names is read through, a REG QUERY command is run on the named computer that would list the value "installed".  The results are not displayed to screen, but are piped into the FIND command looking for the text string "installed".

Dependent on whether this string is found (errorlevel = 0) or not found (errorlevel = 1), then the batch file just echoes a line to a text file that clearly states whether that string was found or not found.

Of course, those "echo" commands could be changed to other commands, as could be the REG QUERY command.  The batch file does, however, give you a good idea how to test things using the error returns, and hopefully I have explained how it does so.

Going back to your example:

for /f %%a in (computerlist.txt) do ping %%a

you would have to test for something specific.  Testing the actual results of the PING command alone wouldn't do you much good, because unless PING.EXE was not found, the results (I expect) will always be a success code of Zero.

It was for that reason that AmazingTech's batch file searched the results of the PING command for an indication of success or failure in REACHING the target computer.  If you do a PING command to a completely bogus IP address, domain, or computer name, then you should be able to see the key parts of the response that can be searched for, eg.

"Ping request could not find host anywhere. Please check the name and try again."

Pinging an IP address, domain, or computer name that is a good one, but happens to be unreachable at the time may yield another result message.

Pinging and getting through to the target will always have the words "Reply from" in the responses.  Test it using %localhost% IP Address 127.0.0.1

@echo off

ping -n 127.0.0.0 | find /i "reply from"

if "%errorlevel%"=="0" start /b /wait notepad.exe
if "%errorlevel%"=="1" start /b /wait calc.exe

exit

The Windows Notepad should always open.
Change the IP address to something like 128.0.0.0 and the target should not be found.  The text string "reply from" should therefore not be found, and the Windows Calculator should open instead.
A minor correction when I explained AmazingTech's batch file where I said:
"Dependent on whether this string is found (errorlevel = 0) or not found (errorlevel = 1), then the batch file just echoes a line to a text file that clearly states whether that string was found or not found."

What it actually does is send the names of the computers (ie. the contents of %%a in each pass) found to be online and offline to separate and logically named text files that clearly infer the status at that time.
I assume that you modified AmazingTech's code given in his first comment to contain your own text file of computer names?

ie. change computerlist.txt in:

for /f %%a in (computerlist.txt) do REG QUERY \\%%a\HKLM\SOFTWARE\something\FolderRedirect /v installed >>reginfo.txt

to pclist.txt like this:

for /f %%a in (pclist.txt) do REG QUERY \\%%a\HKLM\SOFTWARE\something\FolderRedirect /v installed >>reginfo.txt

AND that you also replaced the "\something\" registry key with a real one.
SLPowersEngineer

Author

Commented:
First  excellent amazingtech thanks for the code and i had to give some points to billdl as that really was extremely nice of him to break it down for me like that.  Thanks so much for all your help.  It is very appreciated.
Thank you SLPowers.  You're very welcome.  I have always managed to place myself again in the position of looking at such things and scratching my head,  puzzled at what the code actually did.  I hope AmazingTech approves of my explanation of his batch file and that it has saved him from some typing ;-)
Top Expert 2009

Commented:
Thank you BillDL for providing the explaination.

Just one note:

I typically will always use if errorlevel 1 (error or not found) and if not errorlevel 1 (no errors found).

It is difficult to sometime exactly know what the variable %errorlevel% is set to.

Some programs will set the errorlevel variable to different specific values like 5 for access denied. But using if errorlevel 1 will be set when there is any error. Never use if errorlevel 0 this never changes (or atleast I've never found how it changes.

An example of what I mean :

@echo off

pingin -n 127.0.0.0

if "%errorlevel%"=="0" start /b /wait notepad.exe
if "%errorlevel%"=="1" start /b /wait calc.exe
echo %errorlevel%

Since pingin is not a valid command neither notepad.exe or calc.exe will start. Since %errorlevel% is set to 9009.

This will log success and errors:

@echo off

pingin -n 127.0.0.0

if not errorlevel 1 echo No error occurred>>Status.log
if errorlevel 1 echo Error #%errorlevel% occured>>Status.log
echo %errorlevel%
Hi SLPowers.

You raised some very good points there AmazingTech.

Yes, an errorlevel NOT EQUAL TO Zero is usually assumed to be a failure, and it's always best to use:
             IF NOT ERRORLEVEL 0
UNLESS you are testing for one or more known return codes for a very specific reason, for example:
The 5 return codes for XCOPY (http://commandwindows.com/xcopy.htm), third-party programs that have return codes right up to 255, etc, etc.
This is a good discussion, particularly the advice about testing from the highest number first:
http://www.robvanderwoude.com/errorlevel.php 

Actually, I need to correct errors in my small example batch file anyway.  I referred to LocalHost just above it as 127.0.0.1 and then for some reason used 127.0.0.0 in the batch file.  The correct IP Address of LocalHost is 127.0.0.1.

I also used PING with the -n switch (number of echo requests to send), but somehow ended up missing out the number.  The correct usage of PING with the -n switch in my example should have been (3 times):

         ping -n 3 127.0.0.1 | find /i "reply from" > nul

Duh!!  That's what happens when things are typed off the top of my head without testing.

I have added the redirection to NUL ( > nul) to the command above to send the 3 replies into a void rather than output them to screen.  AmazingTech introduced the method for redirecting activities to a log file above.  The following two pages are very useful and show you how to pick and choose what you want to redirect to file, eg. only errors:
http://www.robvanderwoude.com/battech_redirection.php
http://www.robvanderwoude.com/redirection.php

Used in context only with the FIND command, and referring to my previous example, here is another method of using the ErrorLevel variable in a test.  Just swap the leading REM around between the top lines to test it.  REM remarks out the line it precedes so it is ignored.

I'm only providing this as an example where results can be reasonably anticipated and may serve a useful purpose, it's really just an example of how you can add variables to make up a text string, BUT you should note what AmazingTech has highlighted above about sticking to IF NOT ERRORLEVEL 0, because it is important and useful to know.  Maybe the concept will be useful to you in some other context.

Regards
Bill

@echo off
 
ping -n 2 127.0.0.1 | find /i "Reply from" > nul
REM ping -n 2 127.0.0.1 | find /i "Some Bogus Text String" > nul
 
goto ReturnCode_%ERRORLEVEL%
 
:ReturnCode_0
echo.
echo The FIND command returned Code 0 meaning "Reply From" WAS found
echo Therefore the PING command reached the specified host. 
echo.
pause
goto END
 
:ReturnCode_1
echo.
echo The FIND command returned Code 1 meaning "Reply From" NOT found
echo Therefore the PING command DID NOT reach the specified host.
echo.
pause
goto END
 
:END
EXIT

Open in new window

Whoops, did it again.  I meant to emphasise AmazingTech's advice about NOT using Errorlevel Zero and emphasised the opposite.
SLPowersEngineer

Author

Commented:
Wow thanks guys.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial