Batch file help with FOR /F

Intent:
I want to pull the entries from a text file called 'test.txt' and run commands on them one by one via a batch file.

The text file is very simple.
Contents are computer names:

cha-smbdrm1-l
cha-blloyd-d
cha-mailroom-d
...

The reason I'm doing this is I have a list of computer names in our domain in a txt file,  and I want to push a file to these systems that will disable a particular prompt for updates.
There are a thousand ways to do this, but I chose the Batch file because I'm a bit old school.

The logic runs like this:
Pull a computer name from the TXT file.
Map a drive to that machine.
Copy a file from my machine (or a network location haven't decided yet) to a particular folder on the target.
Remove the mapped drive.
Pull the next computer name from the TXT file...
And so on and so forth.

Here's my batch file:

 
setlocal 
FOR /F %%a in (c:\test.txt) do call :SUB %%a

:SUB

if exist z: (net use z: /delete)
net use z: \\%%a\c$ /user:domain\username Password
copy c:\mms.cfg z:\WINDOWS\system32\Macromed\Flash
if exist z: (net use z: /delete)
  if errorlevel 1 (goto :EOF)
  else (ping -n 2 127.0.0.1 > nul 
  goto :SUB)

:EOF

Open in new window


I'm sure I have the exit strategy wrong with where I have the :EOF being called, but I'm more concerned with the fact that the FOR /F doesn't seem to work.

My results from running this script are mixed.

 Screen cap of running that batch file
1. You can see that the FOR /F command seems to be picking up the correct %%a variables, as it shows it marching through the test.txt file, and taking cha-smbdrm1-l and then cha-smbdrm2-l.

2. However in 2 you can see the variable in the sub routine, which I have specified as %%a is not being correctly filled in.


WHAT I'VE ALREADY TRIED.

1. In the sub routine I've already tried putting in %1 as the variable.  This makes the script work, but it keeps repeating only the first entry in the test.txt file.  The %%a keeps changing, but the variable entered keeps being the first entry.

2. setlocal EnableDelayedExpansion - tried that and put in a set var1=%%a under the FOR command, and referenced it in the sub routine with !var1!.  Same result as if I put in %1 as the variable.
DKingArxxAsked:
Who is Participating?
 
Bill PrewConnect With a Mentor Commented:
When you call a subroutine (or another bat file) via the CALL command, the arguments you pass are accessed via %1, %2, %3, ... etc.  So in your case you want to change:

net use z: \\%%a\c$ /user:domain\username Password

to

net use z: \\%1\c$ /user:domain\username Password

FOR loop variables like %%a are only available inside the FOR loop, and technically the called routine is no longer in that context, so you can't reference the %%a.

The logic in the :SUB itself looks like it could use a little work too, but I'll start by answering your initial question.

~bp

~bp
0
 
knightEknightCommented:
Rather than mounting a drive each time, consider using a UNC instead:

   copy  c:\mms.cfg  \\%%a\c$\WINDOWS\system32\Macromed\Flash

Run the entire batch file as the same user you were using to map the Z: drives.
0
 
Neil RussellTechnical Development LeadCommented:
You know you could do this with a group policy preference in a few minutes.
Old school is an excuse i used to use until i needed to look for a new job and discovered I was OLD SCHOOL!!!

We used to walk infront of cars waving a red flag ;) But times move on ;)
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
DKingArxxAuthor Commented:
@BillPrew

You know? I could SWEAR I tried putting %1 in as the variable.  I think I even mention it in my original post.

But this time I tried it and it worked!

Thank you, Bill!

And yes, I know the rest of my :SUB needs some work. :D
Just wanted to put a little pause in there between mapping attempts.

@knightEknight

Not a bad idea, to run the script with the permissions already in place.  Not what I was asking, but thanks for looking.
0
 
DKingArxxAuthor Commented:
@NeilSr

My Boss has the Group Policy editing locked down pretty tight.  I could get in using the Domain Admin password I have but don't feel like explaining myself 30 times and writing an impact report and then having it discussed in committee for 2 weeks before getting grudging permission to go ahead.

Especially when I can just DO IT!

<hits enter>

Like dat!
0
 
DKingArxxAuthor Commented:
VERY quick reply and the answer was just what I was looking for.
0
 
Bill PrewCommented:
Great, glad that helped. Thanks.

~bp
0
 
DKingArxxAuthor Commented:
OKAY.

Problem still.  Maybe closed this too quickly.

Just tried it again with my full file and the behaviour I described before is happening.

It keeps looping with the 1st entry in my TXT file.

Screenshot attached:

 Script repeating first entry of text file
Code is:

 
setlocal 
FOR /F %%a in (c:\test.txt) do call :SUB %%a

:SUB

if exist z: (net use z: /delete)
net use z: \\%1\c$ /user:domain\user Password
copy c:\mms.cfg z:\WINDOWS\system32\Macromed\Flash
if exist z: (net use z: /delete)
goto :SUB

:EOF

Open in new window


Slight edits to remove some of the :SUB entries...of course that just makes my script loop endlessly because it never goes to :EOF.
Aware of that, just wondering why it isn't moving on to the next entry in the TXT file.
0
 
Bill PrewCommented:
You are stuck in the goto :SUB loop, so never leaving the subroutine.

That should likely either be

goto :EOF

or

exit /b

either of which will exit the subroutine.

~bp
0
 
DKingArxxAuthor Commented:
Ah, so when I cleaned that ping crap out of my original code I also removed the goto :EOF.
Let me try that.
0
 
DKingArxxAuthor Commented:
Yep. That was it.

Code changed to this and it worked:

 
setlocal 
FOR /F %%a in (c:\computers.txt) do call :SUB %%a

:SUB

if exist z: (net use z: /delete)
net use z: \\%1\c$ /user:domain\username Password
copy c:\mms.cfg z:\WINDOWS\system32\Macromed\Flash
if exist z: (net use z: /delete)
  if errorlevel=1 (goto :EOF)
  ) else (
    ping -n 2 127.0.0.1 > nul
    exit /b
  )

:EOF

Open in new window


Silly loops.

Thank you again, Bill!
0
 
Bill PrewCommented:
Very welcome.

~bp
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.