Любой системный администратор не может обойтись в своей работе без применения скриптов. Причём эти скрипты нужны, прежде всего, самому сисадмину для облегчения его работы. Ведь хороший сисадмин - ленивый сисадмин.
Ему лениво бегать по рабочим местам в офисе, ездить по удалённым офисам, если для выполнения административных задач можно обойтись скриптами, к тому же запускаемыми удалённо с его рабочего места или на рабочих станциях и серверах по расписанию автоматически. Без скриптов спокойная работа настоящего сисадмина невозможна. Не важно, на каком языке написаны эти скрипты. Главное - результат. В качестве примера приведу два полезных скрипта, один из которых написан на VBS, и является файлом с расширением VBS, а второй - с использованием команд командного интерпретатора, и является BAT-файлом. Оба скрипта проверены и успешно работают.
Без скриптов спокойная работа настоящего сисадмина невозможна.
Скрипт 1
Скрипт состоит из отдельных блоков, которые можно использовать как отдельно, так и целиком. Вообще, этот скрипт предназначен для обеспечения работы программы "Учёт и контроль компьютеров в сети" для сбора информации о компьютере. Вот её описание. Рекомендую. Бесплатно, информативно, наглядно. Но в данной статье не это главное. Главное, что это делается не руками, а по расписанию или по нажатию иконки.
О скрипте
Где можно применить этот скрипт? Если вам необходимо что-то выполнить на удалённом компьютере, вне пределов локальной сети, и получить результат по электронной почте, с приложенным файлом или без него, то этот скрипт для вас. Или может быть вам нужно при наступлении какого-либо события на удалённом компьютере из любой точки мира получить на свой адрес письмо-оповещение, или SMS на телефон, если ваш оператор поддерживает передачу SMS по электронной почте. Всё в ваших руках.
Вам может показаться, что код перегружен проверками. Не соглашусь с таким мнением. Всевозможные проверки и обработка ошибок - спокойствие для вас и комфорт для пользователя. Гораздо понятнее получить ваше сообщение об ошибке, чем сообщение, сгенерированное интерпретатором или просто молча неработающий скрипт из-за того, что нет нужного файла.
Что делает этот скрипт?
- Запускает программу для сбора информации
- Запускает архиватор для архивирования результата работы первой программы
- Создаёт письмо и отправляет архив по почте в головной офис, не используя почтовые программы. Как он это делает? Специально для таких целей Microsoft создал для всех пользователей Windows бесплатный облачный транспортный сервис, который на основании данных вашей учётной записи вашего почтового сервера отправляет на ваш почтовый сервер ваше письмо. Работает это практически мгновенно. Ну конечно, если вы не отправляете по почте гигабайтный фильм.
Но это - в общем. На самом деле скрипт ещё делает ряд проверок и обрабатывает возможные ошибки. Что полезного может сисадмин найти в этом скрипте для своих нужд?
- Проверка каталога, откуда запущен сам скрипт
- Проверка наличия конкретного файла
- Проверка наличия конкретного каталога
- Запуск программы с параметрами командной строки
- Удаление конкретного файла в каталоге
- Чтение всего текстового файла
- Вывод содержимого текстового файла на экран силами MsgBox и/или WScript.Echo. Второй способ используется просто для примера, как альтернатива
- Вывод окна сообщения с обработкой нажатой пользователем кнопки выбора действия
- Создание письма:
- Заполнение полей для отправки: "Кому", "От кого", "Тема"
- Заполнение тела письма текстом из текстового файла (конечно, можно указать текст и в самом скрипте, но так более гибко)
- Прикрепление файла к письму (можно и не одного файла, но это уже своими силами, аналогично или в цикле)
- Отправка письма силами скрипта, без использования внешней почтовой программы
Если хоть что-то из перечисленного вас заинтересовало, то тогда этот скрипт для вас. Используйте эти "кирпичики" для написания своих скриптов. Разумеется, и этот скрипт можно упростить или дополнить, всё в ваших руках.
Листинг1
Участники листинга:
- Программа сбора информации: Checkcfg.exe (бесплатная)
- Архиватор командной строки: 7za.exe (бесплатный)
- Текстовый файл unitname.txt содержит три строки:
- "Не ваш Город"
- "Не ваш Офис"
- "Не ваши Имя компьютера или Имя пользователя"
и предназначен для информации пользователя в процессе выполнения скрипта о том, правильно ли он заполнил данные о проверяемом компьютере, а в конечном итоге - для помещения этих строк в тело письма. До начала работы пользователю необходимо заменить строки своими данными.
Разумеется, при автоматической работе скрипта надо оставить только сообщения об ошибках, и то их тоже можно послать себе на почту, они отправятся в любом случае, если есть интернет и открыт соответствующий доступ. А этот доступ открываете вы, так что все будет в порядке.
Остальные пояснения даны в теле скрипта.
------------------------Начало скрипта---------------------- 'Объявляем все переменные только явно: Option Explicit 'Выключаем обработчик ошибок - будем перехватывать их сами. '(На время отладки строку ниже надо закомментировать для просмотра ваших ошибок!) On Error resume next 'Объявляем все переменные. Dim oShell, FSO, Email, File, ReadAllTxtFile, WrkDir1, Answ 'Поехали! Создаём объекты, константы, переменные Set oShell = CreateObject("WScript.Shell") SET FSO = CreateObject("Scripting.FileSystemObject") SET Email = CreateObject("CDO.Message") Const Line = "----------" 'Задаём рабочий каталог. Его же надо указать в иконке для запуска, 'иначе проверка сработает неверно! WrkDir1 = "D:\info" 'Проверка наличия файлов и каталогов: 'Проверка того, что программа стартует из нужного каталога, иначе выход. 'Сравниваем в верхнем регистре. 'Для вывода используем MsgBox с кнопкой OK и заголовком "Ошибка". 'Знак подчёркивания "_" используется для переноса длинных строк, 'исключительно для удобочитаемости скрипта. If UCase(oShell.CurrentDirectory) <> UCase(WrkDir1) Then MsgBox "Программа должна быть установлена"_ & CHR(13) & "в каталог " & WrkDir1 & "!"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If 'Проверка наличия файлов программ, иначе выход If FSO.FileExists(WrkDir1 &? "\Checkcfg.exe") = False Then MsgBox "Нет программы Checkcfg.exe!"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If If FSO.FileExists(WrkDir1 & "\7za.exe") = False Then MsgBox "Нет архиватора 7za.exe!"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If 'Проверка наличия файла с данными для тела письма, иначе выход. If FSO.FileExists(WrkDir1 & "\unitname.txt") = False Then MsgBox "Нет файла UnitName.txt с данными об этом компьютере"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If 'Теперь проверка исходных данных и файлов. 'Спросим, а правильные ли данные в файле для тела письма? Иначе выход. 'Откроем файл с телом письма и прочитаем его целиком в окно пользователю для проверки. Set File = fso.OpenTextFile(WrkDir1 & "\unitname.txt", 1) ReadAllTxtFile = File.ReadAll Answ = MsgBox("Это ваши данные?" & CHR(13) & Line & CHR(13) & ReadAllTxtFile & CHR(13) & Line, vbYesNo) 'Если нажата кнопка "No", то выход. If Answ = vbNo Then MsgBox "Внесите соответствующие изменения в файл"_ & CHR(13) & WrkDir1 & "\unitname.txt"_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If 'Если всё хорошо - запускаем программу для снятия конфигурации. 'True означает, что скрипт не пойдёт дальше, пока программа не отработает и не закроется. If FSO.FileExists(WrkDir1 & "\Checkcfg.ini") and FSO.FolderExists(WrkDir1 & "\DATA") Then oShell.Run WrkDir1 & "\Checkcfg.exe", 1, True End If 'Если же чего-то не хватает - исправим это именно в таком порядке: 'Если нет ini-файла. 'Для вывода используем MsgBox с кнопкой OK и заголовком "Замечание". If FSO.FileExists(WrkDir1 & "\Checkcfg.ini") = False Then MsgBox "Нет ini-файла!"_ & CHR(13) & "Нажмите ОК для запуска Checkcfg.exe."_ & CHR(13) & "Потом ещё раз нажмите ОК."_ & CHR(13) & "Затем я продолжу работу...", vbOkOnly, "Замечание!" oShell.Run WrkDir1 & "\Checkcfg.exe", 1, True End If 'Если ini-файл есть, но нет каталога DATA, программа работать не будет, 'поэтому сначала удалим ini-файл, а затем запустим программу, 'она создаст новый ini-файл и каталог DATA. If FSO.FolderExists(WrkDir1 & "\DATA") = False Then MsgBox "Нет папки DATA!"_ & CHR(13) & "Нажмите ОК для запуска Checkcfg.exe."_ & CHR(13) & "Потом ещё раз нажмите ОК."_ & CHR(13) & "Затем я продолжу работу...", vbOkOnly, "Замечание!" Set File = fso.GetFile(WrkDir1 & "\Checkcfg.ini") File.Delete oShell.Run WrkDir1 & "\Checkcfg.exe", 1, True End If 'Если и после этого ничего не создалось - значит что-то не так! 'В принципе это - перестраховка. Но не лишняя. 'Может быть, у пользователя нет прав на запись в этот каталог. If FSO.FileExists(WrkDir1 & "\Checkcfg.ini") = False Then MsgBox "ПРОБЛЕМА! ini-файл не создан!"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If If FSO.FolderExists(WrkDir1 & "\DATA") = False Then MsgBox "ПРОБЛЕМА! Папка DATA не создана!"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!", vbOkOnly, "Ошибка!" WScript.Quit End If 'Всё хорошо. Программа отработала и создала каталог DATA с файлом внутри. 'Запускаем программу архивации каталога DATA с данными в архив Data1.7z. 'Это удобно, если не знаешь, сколько и каких файлов создалось, 'а нужны все, с любым именем, с любым расширением и без такового. 'Архивируй весь каталог, и нет проблем. 'Обратите внимание - звёздочка "*" одна, без точки! Т.е. и для файлов без расширения. oShell.Run WrkDir1 & "\7za.exe u -y Data1 " & WrkDir1 & "\data\*", 1, True 'Проверка наличия созданного архива. 'Для разнообразия - пример использования WScript.Echo. 'Но здесь нельзя задать заголовок окна и надо использовать скобки. If FSO.FileExists(WrkDir1 & "\Data1.7z") = False Then WScript.Echo ("Архив Data1.7z не создан!"_ & CHR(13) & "Обратитесь к системному администратору."_ & CHR(13) & "Данные не отправлены!") WScript.Quit End If 'Всё получилось! Ошибок нет. Пишем письмо. 'Сначала содержимое всего текстового файла unitname.txt целиком помещаем в тело письма. 'Каждая новая строка файла запишется с новой строки в теле письма. SET File = FSO.OpenTextFile(WrkDir1 & "\unitname.txt") Email.Textbody = File.ReadAll File.Close 'Требование: Ящики должны существовать! Данные, разумеется, подставляйте ваши. 'Они аналогичны вашим данным в настройках почтовой программы. 'Лучше писать от самого себя самому себе - меньше проблем на пересылке. Email.From = "myname@mymail.com" Email.To = "myname@mymail.com" Email.Subject = "PC Configuration" Email.Bodypart.Charset = "koi8-r" 'Цепляем архив к письму. Email.AddAttachment WrkDir1 & "\Data1.7z" 'Готовим данные для транспорта Microsoft (значения констант описаны ниже): Email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 'значение 1 - Send the message using Pickup, например, при использовании локального почтового сервера. 'значение 2 - Send the message using the network, отсылка через сетевое подключение. 'значение 3 - Send the message using the Microsoft Exchange mail submission Uniform Resource Identifier. Email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1 'значение 0 - Perform no authentication, без аутентификации. 'значение 1 - Use the basic (clear text) authentication mechanism, базовая аутентификация. 'значение 2 - Use the NTLM authentication mechanism, аутентификация NTLM. Email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "MyName" Email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "MyPass" Email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.mymail.com" Email.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 Email.Configuration.Fields.Update 'Отправляем письмо! Email.Send 'Покажем пользователю сообщение о завершении работы скрипта, 'и на всякий случай - ещё раз покажем, о ком же он отправил данные. Set File = fso.OpenTextFile(WrkDir1 & "\unitname.txt", 1) ReadAllTxtFile = File.ReadAll MsgBox "Данные о "& CHR(13) & Line & CHR(13) & ReadAllTxtFile & CHR(13) & Line & CHR(13) & "успешно отправлены!"_ & CHR(13) & "Если это не ваши данные,"_ & CHR(13) & "то вы всё сделали не так!"_ & CHR(13) & "Внесите изменения в файл"_ & CHR(13) & WrkDir1 & "\unitname.txt"_ & CHR(13) & "и повторите работу!", vbOkOnly, "Ура! Или нет?" -----------------------Конец скрипта------------------------
Скрипт 2
О скрипте
Иногда необходимо выполнить какие-то регламентные работы с файлами на сети в автоматическом режиме, а рассеянные (назовём их ласково так) пользователи забыли выключить свой компьютер и, более того, оставили открытыми кучу приложений с открытыми файлами и базами данных. В итоге из-за блокировки файлов или баз данных работы не были выполнены со всеми вытекающими возможными последствиями. Что делать? Если слова не помогают - надо действовать! Можно получить список всех включённых компьютеров и выключить их. Легко! Но это не всегда хорошо. Бывает, что некоторые рабочие станции должны работать, не выключаясь на ночь. Если вы знаете самых злостных нарушителей, то лучше проверить только их, и, если они забыли выключить свои компьютеры, выключить только эти компьютеры, причём из педагогических соображений - без сохранения их данных. Это дисциплинирует, поверьте мне. Особенно если узаконить приказом иным документом правило выключать компьютеры на ночь. Тогда пользователи и возразить не смогут - сами виноваты.
На чём основана работа скрипта?
Для скорости работы скрипта компьютер пингуется только одним пингом. Опытным путём выявлено, что для IP4 единственным общим для разных версий Windows признаком ответа работающего компьютера является строка "TTL" в ответе. У выключенных компьютеров её нет. Главная строка скрипта работает по принципу конвейера: результат пинга обрабатывает команда FIND, ищет "TTL" в ответе с игнорированием регистра, а чтобы не "светиться", все направляется в NUL. При обнаружении "TTL" переменная ERRORLEVEL будет равна нулю, что нам и надо. "Гасим" его, нарушителя! Вопрос, чем гасить? В Windows есть штатная команда SHUTDOWN. Но она, как выяснилось, не всегда срабатывает, если открыты программы на компьютере нарушителя. Я использовал утилиту Марка Руссиновича PsShutdown.exe. Это работает. Взять её можно официально и бесплатно отсюда. Работу скрипта по выключению при обнаружении работающего компьютера пишем в лог. Записываются текущие дата, время и фамилия нарушителя.
Листинг 2
-------------------Начало скрипта----------------------- REM Выключает компьютер, если он доступен по сети. REM Внимание! Писать без пробелов между "=". Это вам не VBS! @ECHO OFF REM Запоминаем текущие дату и время: SET StartD=%date% SET StartT=%time% REM Будем писать лог в эту папку текущего каталога и в этот файл: SET FName=logs\log_Shutdown.txt REM Задаём имя компьютера предполагаемого нарушителя. REM Имя укажите нужное вам вместо PC_061. SET Comp1=PC_061 REM Вот она, главная строка-сыщик: PING -n 1 %Comp1% | FIND /I "TTL" > nul REM Если нашли - пишем в лог и выключаем компьютер. if %ERRORLEVEL%==0 ( ECHO !!!-- Компьютер НЕ БЫЛ выключен %StartD% в %StartT% --!!! >> %FName% ECHO Starting Shutdown… >> %FName% REM Ну и неминуемая команда на выключение. Путь, конечно же, укажите свой. D:\Test\PsShutdown -s -f -t 0 \\PC_061 ) ---------------------------Конец скрипта--------------------
Просто и надёжно.
Моя рекомендация
Если вы хотите серьёзно заняться написанием своих VBS и WSH скриптов для администрирования, очень рекомендую вам пройти обучение на курсах Microsoft 2433B "Scripting Microsoft Windows Management Instrumentation" и 2439A "Microsoft Visual Basic Scripting Edition and Microsoft Windows Script Host Essentials". Именно в таком порядке. Для настоящего сисадмина не будет минусом то, что все материалы и задания во время обучения - на английском языке. Качество обучения высокое, т.к. это - официальные курсы Microsoft. Говорю так потому, что сам в прошлом году успешно окончил эти курсы.
Александр РЫКУНИН
Комментарии
О, полезная статья!
К редакции: когда спойлеры появятся? Или и дальше будем кодить по тексту?
У смысле, кодить по тексту?
Не цепляйтесь к словам. Вы прекрасно знаете, для чего служит спойлер.
Наберите Lurkmore + спойлер. Ой, некогда стебаться, пора на работу! )))
mike, честно говоря, пока особой необходимости в них не вижу, в частности, в данной статье.
Зря. См., например, Ubuntu.ru. Тоже на Друпале.
Вадим, не разобралась, как сделать так, чтобы скрипт в статье не был обрезан.( Может Алекс сможет поправить?