2010-04-27 2 views
0

Я пишу командный файл (I asked a question on SU), чтобы перебирать серверы терминалов в поисках конкретного пользователя. Итак, я получил базовое начало того, что я пытаюсь сделать.Итерационные массивы в командном файле

  1. Введите имя пользователя
  2. Iterate терминальные серверы
  3. Отображение серверов, где найдено пользователей (они могут быть найдены на нескольких серверах и теперь снова в зависимости от того, как теряется связь)
  4. Показать меню опций

перебор терминальных сервера у меня есть:

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

Сейчас я получаю сообщение об ошибке ...

Environment variable __TermServers.SERVER1 not defined 

... для каждого из серверов терминалов. На самом деле это единственное в моем командном файле. Любая идея о том, почему эта ошибка происходит? Очевидно, переменная не определена, но я понял, что команда SET делает именно это.

Я также думаю, что для того, чтобы продолжить работу на итерации (каждый терминальный сервер), мне нужно будет сделать что-то вроде:

: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 

Однако, есть 2 вещи, которые ошибка мне об этом :

  1. Действительно ли значение %% Q сохраняется при вызове процесса?
  2. Когда я нахожу поиск, начнется ли цикл for-loop?

Я делаю это с помощью инструментов, которые у меня есть, так как я хотел бы услышать о PowerShell и других способах этого сделать, это было бы бесполезно. У меня есть блокнот и все.

Примечание: Я бы продолжил эту строку вопросов на SuperUser, за исключением того, что, похоже, это больше связано с программированием.

ответ

3

Хорошо, это довольно много вопросов/вопросов/и т.д. в одном :-)

И я до сих пор не совсем понимаю, с чем именно вы столкнулись с этим сценарием.

Прежде всего, синтаксис команды set является

set <variable name>=<value> 

Если вы только

set <variable name> 

, то это будет список всех переменных окружения, начиная с <variable name>. Если их нет, выдается сообщение об ошибке, которое вы видите.

Если вы хотите определить переменную без фактического ухода за ее значением, вам все равно необходимо предоставить значение.Я обычно использую 1 для таких флагов, так как это то скорее переключатель вкл/выкл, чем действительная переменная, содержащий значение:

set Foo=1 

В вашем случае вы, вероятно, хотите что-то другое, хотя. В пакетных файлах нет массивов как таковых, вы можете имитировать их, создав ряд переменных и удерживая граф где-нибудь. Я написал об этом once before (немного устаревший, но все еще действительный).

В вашем случае вы хотите выполнять итерацию по нескольким серверам и для каждого сервера по нескольким пользователям. Вы можете сделать это с помощью вложенного цикла:

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

Что касается ваших двух вопросов там:

  1. Нет, переменная цикла действует только внутри петли, а не при вызове подпрограммы. Вы можете передать его в подпрограмму, однако:

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

    Вы можете получить доступ к нему с %1 в подпрограмме. Честно говоря, в большинстве случаев я считаю, что вложенные петли легче читать.

  2. Да.

Другая ошибка (один, что будет прикус вас): Как упоминалось ранее, синтаксис set является

set variable=value 

Обратите внимание, что не существует не пространство вокруг = знака. Если есть, то у вас есть пробел в конце имени переменной или в начале значения:

> set foo = bar 
> echo %foo% 
%foo% 
> echo %foo % 
bar 
+0

+1 и проверьте: отличные описания и пояснения. Если бы я мог голосовать несколько раз, я бы это сделал. Мне еще предстоит найти превосходный ресурс в Интернете, который дает хорошую информацию и полные примеры. Еще раз, отлично !!! – IAbstract

Смежные вопросы