Онлайн библиотека PLAM.RU


  • Использование службы каталогов Active Directory Service Interface (ADSI)
  • Связывание с нужным объектом каталога
  • Список всех доступных доменов в локальной сети
  • Создание пользователя и группы на рабочей станции
  • Вывод информации о пользователе и смена его пароля
  • Удаление пользователя и группы на рабочей станции  
  • Список всех групп на рабочей станции
  • Список всех пользователей в группе
  • Список всех групп, в которые входит пользователь 
  • Создание сценариев включения/выключения и входа/выхода 
  • Сценарии, выполняемые при загрузке операционной системы 
  • Сценарии, выполняемые при завершении работы операционной системы
  • Сценарии входа для всех локальных пользователей
  • Сценарий выхода для всех локальных пользователей
  • Сценарий входа для одного пользователя 
  • Примеры сценариев входа/выхода 
  • Подключение сетевых дисков и синхронизация времени при регистрации пользователей 
  • Интерактивный выбор программ автозагрузки
  • Резервное копирование документов пользователя при окончании сеанса работы 
  • Вызов системных функций и стандартных диалоговых окон оболочки Windows
  • Вызов модулей панели управления
  • Запуск с помощью оболочки Windows
  • Запуск с помощью системных функций Windows
  • Открытие папки в Проводнике Windows
  • Вызов окна форматирования диска
  • Вызов окна запуска программ
  • Блокировка рабочей станции
  • Вызов окна выключения компьютера 
  • Использование технологии Windows Management Instrumentation (WMI)
  • Доступ к свойствам файла
  • Список всех запущенных процессов 
  • Закрытие всех экземпляров запущенного приложения
  • Глава 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. Вывод на экран списка всех доменов локальной сети

    /********************************************************************/

    /* Имя: ListDomains.js                                              */

    /* Язык: JScript                                                    */

    /* Описание: Вывод на экран списка всех доменов локальной сети      */

    /********************************************************************/

    //Объявляем переменные

    var

     NameSpaceObj, //Корневой объект Namespace

     DomObj,       //Экземпляр объекта Domain

     E,            //Объект Enumerator

     SList;        //Строка для вывода на экран


    //Связываемся с корневым объектом Namespace

    NameSpaceObj = GetObject("WinNT:");

    //Устанавливаем фильтр для выделения объектов-доменов

    NameSpaceObj.Filter = Array("domain");

    //Создаем объект Enumerator для доступа к коллекции NameSpaceObj

    E=new Enumerator(NameSpaceObj);

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

    //Цикл по всем элементам коллекции доменов

    while (!E.atEnd()) {

     //Извлекаем текущий элемент коллекции (объект класса Domain)

     DomObj=E.item();

     //Формируем строку с именами доменов

     List+=DomObj.Name+"\n";

     //Переходим к следующему элементу коллекции

     E.moveNext();

    }

    //Вывод информацию на экран

    WScript.Echo(List);

    /*************  Конец *********************************************/

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

    В сценарии 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. Создание нового локального пользователя на рабочей станции

    /********************************************************************/

    /* Имя: AddUser.js                                                  */

    /* Язык: JScript                                                    */

    /* Описание: Создание нового пользователя компьютера                */

    /********************************************************************/

    //Объявляем переменные

    var

     ComputerObj,        //Экземпляр объекта Computer

     UserObj,            //Экземпляр объекта User

     UserStr = "XUser";  //Имя создаваемого пользователя


    //Связываемся с компьютером 404_Popov

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

    //Создаем объект класса User

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

    //Добавляем описание созданного пользователя

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

    //Сохраняем информацию на компьютере

    UserObj.SetInfo();

    /*************  Конец *********************************************/

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

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

    /********************************************************************/

    /* Имя: AddGroup.js                                                 */

    /* Язык: JScript                                                    */

    /* Описание: Создание новой группы на компьютере                    */

    /********************************************************************/

    //Объявляем переменные

    var

     ComputerObj,         //Экземпляр объекта Computer

     GroupObj,            //Экземпляр объекта Group

     GroupStr = "XGroup"; //Имя создаваемой группы


    //Связываемся с компьютером 404_Popov

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

    //Создаем объект класса Group

    GroupObj=DomainObj.Create("group", GroupStr);

    //Сохраняем информацию на компьютере

    GroupObj.SetInfo();

    /*************  Конец *********************************************/

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

    В листинге 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. Вывод информации о пользователе компьютера и смена его пароля

    /********************************************************************/

    /* Имя: UserInfo.js                                                 */

    /* Язык: JScript                                                    */

    /* Описание: Вывод информации о пользователе компьютера и смена     */

    /*           его пароля                                             */

    /********************************************************************/

    var

     UserObj,   //Экземпляр объекта User

     Res,       //Результат нажатия кнопки в диалоговом окне

     SPassword, //Строка с новым паролем

     SInfo;     //Строка для вывода на экран

    //Инициализируем константы для диалогового окна

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Связываемся с пользователем XUser компьютера 404_Popov

    UserObj=GetObject("WinNT://404_Popov/XUser,user");

    //Формируем строку с информацией о пользователе

    SInfo="Информация о пользователе XUser:\n";

    SInfo+="Имя: "+UserObj.Name+"\n";

    SInfo+="Описание: "+UserObj.Description+"\n";

    //Выводим сформированную строку на экран

    WScript.Echo(SInfo);

    //Создаем объект WshShell

    WshShell=WScript.CreateObject("WScript.Shell");

    //Запрос на изменение пароля

    Res=WshShell.Popup("Изменить пароль у XUser?", 0,

     "Администрирование пользователей", vbQuestion+vbYesNo);

    if (Res==vbYes) { //Нажата кнопка Да

     //Устанавливаем новый пароль

     UserObj.SetPassword("NewPassword");

     //Сохраняем сделанные изменения

     UserObj.SetInfo();

     WScript.Echo("Пароль был изменен");

    } else WScript.Echo("Вы отказались от изменения пароля");

    /*************  Конец *********************************************/

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

    Для удаления созданных с помощью сценариев 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. Удаление пользователя и группы на рабочей станции

    /********************************************************************/

    /* Имя: DelUserAndGroup.js                                          */

    /* Язык: JScript                                                    */

    /* Описание: Удаление пользователя и группы компьютера              */

    /********************************************************************/

    //Объявляем переменные

    var

     ComputerObj,         //Экземпляр объекта Computer

     UserStr = "XUser",   //Имя удаляемого пользователя

     GroupStr = "XGroup", //Имя удаляемой группы

     WshShell;            //Объект WshShell

    //Инициализируем константы для диалоговых окон

    var vbCritical=16,vbInformation=64;

    //Связываемся с компьютером 404_Popov

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

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    /*************  Удаление пользователя  ***********************/

    IsError=false;

    try {

     //Удаляем пользователя

     ComputerObj.Delete("user", UserStr);

    } catch (e) {  //Обрабатываем возможные ошибки

     if (e != 0) {

      //Выводим сообщение об ошибке

      IsError=true;

      Mess="Ошибка при удалении пользователя "+UserStr+"\nКод ошибки: " + e.number + "\nОписание: " + e.description;

      WshShell.Popup(Mess,0,"Удаление пользователя",vbCritical);

     }

    }

    if (!IsError)  {

     //Все в порядке

     Mess="Пользователь "+UserStr+" удален";

     WshShell.Popup(Mess,0,"Удаление пользователя",vbInformation);

    }

    /*************  Удаление группы  ***********************/ 

    IsError=false;

    try  {

     //Удаляем группу

     ComputerObj.Delete("group", GroupStr);

    } catch (e) {  //Обрабатываем возможные ошибки

     if (e != 0) {

      //Выводим сообщение об ошибке

      IsError=true;

      Mess="Ошибка при удалении группы "+GroupStr+"\nКод ошибки: " + e.number+"\nОписание: " + e.description;

      WshShell.Popup(Mess,0,"Удаление группы",vbCritical);

     }

    }

    if (!IsError)  {

     //Все в порядке

     Mess="Группа "+GroupStr+" удалена";

     WshShell.Popup(Mess,0,"Удаление группы",vbInformation);

    }

    /*************  Конец *********************************************/

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

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

    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. Вывод на экран имен всех локальных групп заданной рабочей станции

    /********************************************************************/

    /* Имя: ListAllGroups.js                                               */

    /* Язык: JScript                                                    */

    /* Описание: Вывод на экран имен всех групп заданного компьютера    */

    /********************************************************************/

    //Объявляем переменные

    var

     ComputerObj, //Экземпляр объекта Computer

     E,           //Объект Enumerator

     SList;       //Строка для вывода на экран


    //Связываемся с компьютером 404_Popov

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

    //Создание объекта Enumerator для доступа к коллекции ComputerObj

    E=new Enumerator(ComputerObj);

    SList="На компьютере 404_Popov созданы группы:\n";

    //Цикл по всем элементам коллекции объектов компьютера

    while (!E.atEnd()) {

     //Извлекаем текущий элемент коллекции

     GroupObj=E.item();

     //Выделение объекты класса Group

     if (GroupObj.Class == "Group")

      //Формируем строку с именами групп

      SList+=GroupObj.Name+"\n";

     //Переход к следующему элементу коллекции 

     E.moveNext();

    }

    //Выводим информацию на экран

    WScript.Echo(SList);

    /*************  Конец *********************************************/

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

    В листинге 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. Вывод на экран имен всех пользователей заданной группы

    /********************************************************************/

    /* Имя: ListUsers.js                                                */

    /* Язык: JScript                                                    */

    /* Описание: Вывод на экран имен всех пользователей заданной группы */

    /********************************************************************/

    //Объявляем переменные

    var

     GroupObj, //Экземпляр объекта Group

     SList,    //Строка для вывода на экран

     E,        //Объект Enumerator

     UserObj;  //Экземпляр объекта User

    //Связываемся с группой Пользователи компьютера 404_Popov

    GroupObj=GetObject("WinNT://404_Popov/Пользователи,group");

    //Создание объекта Enumerator для доступа к коллекции пользователей

    E=new Enumerator(GroupObj.Members());

    SList="Все пользователи группы Пользователи на компьютере 404_Popov:\n";

    //Цикл по всем элементам коллекции пользователей

    while (!E.atEnd()) {

     //Извлечение элемента коллекции класса User

     UserObj=E.item();

     //Формируем строку с именами пользователей

     SList+=UserObj.Name+"\n";

     //Переходим к следующему элементу коллекции

     E.moveNext();

    }

    //Вывод информации на экран

    WScript.Echo(SList);

    /*************  Конец *********************************************/

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

    В сценарии 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. Вывод на экран названия всех групп, членом которых является заданный пользователь

    /********************************************************************/

    /* Имя: ListGroups.js                                               */

    /* Язык: JScript                                                    */

    /* Описание: Вывод на экран названия всех групп, членом которых     */

    /*           является заданный пользователь                         */

    /********************************************************************/

    //Объявляем переменные

    var

     UserObj,  //Экземпляр объекта User

     E,        //Объект Enumerator

     GroupObj, //Экземпляр объекта Group

     SList;    //Строка для вывода на экран


    //Связывание с пользователем Popov компьютера 404_Popov

    UserObj = GetObject("WinNT://404_Popov/Popov");

    //Создание объекта Enumerator для доступа к коллекции групп пользователя

    E=new Enumerator(UserObj.Groups());

    SList="Пользователь Popov входит в группы:\n";

    //Цикл по всем элементам коллекции групп

    while (!E.atEnd()) {

     //Извлекаем элемент коллекции класса Group

     GroupObj=E.item();

     //Формируем строку с названиями групп

     SList+=GroupObj.Name+"\n";

     //Переходим к следующему элементу коллекции

     E.moveNext();

    }

    //Вывод информации на экран

    WScript.Echo(SList);

    /*************  Конец *********************************************/

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

    Напомним, что в 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. Пример командного файла-сценария входа

    @ECHO OFF

    REM Имя: Logon.bat

    REM Описание: Использование командного файла в качестве сценария входа

    NET TIME \\Server1 /SET

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

    NET SHARE MyTxt=C:\TEXT

    В первой строке файла 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. Сценарий входа, позволяющий выбирать программы для автозагрузки

    //*******************************************************************/

    /* Имя: Logon.js                                                   */

    /* Язык: JScript                                                   */

    /* Описание: Сценарий входа, позволяющий выбирать программы для    */

    /*           автозагрузки                                          */

    /*******************************************************************/

    //Объявляем переменные

    var

     FSO,         //Экземпляр объекта FileSystemObject

     WshShell,    //Экземпляр объекта WshShell

     WshFldrs,    //Экземпляр объекта WshSpecialFolders

     PathStartup, //Путь к папке выборочной автозагрузки

     Folder,      //Экземпляр объекта Folder для папки

                  //выборочной автозагрузки

     Files,       //Коллекция файлов в папке выборочной автозагрузки

     File,        //Экземпляр объекта File для ярлыка в папке

                  //выборочной автозагрузки

     Res,         //Результат нажатия кнопок в диалоговых окнах

     IsRunAll;    //Логический флаг, указывающий, надо ли запустить

                  //сразу все программы из автозагрузки

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6,vbOkOnly=0,vbMinimizedFocus=2;

    //Создаем объект WshShell

    WshShell=WScript.CreateObject("Wscript.Shell");

    //Создаем объект WshSpecialFolders

    WshFldrs=WshShell.SpecialFolders;

    //Определяем путь к папке выборочной автозагрузки

    PathStartup=WshFldrs.item("AllUsersStartMenu")+"\\Выборочная автозагрузка\\";

    //Создаем объект FileSystemObject

    FSO=WScript.CreateObject("Scripting.FileSystemObject");

    //Создаем объект Folder для папки выборочной автозагрузки

    Folder=FSO.GetFolder(PathStartup);

    //Создаем коллекцию файлов каталога выборочной автозагрузки

    Files=new Enumerator(Folder.Files);

    //Выводим запрос на запуск сразу всех программ

    Res=WshShell.Popup("Запустить сразу все программы?",0,

      "Выборочная автозагрузка",vbQuestion+vbYesNo);

    //Определяем, нажата ли кнопка Да

    IsRunAll=(Res==vbYes);

    //Цикл по всем файлам каталога выборочной автозагрузки

    while (!Files.atEnd()) {

     //Создаем объект File для текущего элемента коллекции

     File=Files.item();

     //Обнуляем переменную Res

     Res=0;

     if (!IsRunAll) //Программы нужно запускать по одной

      //Выводим запрос на запуск одной программы

      Res=WshShell.Popup("Запустить "+File.Name+"?",0,

       "Выборочная автозагрузка",vbQuestion+vbYesNo);

     if ((IsRunAll) || (Res==vbYes))

      //Запускаем текущую программу в минимизированном окне

      WshShell.Run("\""+File.Path+"\"",vbMinimizedFocus);

     //Переходим к следующему файлу в коллекции

     Files.moveNext();

    }

    /*************  Конец *********************************************/

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

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

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

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

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

    @ECHO OFF

    REM Имя: Logoff.bat

    REM Описание: BAT-файл, выполняющий резервное копирование

    REM           документов пользователя

    ECHO Окончание сеанса пользователя %UserName%.

    ECHO.

    ECHO Начинаем копирование документов в каталог D:\Backup\%UserName%...

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

    ECHO.

    ECHO Копирование документов завершено.

    PAUSE

    Как мы видим, вся работа файла 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-сценарий выхода, позволяющий производить резервное копирование документов пользователя

    /********************************************************************/

    /* Имя: Logoff.js                                                   */

    /* Язык: JScript                                                    */

    /* Описание: Сценарий выхода, позволяющий производить резервное     */

    /*           копирование документов пользователя                    */

    /********************************************************************/

    //Объявляем переменные

    var

     WshShell,                   //Экземпляр объекта WshShell

     WshFldrs,                   //Экземпляр объекта WshSpecialFolders

     FSO,                        //Экземпляр объекта FileSystemObject

     SUserDocPath,               //Путь к папке с документами пользователя

     SUserName,                  //Имя пользователя

     SBackupPath="D:\\Backup\\", //Каталог для резервных копий документов

     Res,IsError;

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbInformation=64,vbYes=6,vbOkOnly=0,

     vbCritical=16;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Создаем объект FileSystemObject

    FSO = WScript.CreateObject("Scripting.FileSystemObject");

    //Создаем объект WshSpecialFolders

    WshFldrs=WshShell.SpecialFolders;

    //Определяем путь к папке выборочной автозагрузки

    SHomePath=WshFldrs.item("MyDocuments");

    //Определяем имя пользователя

    SUserName=WshShell.ExpandEnvironmentStrings("%UserName%");

    //Формируем полный путь к каталогу с резервными копиями документов

    //пользователя

    SBackupPath+=SUserName;

    //Запрос на создание резервной копии

    Res=WshShell.Popup("Выполнить резервное копирование документов в\n"+

     SBackupPath+" ?", 0, "Выход пользователя "+SUserName, vbQuestion+vbYesNo);

    if (Res==vbYes) { //Нажата кнопка Да

     IsError=false;

     try {

      //Производим копирование каталога

      FSO.CopyFolder(SHomePath,SBackupPath);

     } catch (e) {  //Обрабатываем возможные ошибки

      if (e != 0) {

       //Выводим сообщение об ошибке

       IsError=true;

       Mess="Ошибка при копировании каталога "+SHomePath+"\nКод ошибки: "+

        e.number+"\nОписание: "+e.description;

       WshShell.Popup(Mess,0,"Выход пользователя "+SUserName,vbCritical);

      }

     }

     if (!IsError)  {

      //Все в порядке

      Mess="Копирование документов произведено";

      WshShell.Popup(Mess,0,"Выход пользователя "+SUserName,vbInformation);

     }

    }

    /*************  Конец *********************************************/
     

    Вызов системных функций и стандартных диалоговых окон оболочки 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

    /*******************************************************************/

    /* Имя: RunCPL.js                                                  */

    /* Язык: JScript                                                   */

    /* Описание: Вызов модулей панели управления с помощью             */

    /*           объекта Shell.Application                             */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     Shell,    //Экземпляр объекта Shell.Application

     Res;      //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Создаем объект Shell.Application

    Shell=WScript.CreateObject("Shell.Application");

    //Выводим запрос

    Res=WshShell.Popup("Открыть панель управления?",0,

     "Вызов модулей панели управления",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Выводим панель управления

     Shell.ControlPanelItem("");


    //Выводим запрос

    Res=WshShell.Popup("Открыть окно установки и удаления программ?",0,

     "Вызов модулей панели управления",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Выводим окно установки и удаления программ

     Shell.ControlPanelItem("Appwiz.cpl");

    //Выводим запрос

    Res=WshShell.Popup("Открыть окно установки даты и времени?",0,

     "Вызов модулей панели управления",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Выводим окно установки даты и времени

     Shell.ControlPanelItem("TimeDate.cpl");

    /*************  Конец *********************************************/
     

    Запуск с помощью системных функций 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. Вызов модулей панели управления с помощью вызовов системных функций

    /*******************************************************************/

    /* Имя: RunCPL2.js                                                 */

    /* Язык: JScript                                                   */

    /* Описание: Вызов модулей панели управления с помощью             */

    /*           вызовов системных функций                             */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     Res;      //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Выводим запрос

    Res=WshShell.Popup("Открыть панель управления?",0,

     "Вызов модулей панели управления",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Выводим панель управления

     WshShell.Run("Rundll32.exe shell32.dll,Control_RunDLL");


    //Выводим запрос

    Res=WshShell.Popup("Открыть окно установки Windows?",0,

     "Вызов модулей панели управления",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Выводим окно установки Windows

     WshShell.Run("Rundll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,2");


    //Выводим запрос

    Res=WshShell.Popup("Открыть окно установки даты и времени?",0,

     "Вызов модулей панели управления",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Выводим окно установки даты и времени

     WshShell.Run("Rundll32.exe shell32.dll,Control_RunDLL timedate.cpl");

    /*************  Конец *********************************************/
     

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

    С помощью объекта

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

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

    /*******************************************************************/

    /* Имя: Explore.js                                                 */

    /* Язык: JScript                                                   */

    /* Описание: Открытие заданной папки в Проводнике Windows          */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell,     //Экземпляр объекта WshShell

     Shell,        //Экземпляр объекта Shell.Application

     SPath="C:\\", //Путь к открываемой папке

     Res;          //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Создаем объект Shell.Application

    Shell=WScript.CreateObject("Shell.Application");

    //Выводим запрос

    Res=WshShell.Popup("Открыть папку "+SPath+"?",0,

     "Вызов стандартных диалогов Windows",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Открываем папку в Проводнике

     Shell.Explore(SPath);

    /*************  Конец *********************************************/

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

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

    SHFormatDrive()
    из библиотечного файла shell32.dll.

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


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


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

    /*******************************************************************/

    /* Имя: FormatDisk.js                                              */

    /* Язык: JScript                                                   */

    /* Описание: Вызов окна форматирования диска                       */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     Res;      //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Выводим запрос

    Res=WshShell.Popup("Открыть окно форматирования?",0,

     "Вызов стандартных диалогов Windows",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Вызываем окно форматирования

     WshShell.Run("Rundll32.exe shell32.dll,SHFormatDrive");

    /*************  Конец *********************************************/

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

    Окно запуска программ открывается с помощью метода

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

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

    /*******************************************************************/

    /* Имя: FileRun.js                                                 */

    /* Язык: JScript                                                   */

    /* Описание: Вызов окна запуска программ                           */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     Shell,    //Экземпляр объекта Shell.Application

     Res;      //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Создаем объект Shell.Application

    Shell=WScript.CreateObject("Shell.Application");

    //Выводим запрос

    Res=WshShell.Popup("Открыть окно запуска программ?",0,

     "Вызов стандартных диалогов Windows",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

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

     Shell.FileRun();

    /*************  Конец *********************************************/

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

    Заблокировать рабочую станцию Windows ХР можно с помощью вызова функции

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

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

    /*******************************************************************/

    /* Имя: Lock.js                                                    */

    /* Язык: JScript                                                   */

    /* Описание: Блокировка рабочей станции                            */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     Res;      //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Выводим запрос на блокировку рабочей станции

    Res=WshShell.Popup("Заблокировать рабочую станцию?",0,

     "",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

     //Блокируем рабочую станцию

     WshShell.Run("Rundll32.exe user32.dll,LockWorkStation");

    /*************  Конец *********************************************/

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

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

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


    Для этого необходимо вызвать метод

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

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

    /*******************************************************************/

    /* Имя: ShutdownWindow.js                                          */

    /* Язык: JScript                                                   */

    /* Описание: Вызов окна выключения компьютера                      */

    /*******************************************************************/

    //Объявляем переменные

    var

     WshShell, //Экземпляр объекта WshShell

     Shell,    //Экземпляр объекта Shell.Application

     Res;      //Результат нажатия кнопок в диалоговом окне

    //Инициализируем константы для диалоговых окон

    var vbYesNo=4,vbQuestion=32,vbYes=6;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");

    //Создаем объект Shell.Application

    Shell=WScript.CreateObject("Shell.Application");

    //Выводим запрос

    Res=WshShell.Popup("Открыть окно выключения компьютера?",0,

     "Вызов стандартных диалогов Windows",vbQuestion+vbYesNo);

    if (Res==vbYes) //Нажата кнопка Да

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

     Shell.ShutdownWindows();

    /*************  Конец *********************************************/
     

    Использование технологии 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

    /*******************************************************************/

    /* Имя: FileInfoWMI.js                                             */

    /* Язык: JScript                                                   */

    /* Описание: Доступ к свойствам файла с помощью WMI                */

    /*******************************************************************/

    //Объявляем переменные

    var

     File,  //Объект класса CIM_DataFile

     SInfo; //Строка для вывода на экран

    //Функция для форматирования символьного представления даты

    function StrDate(d) {

     var s;

     s=d.substr(6,2)+"."+d.substr(4,2)+"."+d.substr(0,4)

     return s;

    }

    /*************  Начало *********************************************/

    //Создаем объект класса CIM_DataFile для файла C:\boot.ini

    File=GetObject("winMgmts:CIM_DataFile.Name='C:\\boot.ini'")

    //Инициализируем символьную переменную SInfo

    SInfo="Информация о файле "+File.Name+"\n\n";

    //Извлекаем свойства файла

    SInfo+="Имя:\t\t"+File.Name+"\n";

    SInfo+="Путь:\t\t"+File.Path+"\n";

    SInfo+="Диск:\t\t"+File.Drive+"\n";

    SInfo+="Размер:\t\t"+File.FileSize+"\n";

    SInfo+="Создан:\t\t"+StrDate(File.CreationDate)+"\n";

    SInfo+="Изменен:\t\t"+StrDate(File.LastModified)+"\n";

    SInfo+="Открыт:\t\t"+StrDate(File.LastAccessed)+"\n";

    SInfo+="Короткое имя:\t"+File.EightDotThreeFileName+"\n";

    SInfo+="Расширение:\t"+File.Extension+"\n";

    SInfo+="Тип:\t"+File.FileType+"\n";

    //Определяем атрибуты файла

    SInfo+="\n";

    SInfo+="Атрибуты:\n";

    if (File.Archive) SInfo+="\tАрхивный\n";

    if (File.Hidden) SInfo+="\tСкрытый\n";

    if (File.System) SInfo+="\tСистемный\n";

    if (File.Compressed) SInfo+="\tСжат с помощью "+File.CompressionMethod+"\n";

    if (File.Encrypted) SInfo+="\tЗашифрован с помощью "+File.EncryptionMethod+"\n";

    //Определяем, доступен ли файл для чтения и записи

    SInfo+="\n";

    if (File.Readable) SInfo+="Файл доступен для чтения\n"

    else SInfo+="Файл не доступен для чтения\n";

    if (File.Writeable) SInfo+="Файл доступен для записи\n"

    else SInfo+="Файл не доступен для записи\n";

    //Выводим сформированную строку на экран

    WScript.Echo(SInfo);

    /*************  Конец *********************************************/

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

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

    Создадим сценарий 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. Вывод на экран списка всех запущенных процессов

    /********************************************************************/

    /* Имя: ListProcesses.js                                            */

    /* Язык: JScript                                                    */

    /* Описание: Вывод на экран списка всех запущенных на локальной     */

    /*           рабочей станции процессов                              */

    /********************************************************************/

    var

     WMI,       //Экземпляр WMI

     Processes, //Коллекция процессов

     Process,   //Экземпляр коллекции

     SList;     //Строка для вывода на экран

    //Инициализируем константы для диалоговых окон

    var vbCritical=16;

    try  {

     //Соединяемся с WMI

     WMI=GetObject("winMgmts:");

    } catch (e) {  //Обрабатываем возможные ошибки

     if (e != 0) {

      //Выводим сообщение об ошибке

      Mess="Ошибка при соединении с WMI";

      WshShell.Popup(Mess,0,"Запущенные процессы",vbCritical);

      //Выходим из сценария

      WScript.Quit();

     }

    }

    //Создаем коллекцию всех запущенных процессов

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

    //Инициализируем строку SList

    SList="Запущенные процессы\n\n";

    //Цикл по всем элементам коллекции

    while (!Processes.atEnd()) {

     //Извлекаем текущий элемент коллекции (запущенный процесс)

     Process=Processes.item();

     //Формируем строку с именами процессов

     SList+=Process.Name+"\n";

     //Переходим к следующему элементу коллекции

     Processes.moveNext();

    }

    //Выводим информацию на экран

    WScript.Echo(SList);

    /*************  Конец *********************************************/

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

    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. Закрытие всех запущенных экземпляров Блокнота

    /********************************************************************/

    /* Имя: KillNotepads.js                                             */

    /* Язык: JScript                                                    */

    /* Описание: Закрытие всех запущенных экземпляров Блокнота          */

    /********************************************************************/

    var

     WMI,       //Экземпляр WMI

     SQuery,    //Текст запроса

     Processes, //Коллекция процессов

     Process,   //Экземпляр коллекции

     WshShell;  //Объект WshShell

    //Инициализируем константы для диалоговых окон

    var vbCritical=16;

    //Создаем объект WshShell

    WshShell = WScript.CreateObject("WScript.Shell");


    try {

     //Соединяемся с WMI

     WMI=GetObject("winMgmts:");

    } catch (e) {  //Обрабатываем возможные ошибки

     if (e != 0) {

      //Выводим сообщение об ошибке

      Mess="Ошибка при соединении с WMI";

      WshShell.Popup(Mess,0,"Закрытие всех Блокнотов",vbCritical);

      //Выходим из сценария

      WScript.Quit();

     }

    }


    //Формируем текст запроса 

    SQuery="SELECT * FROM Win32_Process WHERE Name='Notepad.exe'"

    //Создаем коллекцию-результат запроса

    Processes=new Enumerator(WMI.ExecQuery(SQuery));

    //Цикл по всем элементам коллекции

    while (!Processes.atEnd()) {

     //Извлекаем текущий элемент коллекции (процесс с именем Notepad.exe)

     Process=Processes.item();

     try { 

      //Завершаем процесс

      Process.Terminate();

     } catch (e) {  //Обрабатываем возможные ошибки

      if (e != 0) {

       //Выводим сообщение об ошибке

       Mess="Ошибка при закрытии текущего экземпляра";

       WshShell.Popup(Mess,0,"Закрытие всех Блокнотов",vbCritical);

      }

     }

     //Переходим к следующему элементу коллекции 

     Processes.moveNext();

    }

    /*************  Конец *********************************************/









    Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное

    Все материалы представлены для ознакомления и принадлежат их авторам.