Windows Script Host для Windows 2000/XP

Андрей Владимирович Попов

Глава 11. Применение сценариев WSH для администрирования Windows ХР

Одним из основных назначений сценариев WSH является, в конечном счете, автоматизация работы администраторов компьютерных систем, построенных на базе Windows. В данной главе мы рассмотрим примеры сценариев, которые могут быть полезны администраторам в их повседневной работе, например, при создании сценариев регистрации для пользователей.

Особое внимание мы уделим вопросам применения в сценариях WSH таких мощных современных технологий Microsoft, как ADSI — Active Directory Service Interface и WMI — Windows Management Instrumentation, которые позволяют автоматизировать процесс администрирования как отдельной рабочей станции, так и крупной корпоративной информационной системы в целом. Отметим, что в данной книге не ставится задача более или менее полного раскрытия этих технологий, а лишь кратко описываются их основные возможности и приводятся примеры сценариев для их реализации.

Использование службы каталогов Active Directory Service Interface (ADSI)

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

Что касается компьютерных сетей (локальных или глобальных), здесь также уместно говорить о каталогах, содержащих объекты разных типов: зарегистрированные пользователи, доступные сетевые принтеры и очереди печати и т.д. Для пользователей сети важно уметь находить и использовать такие объекты (а их в крупной сети может быть огромное количество), администраторы же сети должны поддерживать эти объекты в работоспособном состоянии. Под службой каталога (directory service) понимается та часть распределенной компьютерной системы (компьютерной сети), которая предоставляет средства для поиска и использования имеющихся сетевых ресурсов. Другими словами, служба каталога — это единое образование, объединяющее данные об объектах сети и совокупность служб, осуществляющих манипуляцию этими данными.

В гетерогенной (неоднородной) компьютерной сети могут одновременно функционировать несколько различных служб каталогов, например, NetWare Bindery для Novell Netware 3.x, NDS для Novell NetWare 4.x/5.x, Windows Directory Service для Windows NT 4.0 или Active Directory для Windows 2000. Естественно, для прямого доступа к разным службам каталогов приходится использовать разные инструментальные средства, что усложняет процесс администрирования сети в целом. Для решения этой проблемы можно применить технологию ADSI — Active Directory Service Interface фирмы Microsoft, которая предоставляет набор объектов ActiveX, обеспечивающих единообразный, не зависящий от конкретного сетевого протокола, доступ к функциям различных каталогов.

!

