Пример программы для командной оболочки Windows

Несколько лет тому назад в компании, где я работал, произошел такой случай. Мне позвонили среди ночи и сообщили, что обновление серверного оборудования завершилось неудачно. Сетевая карта на одном из основных файловых серверов оказалась неисправной и связь с сетью была потеряна. У нас имелись запасные сетевые адаптеры, но при их установке возникали проблемы, поскольку на сервере, по-видимому, отсутствовали какие-либо кэшированные данные для работы в домене в автономном режиме, а пароль локального администратора был благополучно забыт. Итак, мы оказались запертыми в собственном оборудовании. В тот момент под рукой не оказалось утилит, которые могли бы нам помочь. И фактически нам пришлось, подобно хакерам, взламывать свой собственный сервер.

Зачастую системные администраторы придают особое значение смене паролей как средству поддержания должного уровня безопасности. Такое внимание локальной записи Administrator совершенно оправданно, так как с помощью этой учетной записи легко получить доступ ко всем данным сервера. Однако всегда хорошо иметь запасной сценарий, чтобы, оказавшись за консолью сервера, можно было успешно зарегистрироваться в системе. Нет ничего более неприятного при регистрации с консоли, чем увидеть на экране окошко с предупреждением, что имя или пароль указаны неверно.

Проверка и смена паролей на множестве серверов вручную занимает много времени. Из-за этого администратор всегда испытывает соблазн проверять и менять пароли реже, чем нужно, а следовательно, снижать сетевую безопасность. И со временем накапливаются ошибки — те самые ошибки, которые приводят к описанной выше ситуации.

К счастью, сценарии позволяют выполнять повторяющиеся операции, такие как проверка и смена паролей, с большей скоростью и более аккуратно, чем встроенные утилиты. Сценарии также обладают большими преимуществами, нежели графические утилиты независимых разработчиков (об этих преимуществах рассказано во врезке «Графические утилиты против сценариев»). Даже если вы никогда не писали сценарии, ничего страшного — начинайте прямо сейчас, используя Windows Shell, а для примера посмотрите, как работает сценарий PWcheck-change, полнофункциональный сценарий для проверки и смены паролей. Ниже я дам краткое пояснение к нему. А потом покажу, как настроить PWcheck-change для конкретного применения.

Программа PWcheck-change

PWcheck-change — это несложный сценарий, который используется для проверки и смены паролей на большом числе серверов, на что уходит всего лишь несколько секунд. Чтобы эффективно обслуживать и верифицировать пароли с помощью PWcheck-change, его нужно запускать в трех случаях. Во-первых, сценарий нужно периодически запускать для выполнения рутинных операций смены пароля. PWcheck-change переустанавливает пароли при запуске в следующем виде:

PWcheck-change.bat -Change

Во-вторых, нужно периодически запускать сценарий для проверки несанкционированного изменения пароля. PWcheck-change проверяет пароли на серверах и сообщает обо всех неверных паролях, когда сценарий запускается без аргументов:

PWcheck-change.bat

Наконец, в случае опасности сценарий нужно запустить как можно скорее. Например, если установлено, что на одном или нескольких серверах пароли скомпрометированы, следует выполнить аварийный запуск сценария как можно быстрее.

