
- •If "%1" equ "" goto error
- •If "%1" equ "" goto error
- •14:30:59.93 - Часы, минуты, секунды, сотые доли секунды.
- •If "%1" neq "" goto parmok
- •If %errorlevel% equ 4 goto exit
- •If not errorlevel 1 net.Exe send admincomp %%I %1
- •If /I %%I neq %computername% psshutdown -k -t 0 %%I
- •Image - программа вызвавшая окно.
- •Iconv [-c] [-s] [-f encoding] [-t encoding] [inputfile ...]
If "%1" neq "" goto parmok
ECHO Нужно задать командную строку для определения ERRORLEVEL
exit
:PARMOK
%1 %2 %3 %4 %5 %6 %7 %8
ECHO %1 %2 %3 %4 %5 %6 %7 %8 ERRORLEVEL=%ERRORLEVEL%
Примеры запуска:
echoEL.bat NET SHARE
- будет выполнена команда NET SHARE (выдать список разделяемых сетевых ресурсов) и выдан код ERRORLEVEL
echoEL.bat NET SHARE X"="C:\
- будет выполнена команда NET SHARE X:=C:\ (создать разделяемый сетевой ресурс с именем X, и путем в корневой каталог диска C:) Обратите внимание на то, что символ = заключен в двойные кавычки.
Перечисленные выше варианты задают корректную командную строку. Но попробуйте задать неверный параметр для NET.EXE или вообще несуществующую команду и вы увидите, какое значение примет ERRORLEVEL.
Диалог с пользователем
Для диалога с пользователем можно использовать команду:
SET /P имя переменной = текст
при выполнении которой, на экран выдается текстовое сообщение < текст > и ожидается ввод ответа. Пример - выполним запрос пароля и присвоим его значение переменной "pset":
set /p pset="Enter password - "
echo Password is - %pset%
Недостатком данного способа является невозможность продолжения выполнения командного файла при отсутствии ответа пользователя, поэтому очень часто вместо set используются сторонние программы. Одна из них - CHOICE.COM Скачать (1.7кб).
CHOICE выдает пользователю текстовое сообщение и ожидает выбора одного из заданных вариантов ответа (нажатия клавиш на клавиатуре). По результатам выбора формируется переменная ERRORLEVEL, значение которой равно порядковому номеру выбора. По умолчанию вариантов выбора два - Y или N. Если ответ равен Y - то ERRORLEVEL=1, если N - то ERRORLEVEL=2. Можно использовать более 2-х вариантов выбора и есть возможность задать выбор по умолчанию, когда пользователь за определенное время не нажал ни одной клавиши. Формат командной строки:
CHOICE [/C[:]choices] [/N] [/S] [/T[:]c,nn] [text]
/C[:]choices - определяет допустимые варианты выбора. Если не задано - YN
/N - не выдавать варианты выбора.
/S - строчные и заглавные буквы отличаются.
/T[:]c,nn - Выбор по умолчанию равен "c" через "nn" секунд
text - Строка текста выводимая в качестве запроса
Создадим командный файл, демонстрирующий использование CHOICE. Он будет реагировать на нажатие клавиш "1","2",3" и "0" . При нажатии "0" выполняется завершение, а при нажатии остальных - сообщение пользователю. Если в течении 10 секунд ничего не нажато - завершение.
@ECHO OFF
:CHOICE
CHOICE /C:1230 /T:0,10 Ваш вариант
If %errorlevel% equ 4 goto exit
echo Ваш выбор=%ERRORLEVEL%
GOTO CHOICE
:EXIT
Теперь, используя CHOICE вы можете создавать командные файлы, логика работы которых может определяться пользователем.
Задержки в командных файлах
Когда-то, еще в DOS, для организации ожидания в командном файле использовалась команда SLEEP, но затем она почему-то перекочевала из стандартного установочного набора Windows в дополнительный Resource Kit. Можно просто скопировать его оттуда в каталог \system32 и использовать в ваших командных файлах.
: SLEEP N - где N - количество секунд для задержки.
Если же Resource Kit нет под рукой, можно воспользоваться ранее рассмотренной командой CHOISE без вывода текста и с автоматическим формированием ответа через nn секунд (1-99):
choice.com /T:y,10 /N - задержка на 10 секунд
Более удобный способ основан на использовании утилиты ping.exe для петлевого интерфейса. Пинг для петлевого интерфейса (имя хоста - localhost или IP- адрес 127.0.0.1) выполняется без реальной передачи данных, т.е. практически мгновенно, а интервал между посылкой icmp-пакетов составляет 1 секунду. Указывая количество "пингов" с помощью ключа "-n" можно получить задержку на n секунд:
ping 127.0.0.1 -n 30 > nul - даст задержку на 30 секунд
Перенаправление вывода команды ping на фиктивное устройство nul ( > nul ) позволяет убрать сообщения утилиты ping.exe с экрана.
Определение доступности IP-адреса
Для проверки доступности сетевого узла используется упоминаемая выше стандартная утилита ping.exe. Утилита выполняет отправку ICMP-пакета на проверяемый узел (эхо-запрос) и ожидает ответный пакет (эхо-ответ). Результат проверки никак не отражается в переменной ERRORLEVEL и может быть получен только в данных стандартного вывода ping. Ненулевое значение ERRORLEVEL утилита ping.exe формирует только в том случае, если заданы ошибочные параметры командной строки. Иными словами, в некоторых случаях, нужный результат выполнения определенной команды нельзя определить по значению переменной ERRORLEVEL, и приходится анализировать, например, результат текстового вывода.
Если внимательно посмотреть на сообщения программы ping.exe при опросе доступного и недоступного узла, то можно заметить, что они значительно отличаются :
ping 456.0.0.1 - ping на несуществующий адрес
Ответ на такую команду может отличаться от конкретной версии утилиты, и может быть приблизительно таким
При проверке связи не удалось обнаружить узел 456.0.0.1. Проверьте имя узла и повторите попытку.
ping yandex.ru - ping на адрес узла yandex.ru
Ответ на ping доступного узла:
Обмен пакетами с yandex.ru [87.250.250.11] по 32 байт:
Ответ от 87.250.250.11: число байт=32 время=10мс TTL=55
Таким образом, для решения задачи определения доступности узла в командном файле, достаточно проанализировать характерные слова в выводе ping.exe при успешном ответе. Наиболее характерно в данном случае наличие слова TTL. Оно никогда не встречается при возникновении ошибки и состоит всего лишь из символов английского алфавита. Для поиска "TTL" в результатах ping.exe удобнее всего объединить ее выполнение в цепочку с командой поиска строки символов FIND.EXE (конвейер ping и find). Справку по использованию можно получить командой
find /?
Поиск текстовой строки в одном или нескольких файлах.
FIND [/V] [/C] [/N] [/I] [/OFF[LINE]] "строка" [[диск:][путь]имя_файла[ ...]]
/V Вывод всех строк, НЕ содержащих заданную строку.
/C Вывод только общего числа строк, содержащих заданную строку.
/N Вывод номеров отображаемых строк.
/OFF[LINE] Не пропускать файлы с установленным атрибутом "Автономный".
/I Поиск без учета регистра символов.
"строка" Искомая строка.
[диск:][путь]имя_файла
Один или несколько файлов, в которых выполняется поиск.
Если путь не задан, поиск выполняется в тексте, введенном с клавиатуры
либо переданном по конвейеру другой командой.
Как видно из справки, find.exe можно использовать для поиска нужной строки символов в тексте, переданном по конвейеру командой ping.exe. Если текст найден, значение переменной ERRORLEVEL будет равно 0
ping -n 1 COMPUTER | find /I "TTL" > nul
if %ERRORLEVEL%==0 goto LIVE
ECHO computer не доступен
подпрограмма обработки недоступного состояния
...
Exit
:LIVE - начало подпрограммы обработки состояния доступности узла
...
...
В конвейер добавлена команда перенаправления стандартного вывода на фиктивное устройство nul, т.е. подавление вывода. Ключ -n 1 задает однократный опрос узла COMPUTER для ping.exe.
Поиск компьютеров с запущенным приложением
Для реализации этого скрипта используются утилиты из пакета PSTools (краткое описание). Создадим командный файл, выполняющий поиск в локальной сети компьютеров с выполняющейся программой, имя которой (начальная часть имени) задается в качестве параметра при запуске, например, game . При обнаружении будет послано сообщение на компьютер ADMINCOMP и обнаруженное приложение будет принудительно завершено. Для поиска будем использовать утилиту Pslist.exe и анализировать ее код возврата. Значение переменной ERRORLEVEL равное нулю означает, что утилита обнаружила на удаленном компьютере процесс, удовлетворяющий условиям поиска. Имя процесса для поиска будем задавать в качестве параметра при запуске командного файла. Присвоим нашему командному файлу имя psl.bat. Запуск с параметром будет выглядеть следующим образом:
psl.bat game
Для начала, нужно проверить, задан ли параметр в командной строке при запуске, и, если не задан, выдадим сообщение пользователю и завершим выполнение. Если же параметр задан - перейдем на метку " PARMOK ":
@echo off
if "%1" NEQ "" GOTO PARMOK
ECHO Нужно задать имя процесса для поиска
exit
:PARMOK
Теперь нужно обеспечить последовательное формирование IP-адресов компьютеров для командной строки PSlist. Проще всего это сделать с помощью присвоения временной переменной окружения (действительной только на время выполнения командного файла) значения постоянной составляющей адреса (например - 192.168.0.) и вычисляемого значения младшей части (например, в диапазоне 1-254). Для примера будем считать, что нам необходимо просканировать компьютеры в диапазоне адресов:
192.168.0.1 - 192.168.0.30:
set IPTMP=192.168.0. - старшая часть адреса
set /A IPLAST=1 - младшая часть. Ключ /A означает вычисляемое числовое выражение
set IPFULL=%IPTMP%%IPLAST% - значение полного IP-адреса.
Командная строка для PSlist будет выглядеть cледующим образом:
pslist \\%IPFULL% %1
Теперь осталось только циклически запускать PSlist, прибавляя в каждом цикле единицу к младшей части адреса, пока ее значение не достигнет 30 и анализировать значение ERRORLEVEL после выполнения. Для анализа результата будем выполнять переход командой:
GOTO REZULT%ERRORLEVEL%
обеспечивающей переход на метку REZULT0 при обнаружении процесса и на REZULT1 - при его отсутствии.
Окончательное содержимое командного файла:
@echo off
if "%1" NEQ "" GOTO PARMOK
ECHO Нужно задать имя процесса для поиска
exit
:PARMOK
set IPTMP=192.168.0.
rem Зададим начальное значение " хвоста " IP- адреса
set /A IPLAST=1
rem M0 - метка для организации цикла
:M0
rem Переменная IPFULL - полное значение текущего IP-адреса
set IPFULL=%IPTMP%%IPLAST%
rem Если " хвост "больше 30 - на выход
IF %IPLAST% GTR 30 GOTO ENDJOB
pslist \\%IPFULL% %1
GOTO REZULT%ERRORLEVEL%
:REZULT0
rem Если найдено приложение- отправим сообщение на ADMINCOMP
net send ADMINCOMP Запущено %1 - %IPFULL%
rem И завершим приложение с помощью PSkill
pskill \\%IPFULL% %1
:REZULT1
rem Сформируем следующий IP-адрес
set /A IPLAST=%IPLAST% + 1
rem Перейдем на выполнение следующего шага
GOTO M0
rem Завершение работы
:endjob
exit
В заключение добавлю, что для того, чтобы этот скрипт работал, PSlist.exe и PSkill.exe должны быть доступны в путях поиска исполняемых файлов, например в каталоге WINDOWS\SYSTEM32. Пользователь, запускающий его, должен обладать правами администратора по отношению к сканируемым компьютерам. И, если текущий пользователь таковым не является, то в параметры запуска утилит PSlist.exe и PSkill.exe нужно добавить ключи, задающие имя пользователя и пароль.
Поиск компьютеров с запущенным приложением по списку
В предыдущем примере использовался прямой перебор IP-адресов компьютеров в локальной сети, что не всегда удобно, поскольку в процедуру опроса оказываются вовлечены и выключенные компьютеры. Решим задачу другим способом. Создадим текстовый файл со списком компьютеров и опросим их по этому списку.
Список можно получить из сетевого окружения с использованием команды:
net.exe view > comps.txt
После выполнения такой команды файл comps.txt будет содержать список следующего вида:
Имя сервера Заметки
< 2 пустых строки >
-------------------------------------------------------------------------------
\\AB1
\\AB2
\\ALEX
\\BUHCOMP
\\PC2
\\SA
\\SERVER
Команда выполнена успешно.
Обрабатывать содержимое этого текстового файла будем с помощью команды FOR с ключом /F:
FOR /F ["ключи"] %переменная IN (имя файла) DO команда [параметры]
Данная команда позволяет получить доступ к строкам в текстовом файле с использованием ключей:
skip=n - пропустить n строк от начала файла (в нашем случае - 4 строки)
eol=< символ > - не использовать строки, начинающиеся с заданного символа. (в нашем случае - пропустить последнюю строку, начинающуюся с символа "К" - "Команда выполнена успешно"
tokens=n - брать для обработки n-е слово в строке (в нашем случае - 1-е слово)
Окончательный вид команды:
FOR /F "eol=К skip=4 tokens=1 " %%I IN (comps.txt) DO (
pslist.exe -u admin -p pass %%I %1