views:

129

answers:

1

I am writing a batch file (I asked a question on SU) to iterate over terminal servers searching for a specific user. So, I got the basic start of what I'm trying to do.

  1. Enter a user name
  2. Iterate terminal servers
  3. Display servers where user is found (they can be found on multiple servers now and again depending on how the connection is lost)
  4. Display a menu of options

Iterating terminal servers I have:

for /f "tokens=1" %%Q in ('query termserver') do (set __TermServers.%%Q)

Now, I am getting the error...

Environment variable __TermServers.SERVER1 not defined

...for each of the terminal servers. This is really the only thing in my batch file at this point. Any idea on why this error is occurring? Obviously, the variable is not defined, but I understood the SET command to do just that.

I'm also thinking that in order to continue working on the iteration (each terminal server), I will need to do something like:

:Search    
for /f "tokens=1" %%Q in ('query termserver') do (call Process) 
goto Break

:Process
for /f "tokens=1" %%U in ('query user %%username%% /server:%%Q') do (set __UserConnection = %%C)
goto Search

However, there are 2 things that bug me about this:

  1. Is the %%Q value still alive when calling Process?
  2. When I goto Search, will the for-loop be starting over?

I'm doing this with the tools I have at my disposal, so as much as I'd like to hear about PowerShell and other ways to do this, it would be futile. I have notepad and that's it.

Note: I would continue this line of questions on SuperUser, except that it seems to be getting more into programming specifics.

+1  A: 

Ok, those are quite a few questions/issues/etc. in one :-)

And I still don't quite get where exactly you're headed with that script.

First of all, the syntax for the set command is

set <variable name>=<value>

If you do just

set <variable name>

then it will list all environment variables starting with <variable name>. If there are none, then it will output the error message you're seeing.

If you want to define a variable without actually caring about its value, you still need to provide a value. I usually use 1 for such flags, since it's then more an on/off switch than an actual variable holding a value:

set Foo=1

In your case you probably want something else, though. There are no arrays per se in batch files, you can mimic them by creating a number of variables and holding a count somewhere. I've written about that once before (a little outdated by now, but still valid).

In your case you want to iterate over a number of servers and for each server over a number of users. You can do that with a nested loop:

for /f "tokens=1" %%Q in ('query termserver') do (
   for /f "tokens=1" %%U in ('query user ... /server:%%Q' do (
      ...
   )
)

As for your two questions there:

  1. No, the loop variable is only valid inside the loop, not when calling a subroutine. You can pass it to the subroutine, however:

    for ... in (...) do call Process %%Q
    

    You can then access it with %1 in the subroutine. Honestly, though, in most cases I think the nested loops are easier to read.

  2. Yes.

Another error (one that will bite you): As mentioned before, the set syntax is

set variable=value

Note that there is no space around the = sign. If there is, then you have a space at the end of the variable name or at the start of the value:

> set foo = bar
> echo %foo%
%foo%
> echo %foo %
 bar
Joey
+1 and check: Excellent descriptions and explanations. If I could up-vote multiple times, I would. I have yet to find a superior resource on the Internet that gives good information and full examples. Once again, excellent!!!
dboarman