В процессе написания PWcheck-change я исходил из нескольких предположений относительно пользователя, который будет запускать сценарий.

  1. Предполагается, что пользователь следует стандартной практике применения уникальных имен и уникальных паролей для учетной записи администратора на всех серверах. Однако если все имена учетной записи администратора одинаковы или на всех серверах используется один и тот же пароль, можно будет указать данное общее имя или пароль для каждого сервера — точно так же, как и при указании уникальных имени и пароля.
  2. Предполагается, что серверы включены. Поскольку информация об учетной записи администратора находится в локальной учетной базе данных сервера, а не в Active Directory (AD), серверы должны быть включены, чтобы прошли заданные изменения. PWcheck-change сначала проверяет, включен ли сервер, а затем уже проверяет или меняет пароль.
  3. Предполагается, что пароли соответствуют ограничениям на длину и сложность, принятым в системе. Например, если минимальная длина пароля — восемь символов, для паролей администратора не следует задавать пароль, состоящий из шести символов. То же самое относится и к сложности пароля — нельзя задавать пароли, которые не соответствуют принятой схеме использования символов. Кстати, если вы нарушите свою собственную политику паролей, все ошибки будут зафиксированы в файле журнала работы сценария.
  4. Предполагается, что в пароле отсутствуют символы, зарезервированные для использования Windows Shell Scripting (WSS). Существует несколько символов, которые могут применяться в пароле, но являются зарезервированными WSS. Следует избегать использования в паролях следующих символов:

    , ^ & < > ( ) | = « ;

    Если попытаться задать пароль, среди символов которого будет любой из указанных выше, скорее всего, произойдет ошибка. Ниже приведены символы, которые могут использоваться:

    $ % @ # ! ` ? ~ . + _ — * : /

    Порой символы обратный тик (`) и одиночная кавычка (?) трудноразличимы, как и некоторые цифры и символы. Например, прямой слэш (l), набранный в нижнем регистре, он же, набранный в верхнем регистре (I), и цифра 1 выглядят похоже, так же как буква О и цифра 0. Можно задействовать четко различимые символы, буквы и цифры, только сначала следует убедиться, что используется именно то, что нужно.

  5. Предполагается, что на серверах отсутствуют открытые постоянные соединения (persistent connections). В режиме проверки PWcheck-change подсоединяется к IPC$ для проверки комбинации имя-пароль. Если в этот момент имеется открытое постоянное соединение, сценарий не сможет закрыть его и пользователь получит некорректное подтверждение о смене пароля.

Что там внутри?

Тех, кто готовится написать свой самый первый сценарий, первый взгляд на PWcheck-change может повергнуть в уныние. Не надо отчаиваться. Большинство составителей сценариев тоже поначалу думали, что написание сценариев — очень трудное дело. Но постепенно они начинали брать за основу уже созданные сценарии, изменять их, а потом научились создавать собственные сценарии с нуля.

В листинге 1 показан сценарий PWcheck-change. Как и в большинстве сценариев, код PWcheck-change состоит из нескольких важных секций.

Область заголовка, содержащая инициализацию и настройки

Эта область обозначена как метка A. Здесь обычно помещается инициализационный код. Сюда попадает, например, команда Echo Off — она отключает эхо команды (и на экране появляется только результат ее выполнения, но не сама команда), команда Title — задает заголовок командного окна (command-shell), которое открывается во время выполнения сценария. Вы и дальше можете подстраивать под себя командное окно, например менять цвет шрифта и фона или размер шрифта.

Далее в область заголовка включена команда Setlocal. Эта команда задает локальные переменные сценария.

Наконец, в области заголовка PWcheck-change содержится комментарий, как использовать данный сценарий. В сценариях часто применяется входной файл (с информацией, которую сценарий должен обработать), выходной файл (с результатами и другими данными, полученными в результате работы сценария) и утилиты (от Microsoft и независимых компаний, необходимые сценарию для выполнения поставленной задачи). Когда сценарий использует входной файл, выходной файл или утилиты, нужно указать местоположение этих объектов. В PWcheck-change требуется указать пути к входному файлу (в нем содержится имя сервера, имя учетной записи администратора и соответствующий пароль для каждого сервера, на котором предстоит менять или проверять пароли), выходному файлу и двум утилитам (PsPassword от Марка Русиновича из компании Sysinternals и программе local.exe из комплекта Resource Kit).

Размер комментария в области заголовка ничто не ограничивает. Сюда можно добавить сведения о других важных деталях, например указать автора сценария и номер версии.

Чтение входного файла

Если в сценарии используется входной файл, необходимо написать соответствующий код чтения входного файла. Этот код в PWcheck-change отмечен как метка B. Здесь используется команда For для чтения и разбора каждой записи входного файла. Параметр delims указывает разделитель, с помощью которого сегменты в каждой записи отделяются друг от друга. В данном случае используется запятая. Параметр tokens указывает сегменты (собственно значения), которые нужно получить в каждой записи. PWcheck-change захватывает первые три сегмента, которые присваиваются соответственно переменным Server, AdminName и Password. Параметр usebackq указывает на необходимость учета всех пробелов в полном пути входного файла, заставляя заключать название файла в двойные кавычки.

Код операции или цепочки операций

Сценарии часто создаются для автоматизации рутинных задач. В коде сценария обычно встречается секция, которая выполняет определенную операцию или цепочки операций для решения поставленной задачи. Неудивительно, что в PWcheck-change включен код, выполняющий цепочку операций (см. метку D). Но обратите внимание, что самая первая операция цепочки — эхо-тест командой ping, а не проверка и не смена пароля. Некоторые утилиты имеют продолжительные тайм-ауты, когда сервер, к которому происходит обращение, выключен. Поэтому лучше сначала проверить, включен ли сервер, а для этого и используется ping.

Команда Ping находится внутри команды For. Если перед этим For использовался для разбора входного файла, то теперь For нужен для разбора вывода команды Ping — выполняется поиск строки Reply. Если строка не находится (сервер отключен), то регистрируется ошибка. Если строка найдена (сервер работает), начинается операция смены или проверки пароля.

Чтобы сменить пароль, PWcheck-change использует утилиту PsPasswd, которая расширяет возможности встроенной команды Net User. Последняя изменяет только пароли локальных учетных записей и пароли в домене, но не умеет изменять локальные пароли на удаленных системах, что должен делать сценарий, когда меняет пароли локальных учетных записей администратора.

PsPasswd умеет менять пароли учетных записей на удаленных системах, но делает это только для одной машины за раз, что очень неудобно, если таких машин много. Таким образом, PWcheck-change вызывает PsPasswd многократно после прочтения информации входного файла с описанием имени и пароля каждого сервера и имени учетной записи администратора.

В режиме проверки PWcheck-change пропускает код, меняющий пароли, и использует команду Net Use и IPC$ для проверки существующего пароля учетной записи администратора. Когда соединение установлено, связка имя пользователя — пароль верна. Если нет — сценарий вызывает код обработки ошибок.

Обработка ошибок

Некоторые части PWcheck-change уже содержат обработку ошибок определенных типов. Но сценарий также содержит код для обработки двух специальных типов ошибок: неверное имя пользователя и некорректные разрешения для доступа к серверу.

Иногда действующий из лучших побуждений, но рассеянный администратор может сменить пароль или переименовать администраторскую учетную запись. Чтобы обнаружить подобный «дрейф пароля», в сценарии используют утилиту local.exe. Она позволяет выяснить, является ли пользователь с заданным именем членом локальной группы Administrators (см. метку E). Если пользователь не входит в группу Administrators, или во входном файле указано неверное имя пользователя, или пользователь на сервере не имеет нужных прав (например, кто-то неправильно изменил имя учетной записи администратора на сервере), сценарий регистрирует сообщение об ошибке, в котором говорится, что учетная запись не найдена. Если имя задано правильно и прав для работы на сервере достаточно, но возникли проблемы иного рода, сценарий рассматривает этот случай как общий сбой и регистрирует сообщение об ошибке PW Check/Change Failure.

Передача информации в файл или на консоль

Практически в каждой секции PWcheck-change использует команду Echo для вывода информации в файл или на консоль (например, о текущей дате и времени, статусе операции — успешной или с ошибкой, результате работы команды и т. д.). Если за командой Echo следует

>>»%Outputfile%»

сценарий записывает информацию в CSV-файл, указанный в области заголовка. Если символ «>>» (символ перенаправления) отсутствует, информация выводится на консоль.

Есть и другие способы переслать данные в файл или другое место, в том числе: создание файла в каталоге общего пользования; добавление информации в существующий файл; создание HTML-файла и загрузка его на Web-сервер; использование почты SMTP и Blat (бесплатная утилита) для отправки сообщения по электронной почте или на пейджер.

Операции очистки

В сценарий нередко включают операции очистки, когда нужно удалить временно созданные файлы и закрыть используемые локальные переменные. Как видно на примере в метке C, PWcheck-change задействует команду Endlocal для закрытия локальных переменных. Данный сценарий не использует временные файлы, поэтому чистящих операций здесь нет.

Я иногда шучу, что тысячи написанных мною сценариев на самом деле представляют собой один-единственный сценарий, в который со временем вносились новые и новые изменения. И в этом есть доля правды. На самом деле многие сценарии состоят из небольшого числа базовых секций, в которых надо соблюдать несколько практических рекомендаций. Во врезке «Лучшие методики написания сценариев» эти рекомендации приведены.

Как настроить и использовать сценарий

Я тестировал PWcheck-change в системах под Windows Server 2003, Windows 2000 Server и Windows NT Server 4.0. Чтобы запустить PWcheck-change, нужно выполнить следующие действия.

  1. Загрузить файл с кодом сценария PWcheck-change с Web-сайта Windows IT Pro.
  2. Загрузить утилиту PsPasswd с Web-сайта Sysinternals (http://www.sysinternals.com/ntw2k/ freeware/pstools.shtml).
  3. Если программа local.exe еще не установлена, скопировать ее из Windows Resource Kit.
  4. Создать входной файл. Включить в него информацию о каждом сервере (имя сервера, имя учетной записи администратора, пароль); данные о каждом сервере должны располагаться в одной строке. В качестве разделителя следует использовать запятую.
  5. В области заголовка сценария нужно настроить путь к входному файлу, выходному файлу, утилите PsPasswd и local.exe.
  6. Протестировать сценарий на нескольких серверах. Во входном файле требуется добавить выключенные серверы или серверы с неверными именами либо с некорректным именем учетной записи администратора и посмотреть, как поведет себя сценарий. Необходимо запустить сценарий в режиме по умолчанию, это режим проверки. Убедившись, что сценарий в этом режиме работает корректно, нужно добавить аргумент — Change и протестировать режим смены пароля. Следует просмотреть журнал работы, в нем должна быть информация об успешных и неудачных операциях, а затем локально зарегистрироваться на серверах и убедиться, что пароли были изменены правильно.
  7. После того как сценарий будет тщательно протестирован, его можно использовать в рабочей среде. Чтобы запускать его в планировщике задач, необходимо создать задачу и в качестве учетной записи указать пользователя, принадлежащего группе Administrators на целевых серверах.
  8. После выполнения проверки или изменения пароля с помощью сценария нужно обеспечить безопасное хранение входного и выходного файлов. Необходимо убедиться, что администраторы сервера имеют доступ к указанным файлам на тот случай, если потребуется срочно узнать имя и пароль административной учетной записи для выполнения локальной регистрации на серверах.

Будьте всегда начеку

В процессе работы порой возникают самые неожиданные ситуации, например блокировка сервера. PWcheck-change позволяет не просто решить внезапно возникшую проблему с паролями, но сделать это быстро, а самое главное — под рукой всегда будет инструмент обслуживания и управления паролями учетных записей администратора на всех серверах.


Графические утилиты против сценариев

Когда несколько лет тому назад я начал писать сценарии, графических утилит было очень немного. А сегодня для управления и мониторинга всего и вся, начиная с Active Directory (AD) и заканчивая разрешениями NTFS, создано огромное количество графических утилит.

Итак, в чем же разница между утилитой с графическим интерфейсом и сценарием? Графическая утилита подобна роскошному автомобилю. Такие автомобили создаются людьми, которые плохо представляют себе специфические требования будущего водителя, поэтому стараются запихнуть в автомобиль все, что только может потребоваться клиенту. И поэтому, хотя автомобиль и напичкан огромным количеством функций, он может быть неуклюж и медлителен. Другое дело — сценарий. Он подобен гоночному болиду, который разработан специально для вас. И хотя никаких особенных излишеств в нем нет, он легок, подвижен и очень быстр.

Подвижность и быстрота — важные качества для системного администратора, поскольку одна из его обязанностей состоит в умении оперативно реагировать и находить решения возникающих проблем. Такое решение может быть связано с необходимостью просмотра определенной версии программного обеспечения в реестре на всех сетевых компьютерах, поиска на диске С всех машин файла с вирусом или быстрого определения членов группы Administrator на всех серверах. Хотя подобные задачи — забава для настоящих создателей сценариев, для производителей GUI-утилит экономически невыгодно предлагать клиентам такие простые, но чрезвычайно важные решения.

Однако в том случае, когда поставленная задача действительно сложна, покупка подходящей графической утилиты может оказаться более простым решением, чем создание сценария. Многие производители таких утилит заинтересованы в усилении функциональности решений на базе сценариев и разрабатывают интерфейс командной строки, который бы обеспечил аналог большинства или всех возможностей графической утилиты. Поэтому при покупке утилиты с графическим интерфейсом рекомендую обратить внимание на возможности ее командного аналога.


Лучшие методики написания сценариев

  1. Размещайте всю конфигурационную информацию в самом начале сценария. В этом случае вам достаточно будет впоследствии внести изменения только в одну секцию сценария, и вероятность ошибки будет сведена к минимуму.
  2. Если по ходу выполнения сценария данные будут записываться в выходной файл несколько раз, следует использовать переменную для описания пути к файлу вместо жесткого кодирования этого пути. Такая практика не только уменьшит вероятность указания неверного файла, но и позволит сэкономить время. Если нужно будет потом поменять путь к файлу, изменения придется вносить только в одно место, что гораздо быстрее и надежнее, чем сканировать весь сценарий в поисках нужной строки.
  3. Облегчите жизнь себе и всем, кто будет работать с вашим сценарием, — напишите подробный комментарий. Не раз случалось так, что я пытался найти автора сценария для объяснений, когда вдруг выяснялось, что это мой собственный сценарий, написанный несколько лет тому назад. Общий способ внесения комментария в WSS — расположить его в Rem-скобках или перед каждой строкой комментария вставить двойное двоеточие (::). В отличие от некоторых других языков сценариев, WSS не разрешает размещать комментарии в той же самой строке, где пишется команда. Комментарии следует размещать перед программным кодом.
  4. Используйте интуитивно понятные имена переменных. Например, если вы задаете переменную идентификатора пользователя, лучше указывать имя UserID, а не Var1. Задание интуитивно понятных имен переменных сделает сценарий более удобным для чтения, ваши коллеги быстрее смогут в нем разобраться, к тому же повторно воспользоваться таким сценарием будет легче.
  5. Располагайте утилиты в каталоге общего пользования, в названии которого нет пробелов. Как только вы начнете создавать сценарии, вы очень быстро выйдете за пределы внутренних команд Windows и станете использовать дополнительные утилиты Microsoft (из состава Resource Kit, Support Tools) и независимых разработчиков. Уследить за местоположением ранее использованных утилит будет крайне трудно.

    Располагать утилиты в каталоге общего назначения очень удобно, так как ссылаться на этот каталог можно будет во всех других сценариях. Однако, если утилиты покупались и на них распространяется лицензионное право, тогда доступ к ним может быть ограничен. Если у вас используется именно такая утилита, сначала нужно убедиться, что доступ к ней санкционирован или имеется многопользовательская лицензия.

    В настоящее время Windows Support Tools и Windows Resource Kits по умолчанию устанавливаются в каталоги, в названии которых есть пробелы. С точки зрения написания сценариев наличие пробелов в пути не рекомендуется. Когда внутри пути, встроенного в команду For, встречаются пробелы, это может привести к появлению ошибок, диагностировать которые очень тяжело. Не поленитесь и измените пути для всех утилит так, чтобы пробелов в них не было.

  6. Всегда сначала тщательно протестируйте свои сценарии в лабораторных условиях, прежде чем запускать их в рабочей среде. Если сценарий просто создает отчеты или выполняет запросы и при этом возникают ошибки, из-за неаккуратно составленного отчета или данных вряд ли произойдет катастрофа. Но если сценарий удаляет файлы или модифицирует настройки систем и делает это с ошибками, разрушения могут быть необратимыми. Хотя неправильное удаление или модификация настроек выполняется при помощи встроенных утилит, «рыхлый» и неоттестированный сценарий может нанести колоссальный ущерб за очень короткое время. Будьте внимательны и тщательно проверяйте сценарии в тестовых условиях, это позволит свести риск внесения непредусмотренных изменений к минимуму.