Объекты ADSI включены в операционные системы Windows ХР/2000, а также могут быть установлены в более ранних версиях, для чего их нужно скачать с сервера Microsoft (http://www.microsoft.com/NTWorkstation/downloads/Other/ADSI25.asp).

Для того чтобы находить объекты в каталоге по их именам, необходимо определить для этого каталога пространство имен (namespace). Скажем, файлы на жестком диске находятся в пространстве имен файловой системы. Уникальное имя файла определяется расположением этого файла в пространстве имен, например:

С:\Windows\Command\command.com

Пространство имен службы каталогов также предназначено для нахождения объекта по его уникальному имени, которое обычно определяется расположением этого объекта в каталоге, где он ищется. Разные службы каталогов используют различные виды имен для объектов, которые они содержат. ADSI определяет соглашение для имен, с помощью которых можно однозначно идентифицировать любой объект в гетерогенной сетевой среде. Такие имена называются строками связывания (binding string) или строками ADsPath и состоят из двух частей. Первая часть имени определяет, к какой именно службе каталогов (или, другими словами, к какому именно провайдеру ADSI) мы обращаемся, например:

• "LDAP://" — для службы каталогов, созданной на основе протокола LDAP (Lightweight Directory Access Protocol), в том числе для Active Directory в Windows 2000;

• "WinNT://" — для службы каталогов в сети Windows NT 4.0 или на локальной рабочей станции Windows ХР/2000;

• "NDS://" — для службы каталогов NetWare NDS (Novell Directory Service);

• "NWCOMPAT://" — для службы каталогов NetWare Bindery.

Вторая часть строки ADsPath определяет расположение объекта в конкретном каталоге. Приведем несколько примеров полных строк ADsPath:

"LDAP://ldapsrv1/CN=Kazakov,DC=DEV,DO=MSFT, DC-COM"
"WinNT://Domain1/Server1,Computer"
"WinNT://Domain1/Kazakov"
"NDS://TreeNW/0=SB/CN=Kazakov"
"NWCOMPAT://NWServer/MyNw3xPrinter"

В этом разделе мы подробно рассмотрим несколько простых сценариев, использующих объекты ADSI для автоматизации некоторых распространенных задач администрирования на отдельной рабочей станции с операционной системой Windows ХР; поняв принцип их работы, вы без труда сможете написать аналогичные сценарии для локальной сети, которая функционирует под управлением Active Directory или контроллера домена с Windows NT 4.0 (множество подобных примеров приведено в [18]).

Напомним, что на выделенном компьютере с Windows ХР имеется база данных, содержащая информацию обо всех локальных пользователях этого компьютера. Пользователи компьютера определяются своими атрибутами (имя регистрации, полное имя, пароль и т.п.) и могут объединяться в группы. Ниже мы приведем примеры сценариев WSH, с помощью которых можно:

• получить список имеющихся в локальной сети доменов;

• получить список всех групп, определенных на компьютере;

• добавить и удалить пользователя компьютера;

• определить всех пользователей заданной группы или все группы, в которые входит определенный пользователь;

• просмотреть атрибуты пользователя и изменить его пароль.

Для получения более полной информации по технологии ADSI следует обратиться к документации Microsoft или специальной литературе (см. введение).

Связывание с нужным объектом каталога

Первым шагом для доступа к пространству имен любого каталога в целях получения информации о его объектах или изменения свойств этих объектов является связывание (binding) с нужным объектом ADSI.

Рассмотрим вначале, каким образом формируется строка связывания для доступа к объектам отдельной рабочей станции с операционной системой Windows ХР. В общем виде эта строка имеет следующий формат:

"WinNT:[//ComputerName[/ObjectName[, className]]]]"

Здесь параметр ComputerName задает имя компьютера; ObjectName — имя объекта (это может быть имя группы, пользователя, принтера, сервиса и т. п.); className — класс объекта. Возможными значениями параметра className являются, например, group (группа пользователей), user (пользователь), printer (принтер) или service (сервис Windows ХР).

Указав в качестве строки ADsPath просто "WinNT:", можно выполнить связывание с корневым объектом-контейнером, содержащим все остальные объекты службы каталога.

Приведем несколько примеров строк связывания для доступа к различным объектам компьютера Windows ХР (табл. 11.1).


Таблица 11.1. Варианты строк связывания на компьютере Windows ХР

Строка ADsPath Описание
"WinNT:" Строка для связывания с корневым объектом пространства имен
"WinNT://404_Popov" Строка для связывания с компьютером 404_Popov
"WinNT://404_Popov/Popov,user" Строка для связывания с пользователем Popov компьютера 404_Popov
"WinNT://404_Popov/BankUsers, group" Строка для связывания с группой BankUsers на компьютере 404_Popov

Для того чтобы из сценария WSH использовать объект ADSI, соответствующий сформированной строке связывания, необходимо применить функцию GetObject языка JScript, которая возвращает ссылку на объект ActiveX, находящийся во внешнем каталоге. Например:

var NameSpaceObj = GetObject("WinNT:");
var ComputerObj = GetObject("WinNT://404_Popov");
var UserObj = GetObject("WinNT://404_Popov/Popov,user");
var GroupObj = GetObject("WinNT://404_Popov/BankUsers, group");
!

Во всех рассмотренных ранее сценариях для создания объектов ActiveX мы пользовались методами CreateObject и GetObject объекта WScript или объектом ActiveXObject языка JScript. Для связывания же с объектом ADSI нужно использовать именно функцию GetObject языка JScript (или VBScript)!

Перейдем теперь к рассмотрению конкретных примеров сценариев, использующих объекты ADSI.

Список всех доступных доменов в локальной сети

В листинге 11.1 приведен JScript-сценарий ListDomains.js, в котором создается список всех доменов, доступных в сети (рис. 11.1)

Рис. 11.1. Список всех имеющихся в сети доменов


В рассматриваемом сценарии производятся следующие действия. Сначала создается корневой объект NameSpaceObj класса Namespace для провайдера Windows NT, который содержит все остальные объекты службы каталога:

//Связываемся с корневым объектом Namespace
NameSpaceObj = GetObject("WinNT:");

Затем с помощью свойства Filter из коллекции NameSpaceObj выделяются все содержащиеся в ней объекты класса Domain и создается экземпляр объекта Enumerator (переменная е) для доступа к элементам коллекции NameSpaceObj:

//Устанавливаем фильтр для выделения объектов-доменов
NameSpaceObj.Filter = Array("domain");
//Создаем объект Enumerator для доступа к коллекции NameSpaceObj
E=new Enumerator(NameSpaceObj);

Список доменов будет храниться в переменной List, которая инициализируется следующим образом:

List="Bce доступные домены в сети:\n\n";

В цикле while выполняется перебор всех элементов коллекции, которые являются объектами класса Domain; название домена, хранящееся в свойстве Name, добавляется (вместе с символом разрыва строки) в переменную List:

while (!E.atEnd()) {
 //Извлекаем текущий элемент коллекции (объект класса Domain)
 DomObj=Е.item();
 //Формируем строку с именами доменов
 List+=DomObj.Name+"\n";
 //Переходим к следующему элементу коллекции
 E.moveNext();
}

Сформированная таким образом переменная List выводится на экран с помощью метода Echo() объекта WScript:

WScript.Echo(List);
Листинг 11.1. Вывод на экран списка всех доменов локальной сети

Создание пользователя и группы на рабочей станции

В сценарии AddUser.js, который приведен в листинге 11.2, для создания нового пользователя на рабочей станции выполняются следующие шаги. Во-первых, производится связывание с нужным компьютером (в нашем примере это рабочая станция с именем 404_Popov), т.е. создается экземпляр ComputerObj объекта Computer:

ComputerObj = GetObject("WinNT://404_Popov");

Во-вторых, создается экземпляр UserObj объекта User для нового пользователя. Для этого используется метод Create() объекта Computer; в качестве параметров этого метода указывается имя класса "user" и имя создаваемого пользователя (в нашем примере это имя хранится в переменной UserStr):

UserObj=ComputerObj.Create("user", UserStr);
!

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

Для созданного пользователя в свойство Description мы помещаем текст описания:

UserObj.Description="Этот пользователь создан из сценария WSH";

Для сохранения информации о новом пользователе в базе данных пользователей вызывается метод SetInfo() объекта User:

UserObj.SetInfo();
Листинг 11.2. Создание нового локального пользователя на рабочей станции

Группа на рабочей станции создается аналогичным образом (листинг 11.3). 

Листинг 11.3. Создание новой локальной группы на рабочей станции

Вывод информации о пользователе и смена его пароля

В листинге 11.4 приведен сценарий UserInfo.js, в котором выводится на экран информация о созданном в сценарии AddUser.js пользователе XUser (рис. 11.2).

Рис. 11.2. Информация о локальном пользователе XUser


Для получения этой информации мы производим связывание с нужным пользователем, т.е. создаем экземпляр UserObj объекта User и читаем данные из полей этого объекта:

//Связываемся с пользователем XUser компьютера 404_Popov
UserObj=GetObject("WinNT://404_Popov/XUser, user");
//Формируем строку с информацией о пользователе
SInfо="Информация о пользователе XUser:\n";
SInfо+="Имя: "+UserObj.Name+"\n";
SInfо+="Описание: "+UserObj.Description+"\n";
//Выводим сформированную строку на экран
WScript.Echo(SInfo);

После этого в сценарии выдается запрос на изменение пароля пользователя XUser. Для этого мы используем метод Popup() объекта WshShell:

//Создаем объект WshShell
WshShell=WScript.CreateObject("WScript.Shell");
//Запрос на изменение пароля
Res=WshShell.Popup("Изменить пароль у XUser?", 0, "Администрирование пользователей", vbQuestion+vbYesNo);

В случае утвердительного ответа пароль изменяется с помощью метода SetPassword() объекта User, после чего все произведенные изменения сохраняются на рабочей станции с помощью метода SetInfo():

if (Res==vbYes) {
 //Нажата кнопка "Да"
 //Устанавливаем новый пароль
 UserObj.SetPassword("NewPassword");
 //Сохраняем сделанные изменения
 UserObj.SetInfо();
 WScript.Echo("Пароль был изменен");
}
Листинг 11.4. Вывод информации о пользователе компьютера и смена его пароля

Удаление пользователя и группы на рабочей станции  

Для удаления созданных с помощью сценариев AddUser.js и AddGroup.js пользователя XUser и группы XGroup мы создадим сценарий DelUserAndGroup.js, который представлен в листинге 11.5.

!

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

В принципе, удалить пользователя и группу так же просто, как и создать — нужно связаться с объектом Computer:

ComputerObj = GetObject("WinNT://404_Popov");

и вызвать метод Delete(), указав в качестве первого параметра класс объекта, который мы хотим удалить, и в качестве второго параметра — имя этого объекта:

//Удаляем пользователя
ComputerObj.Delete("user", UserStr);

Однако здесь могут возникнуть ошибки (например, мы не запускали предварительно сценарий AddUser.js и у нас на компьютере не зарегистрирован пользователь, которого мы хотим удалить). Поэтому в сценарии DelUserAndGroup.js предусмотрена обработка исключительных ситуаций с помощью конструкции try…catch:

IsError=false;
try {
 //Удаляем пользователя
 ComputerObj.Delete("user", UserStr);
} catch (e) { //Обрабатываем возможные ошибки
 if (e != 0) {
  //Выводим сообщение об ошибке
 IsError=true;
  Mess="Ошибка при удалении пользователя "+UserStr+"\nКод ошибки: " + е.number+"\nОписание: "+е.description;
  WshShell.Popup(Mess, 0, "Удаление пользователя", vbCritical);
 }
}

Как мы видим, если при вызове метода Delete() произойдет какая-либо ошибка, значение переменной IsError станет равным true, а на экран с помощью метода Popup() объекта WshShell выведется соответствующее сообщение (рис. 11.3).

Рис. 11.3. Сообщение, формируемое при попытке удаления несуществующего пользователя


Если же удаление прошло успешно (значение переменной IsError равно false), то на экран также выведется соответствующее диалоговое окно (рис. 11.4):

if (!IsError) { //Все в порядке
 Mess="Пользователь."+UserStr+" удален";
 WshShell.Popup(Mess, 0, "Удаление пользователя", vbInformation);
}

Рис. 11.4. Сообщение об удачном удалении пользователя


Листинг 11.5. Удаление пользователя и группы на рабочей станции

Список всех групп на рабочей станции

Принцип формирования списка всех групп рабочей станции остается тем же, что и для рассмотренного выше списка всех доступных доменов локальной сети, однако первоначальное связывание нужно производить не с корневым объектом класса Namespace, а с нужным объектом класса Computer.

В приведенном в листинге 11.6 сценарии ListAllGroups.js для связывания с компьютером 404_Popov мы создаем объект-контейнер ComputerObj, в котором содержатся все объекты рабочей станции 404_Popov:

//Связываемся с компьютером 404_Popov
ComputerObj = GetObject("WinNT://404_Popov");

Затем в сценарии создается объект Enumerator для доступа к элементам коллекции ComputerObj и инициализируется переменная SList, в которой будет храниться список всех локальных групп рабочей станции:

//Создание объекта Enumerator для доступа к коллекции ComputerObj
E=new Enumerator(ComputerObj);
SList="Ha компьютере 404_Popov созданы группы:\n";

После этого в цикле while из коллекции ComputerObj выбираются лишь объекты класса Group, т.е. те объекты, у которых в поле Class записана строка "Group"; в SList заносятся названия групп из поля Name:

while (!E.atEnd()) {
 //Извлекаем текущий элемент коллекции
 GroupObj=E.item();
 //Выделение объектов класса Group
 if (GroupObj.Class == "Group")
  //Формируем строку с именами групп
  SList+=GroupObj.Name+"\n";
 //Переход к следующему элементу коллекции
 E.moveNext();
}

Рис. 11.5. Список всех локальных групп, определенных на рабочей станции


После окончания цикла сформированная строка выводится на экран (см. рис. 11.5):

//Выводим информацию на экран
WScript.Echo(SList);
Листинг 11.6. Вывод на экран имен всех локальных групп заданной рабочей станции

Список всех пользователей в группе

В листинге 11.7 приведен сценарий ListUsers.js, в котором формируется список всех пользователей, входящих в группу "Пользователи" на компьютере 404_Popov.

Для связывания с группой "Пользователи" рабочей станции 404_Popov создается объект GroupObj; коллекция пользователей этой группы формируется с помощью метода Members() объекта Group:

//Связываемся с группой Пользователи компьютера 404_Popov
GroupObj=GetObject("WinNT://404_Ророv/Пользователи,group");
//Создание объекта Enumerator для доступа к коллекции пользователей
E=new Enumerator(GroupObj.Members());

После инициализации переменной SList мы обрабатываем в цикле while все элементы полученной коллекции; на каждом шаге цикла к переменной SList добавляется имя текущего пользователя (поле Name в объекте user — текущем элементе коллекции):

SList="Bce пользователи группы Пользователи на компьютере 404_Popov:\n";
//Цикл по всем элементам коллекции пользователей
while (!E.atEnd()) {
 //Извлечение элемента коллекции класса User
 UserObj=Е.item();
 //Формируем строку с именами пользователей
 SList+=UserObj.Name+"\n";
 //Переходим к следующему элементу коллекции
 E.moveNext();
}

После выхода из цикла сформированная строка SList выводится на экран (рис. 11.6):

//Выводим информацию на экран
WScript.Echo(SList);

Рис. 11.6. Список всех пользователей заданной группы


Листинг 11.7. Вывод на экран имен всех пользователей заданной группы

Список всех групп, в которые входит пользователь 

В сценарии ListGroups.js, который представлен в листинге 11.8, на экран выводятся названия всех локальных групп, в которые входит пользователь Popov на рабочей станции 404_Popov (рис. 11.7).

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


Для создания коллекции групп, членом которых является пользователь, нужно выполнить связывание с нужным пользователем, т.е. создать экземпляр объекта User и воспользоваться методом Groups() этого объекта:

//Связывание с пользователем Popov компьютера
404_Popov UserObj = GetObject("WinNT://404_Popov/Popov");
//Создание объекта Enumerator для доступа к коллекции групп пользователя
E=new Enumerator(UserObj.Groups());

Как и в предыдущих примерах, после инициализации переменной SList в цикле while происходит перебор всех элементов полученной коллекции:

Slist="Пользователь Popov входит в группы: \n";
//Цикл по всем элементам коллекции групп
while (!Е.atEnd()) {
 //Извлекаем элемент коллекции класса Group
 GroupObj=Е.item();
 //Формируем строку с названиями групп
 SList+=GroupObj.Name+"\n";
 //Переходим к следующему элементу коллекции
 E.moveNext();
}

Как мы видим, название групп хранится в свойстве Name объекта Group.

Сформированная строка SList выводится на экран, как обычно, с помощью метода Echo() объекта WScript:

//Вывод информации на экран
WScript.Echo(SList);
Листинг 11.8. Вывод на экран названия всех групп, членом которых является заданный пользователь

Создание сценариев включения/выключения и входа/выхода 

Напомним, что в Windows XP/2000/NT для настройки среды пользователя используются профили (локальные и серверные), в состав которых входят все настраиваемые пользователем параметры: язык и региональные настройки, настройка мыши и звуковых сигналов, подключаемые сетевые диски и принтеры и т.д. Профили, сохраняемые на сервере, обеспечивают пользователям одну и ту же рабочую среду вне зависимости от того, с какого компьютера (под управлением Windows) зарегистрировался пользователь. Создание и поддержание профилей пользователей описываются практически в любой книге по администрированию Windows и здесь рассматриваться не будут.

Начиная с Windows NT, для настройки среды пользователей, кроме профилей, применяются сценарии входа (сценарии регистрации) — сценарии WSH, командные или исполняемые файлы, которые запускаются на машине пользователя каждый раз при его регистрации в сети или на локальной рабочей станции. Это позволяет администратору задавать только некоторые параметры среды пользователя, не вмешиваясь в остальные настройки; кроме этого, сценарии входа легче создавать и поддерживать, чем профили.

В Windows ХР/2000 для объектов групповой политики можно дополнительно задавать сценарии следующих типов.

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

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

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

Сценарии выключения, которые автоматически выполняются при завершении работы Windows.

Для простоты проверки примеров мы далее будем рассматривать сценарии включения/выключения и входа/выхода, которые хранятся на локальной рабочей станции, работающей под управлением Windows ХР. Ниже будет подробно описано, в каких специальных папках нужно сохранять сценарии того или иного вида и каким образом происходит подключение этих сценариев. Для использования сценариев включения/выключения и входа/выхода в сети со службой каталогов Active Directory нужно просто перенести сценарии в соответствующие папки на контроллере домена и воспользоваться оснасткой Active Directory — пользователи и компьютеры (Active Directory — users and computers) консоли управления MMC для назначения этих сценариев соответствующим объектам групповой политики.

Сценарии, выполняемые при загрузке операционной системы 

Сценарии включения/выключения, как и сценарии входа/выхода групповой политики, подключаются с помощью оснастки Групповая политика (Group Policy) в MMC. Процесс добавления оснастки Групповая политика (Group Policy) для локальной рабочей станции был подробно описан в разд. "Блокировка локальных и удаленных сценариев WSH. Пример административного шаблона" главы 4 (рис. 11.8).

Рис. 11.8. Мастер групповой политики


Для того чтобы подключить определенный сценарий включения, нужно выделить раздел Конфигурация компьютера|Конфигурация Windows|Сценарии (запуск/завершение) (Computer Configuration | Windows Configuration|Scripts (Startup/Shutdown)) и выбрать свойство Автозагрузка (Startup), после чего будет выведено диалоговое окно Свойства: Автозагрузка (Properties: Startup) (рис. 11.9).

Рис. 11.9. Список установленных сценариев включения


Для добавления нового сценария нужно нажать кнопку Добавить (Add) и в диалоговом окне Добавление сценария (Adding script) указать имя нужного файла (для этого можно воспользоваться кнопкой Обзор (Browse)) и, в случае необходимости, параметры сценария (рис. 11.10).

Отметим, что по умолчанию сценарии включения хранятся в каталоге %SystemRoot%\System32\GroupPolicy\Machine\Scripts\Startup.


Рис. 11.10. Имя и параметры сценария включения 

Сценарии, выполняемые при завершении работы операционной системы

Для подключения сценариев выключения нужно выбрать свойство Завершение работы (Shutdown) в разделе Сценарии (запуск/завершение) (Scripts (Startup/Shutdown)), после чего будет выведено диалоговое окно Свойства: Завершение работы (Properties: Shutdown) (рис. 11.11).

Рис. 11.11. Список установленных сценариев выключения


Как и в предыдущем случае, для добавления нового сценария нужно нажать кнопку Добавить (Add) и в диалоговом окне Добавление сценария (Adding script) указать имя нужного файла (по умолчанию сценарии выключения хранятся в каталоге %SystemRoot%\System32\GroupPolicy\Machine\Scripts\Shutdown) и параметры сценария.

Сценарии входа для всех локальных пользователей

Сценарии входа групповой политики подключаются в разделе Конфигурация пользователя|Конфигурация Windows|Сценарии (вход/выход из системы) (User Configuration|Windows Configuration|Scripts (Logon/Logoff)). В этом разделе нужно выбрать свойство Вход в систему (Logon), после чего будет выведено диалоговое окно Свойства: Вход в систему (Properties: Logon) (рис. 11.12).

Для добавления нового сценария входа нужно нажать кнопку Добавить (Add) и в диалоговом окне Добавление сценария (Adding script) указать имя нужного файла (по умолчанию сценарии выключения хранятся в каталоге %SystemRoot%\System32\GroupPolicy\User\Scripts\Logon) и параметры сценария.

Рис. 11.12. Список установленных сценариев входа

Сценарий выхода для всех локальных пользователей

Для подключения сценариев выхода нужно выбрать свойство Выход из системы (Logoff) в разделе Сценарии (вход/выход из системы) (Scripts (Logon/Logoff)), после чего будет выведено диалоговое окно Свойства: Выход из системы (Properties: Logoff) (рис. 11.13).

Для добавления нового сценария нужно нажать кнопку Добавить (Add) и в диалоговом окне Добавление сценария (Adding script) указать имя нужного файла (по умолчанию сценарии выхода хранятся в каталоге %SystemRoot%\System32\GroupPolicy\User\Scripts\Logoff) и параметры сценария.

Рис. 11.13. Список установленных сценариев выхода

Сценарий входа для одного пользователя 

Сценарии входа для отдельных пользователей назначаются с помощью оснастки Локальные пользователи и группы (Local users and groups).

!

В Windows NT для этого использовался Диспетчер пользователей (User Manager for Domain).

Для добавления этой оснастки в консоли ММС выберем пункт Добавить или удалить оснастку (Add/Remove Snap-in) в меню Консоль (Console) и нажмем кнопку Добавить (Add). В появившемся списке всех имеющихся оснасток нужно выбрать пункт Локальные пользователи и группы (Local users and groups) и нажать кнопку Добавить (Add). После этого появится диалоговое окно, в котором нужно указать, что выбранная оснастка будет управлять локальным компьютером, и нажать кнопку Готово (Finish) (рис. 11.14).

Рис. 11.14. Выбор компьютера, которым будет управлять оснастка Локальные пользователи и группы


Никаких других оснасток в окно консоли мы добавлять не будем, поэтому нажимаем кнопку Закрыть (Close) в списке оснасток и кнопку OK в окне добавления/удаления оснасток. После этого мы можем в окне консоли просматривать список локальных пользователей компьютера и изменять их свойства (рис. 11.15).

Рис. 11.15. Список пользователей локального компьютера


Для назначения пользователю сценария входа нужно выбрать этого пользователя (например, Popov) в списке и перейти на вкладку Профиль (Profile) в диалоговом окне со свойствами пользователя. Имя сценария входа вводится в поле Сценарий входа (Logon Script) этого окна (рис. 11.16).

Рис. 11.16. Настройки профиля пользователя


Путь к сценарию входа нужно указывать относительно каталога %SystemRoot%\System32\Repl\Import\Scripts. Если, скажем, сценарий scr99.bat для пользователя Popov находится в каталоге с полным именем F:\Windows\System32\Repl\Import\Scripts\Script99, то в качестве пути к сценарию входа нужно указать \Script99\scr99.bat.

Примеры сценариев входа/выхода 

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

Подключение сетевых дисков и синхронизация времени при регистрации пользователей 

Часто сценарии входа используются для подключения дисков и портов принтера к сетевым ресурсам, а также для синхронизации системного времени пользовательских компьютеров с системным временем определенного сервера (это необходимо, например, для файл-серверных банковских систем, работающих в реальном времени). Конечно, для этих целей можно написать сценарий WSH, однако в подобных случаях проще ограничиться обычным командным (пакетным) файлом. Отметим, что в пакетных файлах можно использовать различные утилиты командной строки из пакетов Windows NT/2000/XP Resource Kit, с помощью которых многие задачи можно решить наиболее быстрым и простым способом. В качестве примера упомянем лишь одну полезную команду IFMEMBER, которая позволяет, не прибегая к помощи ADSI, проверить принадлежность пользователя, выполняющего регистрацию, к определенной группе.

Замечание:   Желающим больше узнать о возможностях пакетных файлов в Windows и командах, которые в них используются, можно порекомендовать мою предыдущую книгу [8].

Предположим, что при регистрации определенного пользователя нам нужно произвести следующие действия:

1. Синхронизировать системное время клиентской рабочей станции с системным временем на сервере Server1.

2. Подключить диск М: к сетевому ресурсу \\Server1\Letters.

3. Предоставить каталог C:\TEXT на клиентском компьютере в общее пользование с именем BOOKS.

Для этого пользователю в качестве сценария регистрации можно назначить командный файл Logon.bat, который состоит (вместе с комментариями) всего из шести строк (листинг 11.9). 

Листинг 11.9. Пример командного файла-сценария входа

В первой строке файла Logon.bat мы отключаем режим дублирования команд на экране:

@ЕСНО OFF

Синхронизация времени с сервером \\Server1 производится с помощью ключа /SET в команде NET TIME:

NET TIME \\Server1 /SET

Сетевой диск подключается командой NET USE:

NET USE M: \\Server1\Letters /PERSISTENT:NO

Ключ /PERSISTENT:NO в команде NET USE нужен для создания временных подключений (не сохраняющихся после завершения сеанса пользователя). Если бы подключения были постоянными (/PERSISTENT:YES), то при следующем входе пользователя в систему возникла бы ошибка (повторное использование уже имеющегося подключения).

Наконец, папка C:\TEXT предоставляется в общее пользование командой NET SHARE:

NET SHARE MyTxt=C:\TEXT

Интерактивный выбор программ автозагрузки

Как известно, в подменю Программы (Programs) стартового меню Windows имеется пункт Автозагрузка (Startup), в который можно поместить ярлыки тех программ, которые должны быть автоматически запущены при регистрации пользователя в системе. Однако в процессе загрузки своего профиля пользователь не имеет возможности запустить только какие-либо определенные программы из папки автозагрузки — можно либо запустить все программы, либо не запускать ни одной (для этого необходимо в процессе регистрации в системе удерживать нажатой клавишу <Shift>).

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

Начнем мы с того, что создадим в каталоге %SystemDrive%\Documents and Settings\All Users\Главное меню, в котором хранятся ярлыки программ из стартового меню для всех пользователей, папку Выборочная автозагрузка и поместим туда ярлыки для нужных приложений (рис. 11.17).

После этого ярлыки из обычной папки Автозагрузка нужно убрать. Рассмотрим теперь алгоритм работы сценария входа Logon.js.

Вначале нужно определить путь к папке выборочной автозагрузки (переменная PathStartup). Для этого мы воспользуемся объектом WshSpecialFolders:

//Создаем объект WshShell
WshShell=WScript.CreateObject("Wscript.Shell");
//Создаем объект WshSpecialFolders
WshFldrs=WshShell.SpecialFolders;
//Определяем путь к папке выборочной автозагрузки
PathStartup=WshFldrs.item("AllUsersStartMenu")+"\\Выборочная автозагрузка\\";

Рис. 11.17. Новая папка Выборочная автозагрузка


Зная путь к нужной папке, мы формируем коллекцию всех файлов, которые находятся в ней (переменная Files):

//Создаем объект FileSystemObject
FSO=WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект Folder для папки выборочной автозагрузки
Folder=FSO.GetFolder(PathStartup);
//Создаем коллекцию файлов каталога выборочной автозагрузки
Files=new Enumerator(Folder.Files);

После этого мы выводим на экран диалоговое окно с вопросом, нужно ли запустить программы из папки автозагрузки в пакетном режиме, т.е. все сразу (рис. 11.18).

Рис. 11.18. Выбор режима автозагрузки программ (пакетный или интерактивный)


В зависимости от нажатой в диалоговом окне кнопки мы присваиваем логическое значение переменной IsRunAll, определяющей режим автозагрузки программ (если IsRunAll равно false, то для каждой программы будет выдаваться запрос на ее запуск, в противном случае все программы запускаются без предупреждения):

//Выводим запрос на запуск сразу всех программ
Res=WshShell.Popup("Запустить сразу все программы?", 0,
 "Выборочная автозагрузка", vbQuestion+vbYesNo);
//Определяем, нажата ли кнопка "Да"
IsRunAll=(Res==vbYes);

Далее в цикле while производится перебор всех файлов из коллекции Files; переменная File соответствует текущему файлу в коллекции:

//Цикл по всем файлам каталога выборочной автозагрузки
while (!Files.atEnd()) {
 //Создаем объект File для текущего элемента коллекции
 File=Files.item();
 //Переходим к следующему файлу в коллекции
 Files.moveNext();
}

Если ранее был выбран интерактивный режим запуска программ (переменная IsRunAll равна false), то мы выводим запрос на запуск текущего файла (рис. 11.19):

//Обнуляем переменную Res Res=0;
if (!IsRunAll) //Программы нужно запускать по одной
 //Выводим запрос на запуск одной программы
 Res=WshShell.Popup("Запустить "+File.Name+"?", 0, "Выборочная автозагрузка", vbQuestion+vbYesNo);

Рис. 11.19. Запрос на запуск одной программы из папки автозагрузки


Если пользователь решил запустить программу (переменная Res равна vbYes) или программы запускаются в пакетном режиме, то мы запускаем текущую программу в минимизированном окне с помощью метода Run объекта WshShell:

if ((IsRunAll) || (Res=vbYes))
 //Запускаем текущую программу в минимизированном окне
 WshShell.Run("\""+File.Path+" \"", vbMinimizedFocus);

Так как в полном имени запускаемой программы могут быть пробелы, это имя нужно заключить в двойные кавычки с помощью escape-последовательности \".

!

Другим вариантом запуска с помощью метода Run программ, имена которых содержат пробелы, можно использовать короткие имена папок и файлов посредством свойства ShortPath объекта File: WshShell.Run(File.ShortPath, vbMinimizedFocus);

Полностью текст сценария Logon.js приведен в листинге 11.10.

Листинг 11.10. Сценарий входа, позволяющий выбирать программы для автозагрузки

Резервное копирование документов пользователя при окончании сеанса работы 

Для каждого пользователя Windows ХР в каталоге Documents and Settings автоматически создается личная папка, имя которой совпадает с именем этого пользователя. В подкаталоге "Мои документы" (My Documents) этой папки по умолчанию сохраняются все созданные пользователем документы. Для того чтобы всегда иметь резервную копию документов пользователей, можно написать универсальный сценарий выхода, в котором будет происходить копирование всех файлов и подкаталогов из пользовательского каталога "Мои документы" в другой каталог с именем пользователя. В нашем примере резервные копии документов будут сохраняться в каталоге D:\Backup, т.е. при выходе пользователя Popov все его документы скопируются в каталог D:\Backup\Popov, а при выходе пользователя Kazakov — в каталог D:\Backup\Kazakov.

Командный файл

Самым быстрым решением поставленной задачи является создание командного файла Logoff.bat (листинг 11.11) и назначение его в качестве сценария выхода для всех пользователей. Результат работы этого пакетного файла будет виден в командном окне (рис. 11.20).

Листинг 11.11. Командный файл-сценарий выхода, позволяющий производить : резервное копирование документов пользователя

Как мы видим, вся работа файла Logoff.bat заключается в вызове команды XCOPY для нужных каталогов:

XCOPY /С /D /Е /I /Y "%HomeDrive%%HomePath%\Мои документы" "D:\Backup\%UserName%"

Рис. 11.20. Результат работы сценария выхода Logoff.bat для пользователя Popov


Здесь для XCOPY указаны несколько ключей, которые позволяют:

• не прерывать копирование при возникновении ошибки (ключ );

• копировать только те файлы, которые были изменены (ключ /D);

•  копировать все подкаталоги, включая пустые (ключ );

•  создавать, при необходимости, каталог, в который производится копирование (ключ /I);

•  перезаписывать файлы без подтверждения пользователя (ключ /Y).

!

Подробнее о ключах команды XCOPY можно узнать из встроенной справки для этой команды. Для вывода этой справки на экран необходимо в командном окне запустить XCOPY с ключом /?; для вывода справки в текстовый файл нужно воспользоваться символом перенаправления вывода '>', например: XCOPY /? > spr.txt.

Пути к каталогу, где хранятся документы пользователя, и к каталогу, в который будет производиться копирование, формируются с помощью переменных среды %HomeDir%, %HomePath% и %UserName%. Описание этих и некоторых других переменных среды, которые определены в Windows, приведено в табл. 11.2.


Таблица 11.2. Переменные среды, полезные для использования в сценариях входа/выхода

Переменная Описание
%COMSPEC% Путь к командному интерпретатору
%HOMEDIR% Буква переопределенного диска на компьютере пользователя, которая ссылается на сетевой ресурс, содержащий личный каталог пользователя
%HOMEDRIVE% Локальный, либо перенаправленный диск, на котором расположен личный каталог
%HOMEPATH% Путь к личному каталогу
%HOMESHARE% Имя каталога общего доступа, включающее личный каталог и локальный, либо переопределенный диск
%OS% Операционная система, управляющая рабочей станцией
%PROCESSOR_ARCHITECTURE% Архитектура процессора (например, х86) рабочей станции пользователя
%SYSTEMDRIVE% Диск, на котором находится системный каталог Windows
%SYSTEMROOT% Путь к системному каталогу Windows
%PROCESSOR_LEVEL% Тип процессора рабочей станции пользователя
%TEMP% Путь к каталогу для хранения временных файлов
%USERDOMAIN% Домен, в котором зарегистрирован пользователь
%USERNAME% Имя, под которым регистрировался при входе в сеть пользователь

Так как имена каталогов, присутствующих в команде XCOPY, могут содержать пробелы, эти имена взяты в кавычки.

Сценарий WSH

Для создания нужных нам резервных копий можно также написать сценарий WSH (назовем этот сценарий Logoff.js), который, конечно, будет намного больше по объему, чем командный файл, но будет выводить сообщения в красивые графические диалоговые окна (рис. 11.21–11.23).

Сначала в сценарии Logoff.js создаются экземпляры объектов WshShell, FileSystemObject и WshSpecialFolders, после чего в переменную SHomePath заносится путь к каталогу с документами текущего пользователя (специальная папка с именем My Documents):

//Создаем объект WshShell
WshShell = WScript.CreateObject("WScript.Shell");
//Создаем объект FileSystemObject
FSO = WScript.CreateObject("Scripting.FileSystemObject");
//Создаем объект WshSpecialFolders
WshFldrs=WshShell.SpecialFolders;
//Определяем путь к папке выборочной автозагрузки
SHomePath=WshFldrs.item("MyDocuments");

Путь к каталогу, в который будет производиться копирование документов, формируется с помощью переменной среды %UserName%; значение такой переменной извлекается c помощью метода ExpandEnvironmentStrings() объекта WshShell:

//Определяем имя пользователя
SUserName=WshShell.ExpandEnvironmentStrings("%UserName%");
//Формируем полный путь к каталогу с резервными копиями документов
//пользователя
SBackupPath+=SUserName;

Копирование документов мы будем производить только после утвердительного ответа пользователя на соответствующий вопрос (см. рис. 11.21):

//Запрос на создание резервной копии
Res=WshShell.Popup("Выполнить резервное копирование документов в\n" + SBackupPath + " ?", 0, "Выход пользователя " + SUserName, vbQuestion+vbYesNo);

Рис. 11.21. Диалоговое окно с запросом о необходимости копирования


Если пользователь согласен, мы копируем нужный каталог с помощью метода CopyFolder(), причем делаем это внутри блока try конструкции try…catch.

IsError=false;
try {
 //Производим копирование каталога
 FSO.CopyFolder(SHomePath,SBackupPath);
}

В случае возникновения ошибки переменной IsError в блоке catch присваивается значение true, а на экран выводится диалоговое окно с соответствующим сообщением (см. рис. 11.22):

catch (е) { //Обрабатываем возможные ошибки
 if (е != 0) {
  //Выводим сообщение об ошибке
  IsError=true;
  Mess="Ошибка при копировании каталога "+SHomePath+"\nКод ошибки: " + е.number + "\nОписание: " + е.description;
  WshShell.Popup(Mess, 0, "Выход пользователя " + SUserName, vbCritical);
 }
}

Рис. 11.22. Диалоговое окно с сообщением о возникшей ошибке


Если же в процессе копирования ошибок не возникло (переменная IsError равна false), то пользователю также выдается сообщение об этом (см. рис. 11.23):

if (!IsError) {
 //Производим копирование каталога
 FSO.CopyFolder(SHomePath, SBackupPath);
 //Все в порядке
 Mess = "Копирование документов произведено";
 WshShell.Popup(Mess, 0, "Выход пользователя " + SUserName, vbInformation);
}

Рис. 11.23. Диалоговое окно с сообщением о возникшей ошибке


Полностью текст сценария Logoff.js приведен в листинге 11.12.

Листинг 11.12. JScript-сценарий выхода, позволяющий производить резервное копирование документов пользователя

Вызов системных функций и стандартных диалоговых окон оболочки Windows

Из сценариев WSH можно выводить на экран стандартные диалоговые окна Windows (например, Выполнить (Run)) и модули панели управления (например, Установка даты и времени (Date/Time)). Для этого используются системные функции Windows (API-функции) и объект Shell.Application, который позволяет получить доступ к оболочке Windows.

Конкретные примеры применения системных функций и методов объекта-оболочки Windows приведены ниже.

Вызов модулей панели управления

Напомним, что в Windows ХР модули панели управления хранятся в каталоге %SystemRoot%\System32 в нескольких файлах с расширением cpl. Эти модули можно вывести на экран с помощью утилиты Control.exe, запустив ее из командной строки или из меню Выполнить (Run) с тремя параметрами (два из них необязательны):

Control.exe File.cpl,[Name],[Page]

Здесь File.cpl — название cpl-файла; Name — имя модуля; Page — номер страницы в диалоговом окне, которая будет выведена на передний план.

Например, команда

Control.exe Main.cpl, @0

вызовет диалоговое окно для настройки мыши (рис. 11.24).

Рис. 11.24. Модуль панели управления для настройки мыши


Если же выполнить команду

Control.exe Main.cpl, @1

то на экран будет выведено диалоговое окно для настройки клавиатуры (рис. 11.25).

Рис. 11.25. Модуль панели управления для настройки клавиатуры


Описание модулей панели управления для Windows ХР приведено в табл. 11.3 (в других версиях операционной системы количество имен и страниц может быть другим).


Таблица 11.3. Модули панели управления в Windows ХР

Модуль панели управления Имя Индекс Описание
appwiz.cpl 0…3 Установка и удаление программ
desk.cpl 0…4 Свойства экрана
hdwwiz.cpl Мастер установки оборудования
inetcpl.cpl 0…6 Параметры браузера Internet Explorer
intl.cpl 0…2 Языки и региональные стандарты
joy.cpl Установленные игровые устройства и их свойства
main.cpl @0, @1 0…4 Параметры мыши и клавиатуры
mmsys.cpl 0…4 Свойства аудиоустройств
ncpa.cpl Сетевые подключения
nusrmgr.cpl Учетные записи пользователей
odbccp32.cpl Администратор источников данных ODBC
powercfg.cpl Настройки управления электропитанием
sysdm.cpl @0, @1 0…6 Свойства системы
telephon.cpl Телефонные подключения
timedate.cpl 0…1 Установка даты и времени
access.cpl 0…5 Настройка специальных возможностей
AccessSetup.cpl Установка пользователя по умолчанию

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

Запуск с помощью оболочки Windows

Для доступа к стандартным диалоговым окнам Windows и модулям панели управления нужно сначала создать экземпляр объекта-оболочки Windows:

//Создаем объект Shell.Application
Shell=WScript.CreateObject("Shell.Application");

Модули панели управления вызываются с помощью метода ControlPanelItem(), в качестве параметра которого указывается имя соответствующего cpl-файла, например:

Shell.ControlPanelItem("Appwiz.cpl");

Если запустить ControlPanelItem() без параметра, то откроется вся панель управления.

В листинге 11.13 приведен сценарий RunCPL.js, в котором происходит вызов некоторых модулей панели управления.

Листинг 11.13. Вызов модулей панели управления с помощью оболочки Windows

Запуск с помощью системных функций Windows

Другим вариантом запуска модулей панели управления является использование специальных функций, находящихся в библиотечном файле shell32.dll. Хотя из сценариев нельзя напрямую вызывать системные функции Windows, для этой цели можно воспользоваться стандартной утилитой RunDll32.exe, которая позволяет запускать функции, хранящиеся в библиотечных dll-файлах. В свою очередь RunDll32.exe запускается в сценарии с помощью метода Run() объекта WshShell. В качестве параметров программы RunDll32.exe нужно через запятую указать имя dll-файла и имя вызываемой функции, например:

//Выводим окно установки Windows
WshShell.Run("Rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2");

Здесь мы вызываем функцию Control_RunDLL() из файла shell32.dll. В качестве же параметров функции Control_RunDLL() указываются через запятую название нужного cpl-файла, имя и индекс страницы модуля, которая будет выведена на передний план (в вышеприведенной команде вызывается страница с индексом 2 ("Установка Windows") из модуля appwiz.cpl ("Установка и удаление программ")).

В листинге 11.14 приведен сценарий RunCPL2.js, в котором вызовы модулей панели управления осуществляются с помощью запуска системных функций Windows.

Листинг 11.14. Вызов модулей панели управления с помощью вызовов системных функций

Открытие папки в Проводнике Windows

С помощью объекта Shell.Application можно запустить Проводник Windows и открыть в нем определенную папку. Для этого используется метод Explore(), в качестве параметра которого указывается путь к открываемой папке; соответствующий пример приведен в листинге 11.15.

Листинг 11.15. Открытие заданной папки в Проводнике Windows

Вызов окна форматирования диска

Диалогoвое окно, позволяющее форматировать диск с заданными параметрами (рис. 11.26), вызывается с помощью системной  функции SHFormatDrive() из библиотечного файла shell32.dll.

Рис. 11.26. Диалоговое окно форматирования диска


Соответствующий пример приведен в листинге 11.16.


Листинг 11.16. Вызов окна форматирования диска

Вызов окна запуска программ

Окно запуска программ открывается с помощью метода FileRun() объекта Shell.Application. Соответствующий пример приведен в листинге 11.17.

Листинг 11.17. Вызов окна запуска программ

Блокировка рабочей станции

Заблокировать рабочую станцию Windows ХР можно с помощью вызова функции LockWorkStation() из библиотечного файла user32.dll. В листинге 11.18 приведен сценарий Lock.js, в котором происходит блокировка компьютера с помощью этой функции.

Листинг 11.18. Блокировка рабочей станции

Вызов окна выключения компьютера 

Из сценария WSH можно вызвать диалоговое окно, в котором производится выбор действия при завершении работы Windows (рис. 11.27).

Рис. 11.27. Диалоговое окно выключения компьютера


Для этого необходимо вызвать метод ShutdownWindows() объекта Shell.Application. Соответствующий пример приведен в листинге 11.19.

Листинг 11.19. Вызов окна выключения компьютера

Использование технологии Windows Management Instrumentation (WMI)

В Windows XP/2000 ядром системы управления является технология WMI — Windows Management Instrumentation. WMI — это глобальная концепция настройки, управления и слежения за работой различных частей корпоративной компьютерной сети. В частности, используя WMI, можно из сценария WSH контролировать и изменять параметры самых разнородных физических и логических элементов компьютерной системы, в качестве которых могут выступать, например, файл на жестком диске, запущенный экземпляр приложения, системное событие, сетевой пакет или установленный в компьютере процессор. Очень важно, что при этом для доступа ко всем элементам используется единый интерфейс с помощью CIMOM — Common Information Model Object Manager — базы данных объектов, представляющих эти элементы. Это позволяет, в частности, быстро получать информацию разнообразного типа об объектах с помощью запросов на языке SQL. Другой важной особенностью WMI является то, что этот же интерфейс можно использовать для дистанционного управления компьютерами в сети (естественно, если на локальной и удаленной машине установлен WMI, а у пользователя, который выполняет удаленное администрирование, имеются соответствующие права).

Технология WMI — это созданная фирмой Microsoft реализация модели управления предприятием на базе Web (WBEM, Web-Based Enterprise Management), которая была разработана и принята рабочей группой по управлению распределенными системами (DMTF, Distributed Management Task Force), при участии таких компаний, как ВМС Software, Cisco Systems, Compaq Computer, Intel и Microsoft. Задачей WBEM была разработка стандартного набора интерфейсов для управления информационной средой предприятия.

В WBEM информация интерпретируется в рамках модели Common Information Model (CIM). CIM представляет собой стандартную схему именования для физических и логических компонентов компьютера. К любому элементу CIM можно обратиться с помощью объектно-ориентированной терминологии:

• класс CIM — это шаблон управляемых элементов, имеющий свойства и методы;

• объект CIM — это экземпляр класса, представляющий базовый компонент системы;

• схема (schema) — это совокупность классов, описывающая систему в целом.

В Windows используются две схемы: CIM (соответствует спецификации CIM 2.0) и Win32 (расширяет спецификацию CIM 2.0).

!

Объекты WMI также могут использоваться и в Windows 9x/ME/NT, для этого нужно скачать с сервера Microsoft(http://www.microsoft.com/downloads/release.asp?ReleaseID=18490).

Здесь мы не будем рассматривать классы, свойства и методы, которые поддерживает WMI, т.к. даже поверхностное ознакомление с ними потребовало бы отдельной книги, а лишь приведем несколько простых примеров сценариев, из которых станет ясно, каким образом происходит соединение с WMI, запрос нужной информации и использование объектов WMI.

Доступ к свойствам файла

Первый пример, который мы рассмотрим, будет посвящен работе с файловой системой. Мы напишем сценарий FileInfoWMI.js, в котором с помощью WMI будет формироваться диалоговое окно с информацией о файле C:\boot.ini (рис. 11.28).

Рис. 11.28. Свойства файла C:\boot.ini


!

Напомним, что из сценария к файловой системе можно получить доступ с помощью стандартного объекта FileSystemObject, однако использование WMI дает возможность собрать более полную информацию.

Для доступа к файлу на диске нужно создать для этого файла объект класса DataFile схемы CIM. Как и при использовании объектов ADSI, это делается с помощью JScript-функции GetObject(), в качестве параметра которой указывается строка вида "winMgmts:Prefix_class.Property=Value", где параметр Prefix соответствует используемой схеме (CIM или Win32), Class задает имя требуемого класса, Property соответствует имени свойства класса, a Value определяет конкретное значение этого свойства. В нашем случае нужный объект (переменная File) создается следующим образом:

//Создаем объект класса CIM_DataFile для файла C:\boot.ini
File=GetObject("winMgmts:CIM_DataFile.Name='С:\\boot.ini'")

После этого свойства файла извлекаются обычным образом из переменной File:

//Инициализируем символьную переменную SInfo
SInfo="Информация о файле "+File.Name+"\n\n";
//Извлекаем свойства файла
SInfo+="Имя:\t\t"+File.Name+"\n";

//Определяем, доступен ли файл для чтения и записи
SInfo+="\n";
if (File.Readable) SInfo+="Файл доступен для чтения\n"
else SInfo+="Файл не доступен для чтения\n";
if (File.Writeable) SInfo+="Файл доступен для записи\n"
else SInfo+="Фaйл не доступен для записи\n";

Сформированная символьная переменная SInfo выводится на экран с помощью метода Echo() объекта WScript:

WScript.Echo(SInfo);

Полностью текст сценария FileInfoWMI.js приведен в листинге 11.20.

Листинг 11.20. Доступ к свойствам файла с помощью WMI

Список всех запущенных процессов 

В следующих двух примерах мы будем работать с запущенными в операционной системе процессами.

Создадим сценарий ListProcesses.js, который будет выводить на экран имена всех запущенных процессов (рис. 11.29).

Рис. 11.29. Список всех запущенных в системе процессов


Первое, что необходимо сделать в сценарии — подключиться к службе Windows Management service, т.е. создать корневой элемент WMI, который содержит в себе все остальные. 

Для этого в качестве параметра функции GetObject() указывается "winMgmts:"; в нашем примере мы соединяемся с WMI внутри блока try, что позволяет обработать возможные исключительные ситуации:

try {
 //Соединяемся с WMI
 WMI=GetObject("winMgmts:");
} catch (e) {
 //Обрабатываем возможные ошибки
 if (е != 0) {
  //Выводим сообщение об ошибке
  Mess="Ошибка при соединении с WMI";
  WshShell.Popup(Mess, 0, "Запущенные процессы", vbCritical);
  //Выходим из сценария
  WScript.Quit();
 }
}

Запущенным процессам соответствует класс Process схемы Win32. Коллекция всех процессов создается с помощью выполнения следующего SQL-запроса:

SELECT * FROM Win32 Process

Таким образом, можно сказать, что класс Win32_Process является аналогом таблицы базы данных; сам запрос выполняется с помощью метода ExecQuery():

Processes=new Enumerator(WMI.ExecQuery("SELECT * FROM Win32_Process"));

После создания коллекции мы просматриваем в цикле while все ее элементы, каждый из которых соответствует одному процессу, и добавляем имя процесса, хранящееся в свойстве Name, к переменной SList:

//Инициализируем строку SList
SList="Запущенные процессы\n\n";
//Цикл по всем элементам коллекции
while (!Processes.atEnd()) {
 //Извлекаем текущий элемент коллекции (запущенный процесс)
 Process=Processes.item();
 //Формируем строку с именами процессов
 SList+=Process.Name+"\n";
 //Переходим к следующему элементу коллекции
 Processes.moveNext();
}

После выхода из цикла переменная SInfo выводится на экран с помощью метода Echo() объекта WScript:

WScript.Echo(SInfo);

Полностью текст сценария ListProcesses.js приведен в листинге 11.21.

Листинг 11.21. Вывод на экран списка всех запущенных процессов

Закрытие всех экземпляров запущенного приложения

WMI позволит нам закрывать сразу все экземпляры какого-либо запущенного приложения.

В сценарии KillNotepads.js мы будем закрывать все копии Блокнота (Notepad.exe). Как и в предыдущем примере, сначала мы соединяемся с WMI внутри блока try конструкции try…catch:

try {
 //Соединяемся с WMI
 WMI=GetObject("winMgmts:");
} catch (e) {
 //Обрабатываем возможные ошибки
 if (e != 0) {
  //Выводим сообщение об ошибке Mess="Ошибка при соединении с WMI";
  WshShell.Popup(Mess, 0, "Закрытие всех Блокнотов", vbCritical);
  //Выходим из сценария
  WScript.Quit();
 }
}

Далее нам нужно получить коллекцию всех процессов с именем "Notepad.exe". Для этого мы выполняем соответствующий SQL-запрос, текст которого предварительно заносится в переменную SQuery:

//Формируем текст запроса
SQuery="SELECT * FROM Wln32_Process WHERE Name='Notepad.exe'"
//Создаем коллекцию-результат запроса
Processes=new Enumerator(WMI.ExecQuery(SQuery));

Теперь, имея коллекцию нужных нам процессов, мы в цикле while перебираем все ее элементы, вызывая для каждого элемента (запущенного экземпляра Блокнота) метод Terminate(), который завершает этот процесс:

//Цикл по всем элементам коллекции
while (!Processes.atEnd()) {
 //Извлекаем текущий элемент коллекции (процесс с именем Notepad.exe)
 Process=Processes.item();
 try {
  //Завершаем процесс
  Process.Terminate();
 } catch (e) {
  //Обрабатываем возможные ошибки if (e != 0) {
  //Выводим сообщение об ошибке
  Mess="Ошибка при закрытии текущего экземпляра";
  WshShell.Popup(Mess, 0, "Закрытие всех Блокнотов", vbCritical);
 }
}
//Переходим к следующему элементу коллекции
Processes.moveNext();

Полностью текст сценария KillNotepads.js приведен в листинге 11.22.

Листинг 11.22. Закрытие всех запущенных экземпляров Блокнота


 

Глава 11. Применение сценариев WSH для администрирования Windows ХР