- Введение
- Определение
- MS-DOS batch
- Зачем нужны bat-файлы
- Передача параметров
- Использование кавычек
- Экранирование спецсимволов
- Получение свойств файла сценария
- Перенаправление вывода в файл
- Использование функций
- Чтение конфигурационного файла
- Конвейеры
- Сценарий "Установка программы"
- Сценарий "Распаковка всех архивных файлов"
- Сценарий "Создание загрузочного диска"
- Сценарий "Разметка и форматирование диска"
- Сценарий "Настройка компьютера"
В работе системного администратора встречается много рутинной работы. Естественно, человек всегда ищет способы автоматизации своей работы. Администратору для решения задач оптимизации своей работы помогают скрипты (сценарии).
В данной статье я хочу рассказать о скриптах для операционных систем семейства Windows. Конечно, сейчас очень сильно развиты языки высшего уровня, различные автоматические оптимизаторы и оболочки, но, как я считаю, администратор должен уметь работать с командной строкой и знать операционную систему, в которой он работает. Эта статья не будет построена на голой теории, я не буду углубляться в механизмы работы той или иной команды, мы рассмотрим основные команды двух оболочек сценариев, встроенных в операционную систему, а так же посмотрим основные возможности скриптовых языков.
Скриптовый язык (scripting language) - это язык программирования, разработанный для записи "сценариев", последовательности операций, которые пользователь может выполнять на компьютере.
То есть скрипты могут повторить практически все операции, которые пользователь выполняет на компьютере:
- Сконфигурировать систему;
- Сконфигурировать профиль пользователя;
- Установить или удалить программу;
- Собрать статистику работы компьютера или пользователя;
- Сделать резервные копии файлов;
- Другие операции.
Конечно, все эти операции можно осуществить либо вручную, либо через язык программирования высокого уровня, тем не менее, не стоит забывать и о сценариях, как о простом методе выполнения процедур, доступном для любого пользователя. Скриптовый язык предпочтительнее применять, если:
- нужна прозрачность кода сценария, сценарии обычно распространяются с открытым кодом, и любой пользователь может посмотреть, какие команды будет выполнять сценарий;
- нужно обеспечить стабильность системы, неправильно написанный скрипт выведет диагностическое сообщение, а не приведёт систему к краху;
- требуется дать пользователям возможность самостоятельно изменять переменные сценария и процедуры;
- нужно использовать процедуры определенной программы, которые проще осуществить через сценарии, чем осуществлять интерфейс между приложениями;
- требуется кроссплатформенность - возможность исполнять сценарий на разных операционных системах или в разных браузерах.
Итак, в зависимости от способа реализации сценария и универсальности использования этого сценария, скрипты делятся на нескольких типов:
- Универсальные - скрипты, которые выполняются независимо от платформы, такие скрипты требуют компиляции, примеры таких языков: Perl (Practical Extraction and Report Language), Python, PHP (Hypertext Preprocessor).
- Интегрированные в приложение - это скрипты, которые разработаны и работают только внутри определенной программы, явный представитель этого класса - VBA (Visual Basic for Applications).
- Оболочки - скрипты, которые работают в специальной среде выполнения команд, членам этой группы являются такие скриптовые языки как sh, bash (Bourne shell), bat (MS-DOS batch).
- Встраиваемые - это языки, которые можно интегрировать в различные приложения, такие языки имеют жесткие стандарты для того, чтобы любая программа, в которую будет интегрирован сценарий, смогла выполнить этот сценарий, примерами таких языков являются js (Java Script), vbs (Visual Basic Script).
В этой статье я рассмотрю два скриптовых языка: "MS-DOS batch" и " Visual Basic Script". Все приведенные примеры я использовал в своей работе, хотя для написания статьи они немного упрощены. Кстати, сценарии очень удобно применять в групповых политиках, в запланированных заданиях и в таком продукте, как Microsoft System Management Server 2003 (MS SMS 2003).
Bat-файлы - это наиболее быстрый и простой способ автоматизации действий пользователя. Такой тип сценариев обычно используется чтобы:
- создать скрипт как можно быстрее;
- видеть ход выполнения сценария;
- видать результаты работы скрипта на экране;
- знать, когда скрипт закончит работу;
- вызвать внешнее приложение в ходе работы скрипта.
В основном bat-файлы применяется для копирования и удаления файлов, составления отчетов, запуска других программ и скриптов. Наиболее часто используемые команды:
- копирование файлов и каталогов: copy, xcopy;
- перемещение файлов: move;
- удаление файлов и каталогов: del, rd;
- создание каталогов: md;
- перемещение по файловой системе: cd;
- информация о содержимом файлов и каталогов: type, dir;
- запуск оболочки и выход из нее: cmd, exit;
- вызов внешних приложений, циклы и условия: call, for, goto, if, set;
- дополнительные команды: at, net, set, cls.
Чтобы получить полный список команд, доступных в Вашей операционной системе, надо вызвать командную строку и выполнить команду "help" (надеюсь, что читатели знают, как запустить командную строку в Windows):
C:\>help
Чтобы из команд получился сценарий, нужно построчно написать список команд в текстовый файл и сохранить этот файл с расширением "bat".
Какими бы примитивными не казались bat-файлы, c помощью них можно сильно автоматизировать работу. Мало того, такие сценарии поддерживают передачу переменных через командную строку. Например, чтобы обработать какой-то файл, нужно, чтобы сценарий знал, какой именно файл нужно обработать. Конечно, можно прописать имя обрабатываемого файла непосредственно в коде, но тогда мы получим неуниверсальный скрипт. Чтобы избежать этого, нужно использовать передачу переменных:
- в теле сценария использовать обращение к переданной переменной;
- при вызове скрипта передавать ему переменную или список переменных через пробел.
Тело сценария Test.bat:
REM отключение вывода команд на экран @echo OFF REM вывод на экран переданной в переменной echo %1 REM остановка в ходе выполнения сценария pause
Вызов сценария:
C:\>Test.bat MyParameter
Очень часто в путях к внешним приложениям употребляются пробелы, например, если программа находится в каталоге "Program Files". В таких случаях путь к файлу должен быть заключен в кавычки, иначе интерпретатор сценария сочтет, что вы ввели две команды, разделенных пробелами. Пример использования кавычек:
call "C:\Program Files\Movie Maker\moviemk.exe" call "C:\My Folder\test.bat" "C:\My Catalog\archive.zip"
В командном языке существует некоторый набор символов, которые всегда трактуются как спецсимволы. К ним, в частности, относятся:
- операторы перенаправления ввода-вывода <, >, >>;
- оператор конвейера |;
- операторы объединения команд ||, & и &&;
- оператор переменной %…%.
Чтобы применять вышеперечисленные символы в своих целях, их нужно экранировать символом "^". То есть, если Вам требуется вставить символ в текст своей команды, то это будет выглядеть так:
echo ^<html^> >mytest.html echo ^<head^> >>mytest.html echo ^<title^>My test page^</title^> >>mytest.html echo ^</head^> >>mytest.html echo ^<body^> >>mytest.html echo Hello World! >>mytest.html echo ^</body^> >>mytest.html echo ^</html^> >>mytest.html
Еще одним полезным свойством символа "^" является перенос строк. То есть, если ваша команды слишком длинные, то это обстоятельство уменьшает удобочитаемость сценария. Чтобы вся команда убиралась в экран редактора, применим перенос строки:
oscdimg -m -n -h -lDeployment -bC:\Common\DeploymentDisk\winpe_x86\etfsboot.com ^ C:\Common\DeploymentDisk\winpe_x86\ISO C:\Common\DeploymentDisk\winpe_x86\^ Deployment.iso
Очень часто разработчику необходимо знать путь, откуда сценарий был запущен. В решении этой задачи ему помогают специальные переменные:
- %~0 - возвращает путь к сценарию, удаляя кавычки
- %~f0 - возвращает полный квалифицированный путь к сценарию
- %~d0 - возвращает в букву диска, откуда запущен сценарий
- %~p0 - возвращает путь к сценарию
- %~n0 - возвращает имя файла сценария
- %~x0 - возвращает расширение файла сценария
- %~s0 - возвращает путь к сценарию в коротком формате
- %~a0 - возвращает атрибуты файла сценария
- %~t0 - возвращает в дату и время создания файла сценария
- %~z0 - возвращает размер файла сценария
Указанные модификаторы можно объединять. Например, чтобы получить полный путь к директории, откуда был запущен сценарий, нужно применить в тексте сценария такой модификатор "%~dp0":
REM отключение вывода команд на экран @echo OFF REM вывод на экран месторасположения файла сценария echo %~dp0 REM остановка в ходе выполнения сценария pause
Интерпретатор сценариев таким образом может обработать не только путь к файлу сценария, но и пути, переданные в качестве параметров. Чтобы применить модификаторы к переданному параметру, необходимо указать его порядковый номер в командной строке. Как уже понятно из предыдущего примера, нулевым параметром является сам сценарий, а все остальные переданные переменные нумеруются от 1 до 9:
REM отключение вывода команд на экран @echo OFF REM вывод на экран имени файла, переданного в качестве переменной echo %~nx1 REM остановка в ходе выполнения сценария pause
Кстати, не стоит забывать заключать переменные в кавычки, ведь переменные могут содержать пробелы.
Обычно каждая команда из сценария выводит результат своей работы в окно консоли. Если необходимо сохранить журнал выполнения скрипта, то для этого используют перенаправление вывода в файл:
- команда >файл - перенаправить вывод в файл с удалением старого содержимого файла;
- команда >>файл - перенаправить вывод в файл c дописыванием в конец файла.
Иногда bat-файлы вырастают до довольно больших размеров, тогда перенаправление в файл очень загромождает код сценария - почти каждая строка имеет хвостик типа >>файл. Правильнее было бы перенаправить стандартный вывод в файл, чтобы все, что выводится на экран, автоматически попадало в файл вывода. Сделать это можно следующим образом:
REM отключение вывода команд на экран @echo OFF REM установка значения переменной имени файла вывода set OUTPUT=mytest.html REM задание вывода работы сценария в файл вывода if "%STDOUT_REDIRECTED%" == "" ( set STDOUT_REDIRECTED=yes cmd.exe /c %0 %* >%OUTPUT% exit /b %ERRORLEVEL% ) REM тело сценария echo ^<html^> echo ^<head^> echo ^<title^>My test page^</title^> echo ^</head^> echo ^<body^> echo Hello World! echo ^</body^> echo ^</html^>
В этом примере сценарий проверяет задана ли переменная окружения STDOUT_REDIRECTED. Если она не установлена, то сценарий перезапускает сам себя, предварительно устанавливая эту переменную и останавливая выполнение остальных команд из тела скрипта. Если переменная STDOUT_REDIRECTED установлена, значит, сценарий уже перезапущен с перенаправленным выводом, и можно перейти к телу сценария. Такое перенаправление дает еще одно преимущество - файл открывается и закрывается только один раз, а всем командам передается ссылка на уже открытый файл.
Иногда требуется, чтобы сценарий вообще ничего не выводил ни на экран, ни в файл. Добиться такого результата можно с помощью отключения вывода команд на экран и перенаправления результатов команд в ноль.
REM отключение вывода команд на экран @echo OFF REM перенаправление результатов команд в ноль copy text.txt test2.txt >nul
Иногда может потребоваться обрабатывать какой-то параметр несколько раз за один проход сценария. Конечно, можно несколько раз написать код для обработки переменной, но более красивым решением было бы применение функций. Функции объявляются и описываются после основной части сценария, вызов функции производится командой call, а выход из нее - exit. Простой пример использования функции:
REM отключение вывода команд на экран @echo OFF REM вызов функции call :GetSum %1 %2 -30 REM вывод результатов на экран echo (%1 + %2 - 30) = %RESULT% REM остановка в ходе выполнения сценария pause REM окончание основной программы, выход из сценария exit REM функция суммирования :GetSum if %1 == 0 ( set /a RESULT=%2+%3 exit /b ) set /a RESULT=%1+%2+%3 exit /b
Встречаются случаи, когда сценарию нужно передать параметры, описанные в конфигурационном файле. Например, мы имеем файл следующего формата:
# Файл с настройками # Первое число Value1=23 # Второе число Value2=15
Чтобы его прочитать, воспользуемся следующим сценарием:
@echo OFF REM Вызов функции считывания текстового файла config.txt call :read_config "%~dp0\config.txt" || exit /b 1 REM Вывод считанных параметров на экран echo Build mode : %Value1% echo Compiler : %Value2% REM окончание основной программы, выход из сценария exit /b 0 REM функция считывания текстового файла :read_settings set ConfigFile=%1 REM Проверка существования файла if not exist %ConfigFile% ( echo FAIL: Файл с настройками отсутствует exit /b 1 ) REM Обработка файла REM eol=# - указывает, что строку надо пропустить - это комментарий REM delims== - указывает разделитель - это символ "=" REM tokens= - указывает как распределить разделенные переменные for /f "eol=# delims== tokens=1,2" %%i in (%ConfigFile%) do ( set %%i=%%j ) exit /b 0
Конвейеры - это операторы, которые позволяют командам работать совместно. Обратите внимание на строку вызова функции в предыдущем примере - в ней присутствует конвейер "||". Давайте рассмотрим, какие же конвейеры могут использоваться в bat-файлах:
- < - ввод в первую команду результатов выполнения второй программы;
- | - передача выхода первой команды непосредственно на вход другой;
- || - выполнение второй команды только в том случае, если первая дала сбой;
- & - выполнение второй команды после выполнения первой;
- && - выполнение второй команды только в том случае, если первая выполнена успешно.
Данный пример осуществляет поиск каталога или файла, в название которого входит слово "Accessories".
dir "C:\Program Files" /S | find "Accessories"
Конвейер команд состоит из двух частей: первая команда выводит все файлы и каталоги папки "C:\Program Files" (дополнительный параметр "/S" означает, что нужно обработать и подпапки), вторая команда получает результат выполнения первой через оператор конвейера "|" и осуществляет поиск слов "Accessories".
На этом я закончу разбор операторов командной строки и приведу несколько сценариев bat-файлов из моей практики.
Данный сценарий разработан для установки программы Autodesk DWG True View. Установочный пакет и скрипт размещаются на сервере. Чтобы установить программу на компьютер пользователя, нужно подключить сетевой ресурс на требуемом компьютере и запустить bat-файл.
REM отключение вывода команд на экран @ECHO OFF REM задание заголовка окна оболочки TITLE Autodesk DWG True View REM запуск установочного файла в режиме пассивной установки "%~DP0DWGViewer.msi" /passive REM копирование чертежа на рабочий стол пользователей COPY "%~DP0Draw.dwg" "%ALLUSERSPROFILE%\Desktop"
Здесь используются такие параметры как:
- %~DP0 - подстановка пути месторасположения сценария;
- %ALLUSERSPROFILE% - подстановка пути общего профиля пользователей;
- package.msi/passive - установка MSI-пакета в пассивном режиме - установка "По умолчанию" без окон подтверждения.
Данный сценарий разработан для распаковки всех архивов, находящихся в одной папке, в указанную директорию. Приложение-распаковщик, папка с архивами и папка для распакованных файлов находятся в той же директории, что и сценарий. Чтобы установить распаковать архивы, нужно запустить bat-файл.
REM отключение вывода команд на экран @ECHO OFF REM проверка, что папка для распаковки существует, удаление папки IF EXIST "%~DP0Extracts" RD "%~DP0Extracts" /S /Q REM создание папки для распаковки MD "%~DP0Extracts" REM распаковка всех 7z-файлов из папки Archives в папку Extracts FOR %%a IN ("%~DP0Archives\*.7z") DO CALL "%~DP07z.exe" e "%%a" -o"%~DP0Extracts" -r
Здесь используются такие процедуры как:
- IF EXISTfolder- поверка существования папки или файла;
- %~DP0 - подстановка пути месторасположения сценария;
- RDfolder/S /Q - удаление каталога без вывода на экран подтверждения на удаление
- FOR %%a IN (folder\mask) DO - цикл перебора всех элементов в выбранном списке;
- CALLapplication"%%a" - вызов внешнего приложения и передача ему параметра из цикла.
Данный сценарий разработан для создания загрузочного диска с помощью пакета Microsoft Windows Automated Installation Kit. Запускается из командной строки указанного выше пакета. Результатом работы сценария является загрузочный ISO-образ, который впоследствии можно записать на DVD и использовать для установки или восстановления системы. Более подробно о создании такого диска будет рассказано в одной из следующих статей.
REM копирование заготовки загрузочного диска copype.cmd x86 c:\DeploymentDisk\winpe_x86 REM монтирование заготовки для изменения imagex /mountrw c:\DeploymentDisk\winpe_x86\winpe.wim 1 c:\DeploymentDisk\^ winpe_x86\mount REM внедрение в заготовку необходимых пакетов peimg /install=WinPE-Scripting-Package c:\eploymentDisk\winpe_x86\mount\^ Windows peimg /install=WinPE-HTA-Package c:\DeploymentDisk\winpe_x86\mount\Windows peimg /install=WinPE-WMI-Package c:\DeploymentDisk\winpe_x86\mount\Windows peimg /install=WinPE-XML-Package c:\DeploymentDisk\winpe_x86\mount\Windows REM вывод на экран установленых в заготовку пакетов peimg /list c:\DeploymentDisk\winpe_x86\mount\Windows REM внедрение в заготовку дополнительных драйверов peimg /inf=C:\DeploymentDisk\winpe_tools\Drivers\*.inf c:\DeploymentDisk\^ winpe_x86\mount\Windows REM подготовка заготовки к записи на диск peimg /prep /f c:\DeploymentDisk\winpe_x86\mount\Windows REM копирование дополнительных программ в заготовку xcopy C:\DeploymentDisk\winpe_tools\Starter c:\DeploymentDisk\winpe_x86\^ mount\ /S /Y xcopy C:\DeploymentDisk\winpe_tools\winpe.bmp C:\DeploymentDisk\winpe_x86\^ mount\Windows\System32\ /Y xcopy C:\DeploymentDisk\winpe_tools\winpeshl.ini C:\DeploymentDisk\winpe_x86\^ mount\Windows\System32\ /Y REM размонтирование заготовки imagex /unmount /commit c:\Common\DeploymentDisk\winpe_x86\mount REM копирование готового загрузчика в папку ISO-проекта xcopy /y C:\DeploymentDisk\winpe_x86\winpe.wim C:\DeploymentDisk\winpe_x86\^ ISO\sources\boot.wim REM копирование дополнительных программ в ISO-проект xcopy C:\DeploymentDisk\winpe_tools\FarManager C:\DeploymentDisk\winpe_x86\^ iso\FarManager\ /S /Y xcopy C:\DeploymentDisk\winpe_tools\Starter C:\DeploymentDisk\winpe_x86\iso\^ Starter\ /S /Y xcopy C:\DeploymentDisk\winpe_tools\Deployment C:\DeploymentDisk\winpe_x86\iso\^ Deployment\ /S /Y REM создание ISO-образа загрузочного диска oscdimg -m -n -h -lDeployment -bC:\Common\DeploymentDisk\winpe_x86\etfsboot.com ^ C:\Common\DeploymentDisk\winpe_x86\ISO C:\Common\DeploymentDisk\winpe_x86\^ Deployment.iso
Здесь используются такие процедуры Microsoft Windows Automated Installation Kit как:
- copype.cmd - сценарий копирования заготовки диска;
- imagex - утилита редактирования образа операционной системы;
- peimg - утилита подготовки образа операционной системы;
- oscdimg - утилита создания ISO-образов;
Этот сценарий разработан для разметки и форматирования диска компьютера перед установкой операционной системы. Скрипт в основном запускают в специальной прединсталляционной операционной системе Windows PE, например в такой, какая была собрана в предыдущем примере.
REM отключение вывода команд на экран @ECHO OFF REM создание новой дисковой структуры ECHO "Creating the new disk structure" DISKPART.EXE /S "%~DP0DiskPart00.txt">nul REM создание файловой сиситемы ECHO "Formating the disk" ECHO Y | FORMAT C: /Q /FS:NTFS /V:>nul REM вывод на экран результатов обработки диска DISKPART.EXE /S "%~DP0DiskPart01.txt" ECHO "The disk partitioning is completed. Please review the log in this window." PAUSE
В этом примере используются:
- DISKPART.EXE - утилита разметки диска, которая использует внешние сценарии (эти сценарии приведены ниже);
- конвейер "|" - на вход команды "FORMAT" подается значение "Y", что позволяет избежать участия пользователя в работе сценария;
- FORMAT - команда форматирования диска, использующая ключи, которые определяют, что нужно отформатировать диск С: в формате NTFS в быстром режиме и без метки диска;
- >nul - перенаправление результатов команд в ноль.
Сценарий разметки диска:
select disk 0 clean create partition primary select partition 1 active assign letter=C
Сценарий вывода информации о диске:
select disk 0 select partition 1 detail partition
Данный сценарий применяется сразу же после установки операционной системы с целью настроить компьютер под стандарты компании. Сценарий работает как единый центр выполнения внешних приложений и других сценариев. Для корректной работы требуется наличие в папке основного сценария всех вызываемых приложений и скриптов. После выполнения команд сценарий удаляет все внешние модули, а также себя, чтобы пользователь не смог воспользоваться данными из скриптов.
REM отключение вывода команд на экран @ECHO OFF REM создание меню быстрого запуска IF NOT EXIST "%SYSTEMDRIVE%\Documents and Settings\Default User\Application Data\^ Microsoft\Internet Explorer\Quick Launch\" MD "%systemdrive%\^ Documents and Settings\Default User\Application Data\Microsoft\^ Internet Explorer\Quick Launch\" REM установка классического входя в систему REGEDIT /S "%~DP0Classic_Login.reg" REM удаление ярлыка на центр обновления Windows IF EXIST "C:\Documents and Settings\All Users\Start Menu\Windows Update.lnk"^ DEL "C:\Documents and Settings\All Users\Start Menu\Windows Update.lnk">nul REM остановка сервиса Windows Management Instrumentation NET STOP "WINMGMT" /Y>nul REM удаление репозитория сервиса Windows Management Instrumentation DELTREE /Y "%SystemRoot%\System32\WBEM\Repository">nul REM запуск сервиса Windows Management Instrumentation NET START "WINMGMT" /Y>nul REM регистрация путей драйверов CSCRIPT "%~DP0DevicePath.vbs" REM перемещение утилиты robocopy.exe в системный каталог MOVE /Y "%~DP0robocopy.exe" %SystemRoot%\System32 REM добавление администраторов компании в локальные администраторы компьютера CSCRIPT "%~DP0AddAccountToAdmins.vbs" "DOMAIN\Site Admins" REM замена ссылок "по умолчанию" на ссылки сервера компании "%~DP0REGFIND.exe" -b -y \\DefaultServer\Distrib$ -r \\SiteServer\Distrib$ "%~DP0REGFIND.exe" -b -y http://u18.eset.com:8081 -r http://SiteServer.domain.com:8081 REM установка клиента MS SMS 2003 MSIEXEC /i "%~DP0client.msi" /passive REM подписывание клиента MS SMS 2003 к серверу компании CSCRIPT "%~DP0AssignSMSClient.vbs" REM очистка журнала компьютера CSCRIPT "%~DP0ClearEventLogs.vbs" REM удаление временной папки RD /S /Q C:\Temp REM удаление сценариев настройки компьютера DEL /q "%~DP0ClearEventLogs.vbs" DEL /q "%~DP0regfind.exe" DEL /q "%~DP0DevicePath.vbs" DEL /q "%~DP0AddAccountToAdmins.vbs" DEL /q "%~DP0client.msi" DEL /q "%~DP0AssignSMSClient.vbs" REM перезагрузка компьютера CSCRIPT "%~DP0\Reboot.vbs"
Здесь использованы такие команды и внешние модули как:
- IF NOT EXIST folder command - проверка на существование папки;
- REGEDIT file - слияние файла с реестром;
- NET STOP - остановка сервиса;
- NET START - запуск сервиса;
- CSCRIPT - выполение VBS-сценария в консольном режиме;
- REGFIND - утилита поиска и замены значений реестра;
- MSIEXEC - утилита распаковки MSI-пакета.
Итак, давайте подведем итог: для чего применяются bat-сценарии, что с их помощью можно сделать, какие ограничения имеют такие сценарии:
- сценарии не требуют компиляции и их код в любой момент можно отредактировать;
- BAT-сценарии просты и быстры в написании;
- BAT-файлы выполняются в консоли, поэтому пользователь видит ход выполнения сценария, и знает, когда сценарий закончит свою работу;
- эти скрипты, в основном, применяются для копирования файлов и для запуска других приложений;
- BAT-файлы ограничены в функциональности и не могут выполнять сложных задач;
- такие сценарии могут выполняться только в консоли MS DOS.
Продолжение следует...