Командная строка и сценарии Windows

Сценарии WSH для доступа к службе каталогов АDSI

Разбить на страницы
Показывать лекцию целиком

Сценарии WSH для доступа к службе каталогов АDSI

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

Что касается компьютерных сетей (локальных или глобальных), здесь также уместно говорить о каталогах, содержащих объекты разных типов: зарегистрированные пользователи, доступные сетевые принтеры и очереди печати и т.д. Для пользователей сети важно уметь находить и использовать такие объекты (а их в крупной сети может быть огромное количество), администраторы же сети должны поддерживать эти объекты в работоспособном состоянии. Под службой каталога (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/2003. Естественно, для прямого доступа к разным службам каталогов приходится использовать разные инструментальные средства, что усложняет процесс администрирования сети в целом. Для решения этой проблемы можно применить технологию ADSI (Active Directory Service Interface) фирмы Microsoft, которая предоставляет набор объектов ActiveX, обеспечивающих единообразный, не зависящий от конкретного сетевого протокола, доступ к функциям различных каталогов. Объекты ADSI включаются в операционные системы Windows 2000/XP и выше.

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

C:\Windows\Command\command.com

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

  • "LDAP://" — для службы каталогов, созданной на основе протокола LDAP (Lightweight Directory Access Protocol), в том числе для Active Directory в Windows 2000/2003;
  • "WinNT://" — для службы каталогов в сети Windows NT 4.0 или на локальной рабочей станции Windows XP/2000;
  • "NDS://" — для службы каталогов NetWare NDS (Novell Directory Service);
  • "NWCOMPAT://" — для службы каталогов NetWare Bindery.
  • Вторая часть строки ADsPath определяет расположение объекта в конкретном каталоге. Приведем несколько примеров полных строк ADsPath:

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

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

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

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

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

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

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

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

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

    Варианты строк связывания на компьютере Windows XP
    Строка 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 или VBScript, которая возвращает ссылку на объект ActiveX, находящийся во внешнем каталоге. Например (язык VBScript):

    Set objNameSpace = GetObject("WinNT:")
    Set objComputer = GetObject("WinNT://404_Popov")
    Set objUser = GetObject("WinNT://Popov/Popov,user")
    Set objGroup = GetObject("WinNT://Popov/BankUsers, group")

    Замечание

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

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

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

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

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

    Set objNameSpace = GetObject("WinNT:")

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

    objNameSpace.Filter = Array("domain")

    В цикле For Each … In … выполняется перебор всех элементов коллекции, которые являются объектами класса Domain ; название домена, хранящееся в свойстве Name, добавляется (вместе с символом разрыва строки) в переменную strResult. Сформированная таким образом переменная strResult выводится на экран с помощью метода Echo объекта WScript.

    '*******************************************************************
    ' Имя: ListDomains.vbs                                              
    ' Язык: VBScript                                                    
    ' Описание: Вывод на экран списка всех доменов локальной сети     
    '*********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objNameSpace        ' Корневой объект Namespace
    Dim objDomain           ' Экземпляр объекта Domain
    Dim strResult           ' Строка для вывода на экран
    
    'Связываемся с корневым объектом Namespace
    Set objNameSpace = GetObject("WinNT:")
    'Устанавливаем фильтр для выделения объектов-доменов
    objNameSpace.Filter = Array("domain")
    
    strResult = "Все доступные домены в сети:"  vbCrLf  vbCrLf
    
    ' Перебираем элементы коллекции 
    For Each objDomain In objNameSpace
      'Формируем строку с именами доменов
      strResult = strResult  objDomain.Name  vbCrLf
    Next
    
    'Вывод информацию на экран
    WScript.Echo strResult
    '*************  Конец *********************************************

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

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

    Set objComputer = GetObject("WinNT://Popov")

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

    Set objUser = objComputer.Create("user",strUser)

    Замечание

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

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

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

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

    '********************************************************************
    ' Имя: AddUser.vbs                                                  
    ' Язык: VBScript                                                    
    ' Описание: Создание нового пользователя компьютера                
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objComputer        ' Экземпляр объекта Computer
    Dim objUser            ' Экземпляр объекта User
    Dim strUser            ' Имя создаваемого пользователя
    
    ' Задаем имя пользователя
    strUser = "XUser"
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    ' Создаем объект класса User
    Set objUser = objComputer.Create("user",strUser)
    ' Добавляем описание созданного пользователя
    objUser.Description = "Этот пользователь создан из сценария ADSI"
    
    ' Сохраняем информацию на компьютере
    objUser.SetInfo
    '*************  Конец *********************************************

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

    '********************************************************************
    ' Имя: AddGroup.vbs                                                  
    ' Язык: VBScript                                                    
    ' Описание: Создание новой группы на компьютере
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objComputer        ' Экземпляр объекта Computer
    Dim objGroup           ' Экземпляр объекта Group
    Dim strGroup           ' Имя создаваемой группы
    
    ' Задаем имя пользователя
    strGroup = "XGroup"
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    ' Создаем объект класса Group
    Set objGroup = objComputer.Create("group",strGroup)
    ' Сохраняем информацию на компьютере
    objGroup.SetInfo
    '*************  Конец *********************************************

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

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

    ' Связываемся с пользователем XUser компьютера Popov
    Set objUser = GetObject("WinNT://Popov/XUser,user")
    ' Формируем строку с информацией о пользователе
    strResult = "Информация о пользователе XUser"  vbCrLf _
            "Имя: "  objUser.Name  vbCrLf  _
            "Описание: "  objUser.Description  vbCrLf
    ' Выводим сформированную строку на экран
    WScript.Echo strResult

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

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

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

    If Res=vbYes Then ' Нажата кнопка Да
      ' Устанавливаем новый пароль
      objUser.SetPassword "NewPassword"
      ' Сохраняем сделанные изменения
      objUser.SetInfo
    '********************************************************************
    ' Имя: UserInfo.vbs                                                 
    ' Язык: VBScript                                                    
    ' Описание: Вывод информации о пользователе компьютера и смена     
    '           его пароля                                             
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objUser      ' Экземпляр объекта User
    Dim WshShell     ' Объект WshShell
    Dim Res          ' Результат нажатия кнопки в диалоговом окне
    Dim strPassword  ' Строка с новым паролем
    Dim strResult    ' Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Связываемся с пользователем XUser компьютера Popov
    Set objUser = GetObject("WinNT://Popov/XUser,user")
    ' Формируем строку с информацией о пользователе
    strResult = "Информация о пользователе XUser"  vbCrLf _
            "Имя: "  objUser.Name  vbCrLf  _
            "Описание: "  objUser.Description  vbCrLf
    ' Выводим сформированную строку на экран
    WScript.Echo strResult
    
    ' Создаем объект WshShell
    Set WshShell = WScript.CreateObject("WScript.Shell")
    ' Запрос на изменение пароля
    Res = WshShell.Popup("Изменить пароль у XUser?",0,_
      "Администрирование пользователей",vbQuestion+vbYesNo)
    If Res=vbYes Then ' Нажата кнопка Да
      ' Устанавливаем новый пароль
      objUser.SetPassword "NewPassword"
      ' Сохраняем сделанные изменения
      objUser.SetInfo
      WScript.Echo "Пароль был изменен"
    Else
      WScript.Echo "Вы отказались от изменения пароля"
    End If  
    '*************  Конец *********************************************/

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

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

    Замечание

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

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

    Set objComputer = GetObject("WinNT://Popov")

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

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

    objComputer.Delete "user", strUser

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

    If Err.Number <> 0 Then  
      strMess="Ошибка при удалении пользователя "  strUser  vbCrLf  _
           "Код ошибки: "  Err.number  "Описание: "  Err.description
      WshShell.Popup strMess,0,"Удаление пользователя",vbCritical
    
      ' Очищаем свойства объекта Err
      Err.Clear
    Else
      ' Все в порядке
      strMess = "Пользователь "  strUser  " удален"
      WshShell.Popup strMess,0,"Удаление пользователя",vbInformation
    End If

    Как мы видим, если при вызове метода Delete произойдет какая-либо ошибка, то на экран с помощью метода Popup объекта WshShell выведется соответствующее сообщение. Если же удаление прошло успешно (свойство Number объекта Err равно нулю), то на экран также выведется соответствующее диалоговое окно.

    Процесс удаления группы в сценарии проходит аналогично.

    '********************************************************************
    ' Имя: DelUserAndGroup.vbs  
    ' Язык: VBScript                                                    
    ' Описание: Удаление пользователя и группы компьютера
    '********************************************************************
    Option Explicit
    On Error Resume Next
    
    'Объявляем переменные
    Dim objComputer          ' Экземпляр объекта Computer
    Dim strUser              ' Имя удаляемого пользователя
    Dim strGroup             ' Имя удаляемой группы
    Dim WshShell             ' Объект WshShell
    Dim strMess              Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Имя удаляемого пользователя
    strUser = "XUser"    
    ' Имя удаляемой группы
    strGroup = "XGroup"  
    
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    ' Создаем объект WshShell
    Set WshShell = WScript.CreateObject("WScript.Shell")
    
    '*************  Удаление пользователя  ***********************
    ' Удаляем пользователя
    objComputer.Delete "user", strUser
    
    ' Обрабатываем ошибки
    If Err.Number <> 0 Then  
      strMess="Ошибка при удалении пользователя "  strUser  vbCrLf  _
           "Код ошибки: "  Err.number  "Описание: "  Err.description
      WshShell.Popup strMess,0,"Удаление пользователя",vbCritical
    
      ' Очищаем свойства объекта Err
      Err.Clear
    Else
      ' Все в порядке
      strMess = "Пользователь "  strUser  " удален"
      WshShell.Popup strMess,0,"Удаление пользователя",vbInformation
    End If
    
    '*************  Удаление группы  ***********************/
    objComputer.Delete "group", strGroup
    
    ' Обрабатываем ошибки
    If Err.Number <> 0 Then  
      strMess="Ошибка при удалении группы "  strGroup  vbCrLf  _
           "Код ошибки: "  Err.number  "Описание: "  Err.description
      ' Очищаем свойства объекта Err
      Err.Clear
    Else
      ' Все в порядке
      strMess="Группа "  strGroup  " удалена"
      WshShell.Popup strMess,0,"Удаление группы",vbInformation
    End If
    '*************  Конец *********************************************/

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

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

    В приведенном в листинге 8.6 сценарии ListAllGroups.vbs для связывания с компьютером Popov мы создаем объект-контейнер objComputer, в котором содержатся все объекты рабочей станции Popov:

    Set objComputer = GetObject("WinNT://Popov")

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

    strResult = "На компьютере Popov созданы группы:"  vbCrLf   vbCrLf

    После этого в цикле For Each … In … из коллеции objComputer выбираются лишь объекты класса Group, то есть те объекты, у которых в поле Class записана строка "Group"; в strResult заносятся названия групп из поля Name:

    For Each objGroup In objComputer
      ' Выделяем объекты класса Group
      If objGroup.Class = "Group" Then
        'Формируем строку с именами групп
        strResult = strResult  objGroup.Name  vbCrLf
      End If
    Next

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

    '********************************************************************
    ' Имя: ListAllGroups.vbs
    ' Описание: Вывод на экран имен всех групп заданного компьютера 
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objComputer    ' Экземпляр объекта Computer
    Dim objGroup       ' Экземпляр объекта Group
    Dim strResult      ' Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    
    strResult = "На компьютере Popov созданы группы:"  vbCrLf   vbCrLf
    
    ' Перебираем элементы коллекции 
    For Each objGroup In objComputer
      ' Выделяем объекты класса Group
      If objGroup.Class = "Group" Then
        'Формируем строку с именами групп
        strResult = strResult  objGroup.Name  vbCrLf
      End If
    Next
        
    'Выводим информацию на экран
    WScript.Echo strResult
    '*************  Конец *********************************************/

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

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

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

    Set objGroup = GetObject("WinNT://Popov/Пользователи,group")

    После инициализации переменной strResult мы обрабатываем в цикле For Each … In … все элементы полученной коллекции пользователей группы (данная коллекция формируется с помощью метода Members объекта Group ); на каждом шаге цикла к переменной strResult добавляется имя текущего пользователя (поле Name в объекте objUser — текущем элементе коллекции):

    strResult = "Все пользователи группы Пользователи 
     на компьютере Popov:"  vbCrLf
    ' Перебираем элементы коллекции 
    For Each objUser In objGroup.Members()
      ' Формируем строку с именами пользователей
      strResult = strResult  objUser.Name  vbCrLf
    Next

    После выхода из цикла сформированная строка strResult выводится на экран.

    '********************************************************************
    ' Имя: ListUsers.vbs                                                
    ' Язык: VBScript                                    
    ' Описание: Вывод на экран имен всех пользователей заданной группы
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objGroup       ' Экземпляр объекта Group
    Dim objUser        ' Экземпляр объекта User
    Dim strResult      ' Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Связываемся с группой Пользователи компьютера Popov
    Set objGroup = GetObject("WinNT://Popov/Пользователи,group")
    
    strResult = "Все пользователи группы Пользователи на компьютере Popov:"  vbCrLf
    
    ' Перебираем элементы коллекции 
    For Each objUser In objGroup.Members()
      ' Формируем строку с именами пользователей
      strResult = strResult  objUser.Name  vbCrLf
    Next
    
    ' Вывод информации на экран
    WScript.Echo strResult
    '*************  Конец *********************************************
    Страницы:

    Сценарии WSH для доступа к службе каталогов АDSI

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

    Что касается компьютерных сетей (локальных или глобальных), здесь также уместно говорить о каталогах, содержащих объекты разных типов: зарегистрированные пользователи, доступные сетевые принтеры и очереди печати и т.д. Для пользователей сети важно уметь находить и использовать такие объекты (а их в крупной сети может быть огромное количество), администраторы же сети должны поддерживать эти объекты в работоспособном состоянии. Под службой каталога (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/2003. Естественно, для прямого доступа к разным службам каталогов приходится использовать разные инструментальные средства, что усложняет процесс администрирования сети в целом. Для решения этой проблемы можно применить технологию ADSI (Active Directory Service Interface) фирмы Microsoft, которая предоставляет набор объектов ActiveX, обеспечивающих единообразный, не зависящий от конкретного сетевого протокола, доступ к функциям различных каталогов. Объекты ADSI включаются в операционные системы Windows 2000/XP и выше.

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

    C:\Windows\Command\command.com

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

  • "LDAP://" — для службы каталогов, созданной на основе протокола LDAP (Lightweight Directory Access Protocol), в том числе для Active Directory в Windows 2000/2003;
  • "WinNT://" — для службы каталогов в сети Windows NT 4.0 или на локальной рабочей станции Windows XP/2000;
  • "NDS://" — для службы каталогов NetWare NDS (Novell Directory Service);
  • "NWCOMPAT://" — для службы каталогов NetWare Bindery.
  • Вторая часть строки ADsPath определяет расположение объекта в конкретном каталоге. Приведем несколько примеров полных строк ADsPath:

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

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

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

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

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

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

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

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

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

    Варианты строк связывания на компьютере Windows XP
    Строка 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 или VBScript, которая возвращает ссылку на объект ActiveX, находящийся во внешнем каталоге. Например (язык VBScript):

    Set objNameSpace = GetObject("WinNT:")
    Set objComputer = GetObject("WinNT://404_Popov")
    Set objUser = GetObject("WinNT://Popov/Popov,user")
    Set objGroup = GetObject("WinNT://Popov/BankUsers, group")

    Замечание

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

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

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

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

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

    Set objNameSpace = GetObject("WinNT:")

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

    objNameSpace.Filter = Array("domain")

    В цикле For Each … In … выполняется перебор всех элементов коллекции, которые являются объектами класса Domain ; название домена, хранящееся в свойстве Name, добавляется (вместе с символом разрыва строки) в переменную strResult. Сформированная таким образом переменная strResult выводится на экран с помощью метода Echo объекта WScript.

    '*******************************************************************
    ' Имя: ListDomains.vbs                                              
    ' Язык: VBScript                                                    
    ' Описание: Вывод на экран списка всех доменов локальной сети     
    '*********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objNameSpace        ' Корневой объект Namespace
    Dim objDomain           ' Экземпляр объекта Domain
    Dim strResult           ' Строка для вывода на экран
    
    'Связываемся с корневым объектом Namespace
    Set objNameSpace = GetObject("WinNT:")
    'Устанавливаем фильтр для выделения объектов-доменов
    objNameSpace.Filter = Array("domain")
    
    strResult = "Все доступные домены в сети:"  vbCrLf  vbCrLf
    
    ' Перебираем элементы коллекции 
    For Each objDomain In objNameSpace
      'Формируем строку с именами доменов
      strResult = strResult  objDomain.Name  vbCrLf
    Next
    
    'Вывод информацию на экран
    WScript.Echo strResult
    '*************  Конец *********************************************

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

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

    Set objComputer = GetObject("WinNT://Popov")

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

    Set objUser = objComputer.Create("user",strUser)

    Замечание

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

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

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

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

    '********************************************************************
    ' Имя: AddUser.vbs                                                  
    ' Язык: VBScript                                                    
    ' Описание: Создание нового пользователя компьютера                
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objComputer        ' Экземпляр объекта Computer
    Dim objUser            ' Экземпляр объекта User
    Dim strUser            ' Имя создаваемого пользователя
    
    ' Задаем имя пользователя
    strUser = "XUser"
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    ' Создаем объект класса User
    Set objUser = objComputer.Create("user",strUser)
    ' Добавляем описание созданного пользователя
    objUser.Description = "Этот пользователь создан из сценария ADSI"
    
    ' Сохраняем информацию на компьютере
    objUser.SetInfo
    '*************  Конец *********************************************

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

    '********************************************************************
    ' Имя: AddGroup.vbs                                                  
    ' Язык: VBScript                                                    
    ' Описание: Создание новой группы на компьютере
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objComputer        ' Экземпляр объекта Computer
    Dim objGroup           ' Экземпляр объекта Group
    Dim strGroup           ' Имя создаваемой группы
    
    ' Задаем имя пользователя
    strGroup = "XGroup"
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    ' Создаем объект класса Group
    Set objGroup = objComputer.Create("group",strGroup)
    ' Сохраняем информацию на компьютере
    objGroup.SetInfo
    '*************  Конец *********************************************

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

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

    ' Связываемся с пользователем XUser компьютера Popov
    Set objUser = GetObject("WinNT://Popov/XUser,user")
    ' Формируем строку с информацией о пользователе
    strResult = "Информация о пользователе XUser"  vbCrLf _
            "Имя: "  objUser.Name  vbCrLf  _
            "Описание: "  objUser.Description  vbCrLf
    ' Выводим сформированную строку на экран
    WScript.Echo strResult

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

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

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

    If Res=vbYes Then ' Нажата кнопка Да
      ' Устанавливаем новый пароль
      objUser.SetPassword "NewPassword"
      ' Сохраняем сделанные изменения
      objUser.SetInfo
    '********************************************************************
    ' Имя: UserInfo.vbs                                                 
    ' Язык: VBScript                                                    
    ' Описание: Вывод информации о пользователе компьютера и смена     
    '           его пароля                                             
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objUser      ' Экземпляр объекта User
    Dim WshShell     ' Объект WshShell
    Dim Res          ' Результат нажатия кнопки в диалоговом окне
    Dim strPassword  ' Строка с новым паролем
    Dim strResult    ' Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Связываемся с пользователем XUser компьютера Popov
    Set objUser = GetObject("WinNT://Popov/XUser,user")
    ' Формируем строку с информацией о пользователе
    strResult = "Информация о пользователе XUser"  vbCrLf _
            "Имя: "  objUser.Name  vbCrLf  _
            "Описание: "  objUser.Description  vbCrLf
    ' Выводим сформированную строку на экран
    WScript.Echo strResult
    
    ' Создаем объект WshShell
    Set WshShell = WScript.CreateObject("WScript.Shell")
    ' Запрос на изменение пароля
    Res = WshShell.Popup("Изменить пароль у XUser?",0,_
      "Администрирование пользователей",vbQuestion+vbYesNo)
    If Res=vbYes Then ' Нажата кнопка Да
      ' Устанавливаем новый пароль
      objUser.SetPassword "NewPassword"
      ' Сохраняем сделанные изменения
      objUser.SetInfo
      WScript.Echo "Пароль был изменен"
    Else
      WScript.Echo "Вы отказались от изменения пароля"
    End If  
    '*************  Конец *********************************************/

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

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

    Замечание

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

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

    Set objComputer = GetObject("WinNT://Popov")

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

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

    objComputer.Delete "user", strUser

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

    If Err.Number <> 0 Then  
      strMess="Ошибка при удалении пользователя "  strUser  vbCrLf  _
           "Код ошибки: "  Err.number  "Описание: "  Err.description
      WshShell.Popup strMess,0,"Удаление пользователя",vbCritical
    
      ' Очищаем свойства объекта Err
      Err.Clear
    Else
      ' Все в порядке
      strMess = "Пользователь "  strUser  " удален"
      WshShell.Popup strMess,0,"Удаление пользователя",vbInformation
    End If

    Как мы видим, если при вызове метода Delete произойдет какая-либо ошибка, то на экран с помощью метода Popup объекта WshShell выведется соответствующее сообщение. Если же удаление прошло успешно (свойство Number объекта Err равно нулю), то на экран также выведется соответствующее диалоговое окно.

    Процесс удаления группы в сценарии проходит аналогично.

    '********************************************************************
    ' Имя: DelUserAndGroup.vbs  
    ' Язык: VBScript                                                    
    ' Описание: Удаление пользователя и группы компьютера
    '********************************************************************
    Option Explicit
    On Error Resume Next
    
    'Объявляем переменные
    Dim objComputer          ' Экземпляр объекта Computer
    Dim strUser              ' Имя удаляемого пользователя
    Dim strGroup             ' Имя удаляемой группы
    Dim WshShell             ' Объект WshShell
    Dim strMess              Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Имя удаляемого пользователя
    strUser = "XUser"    
    ' Имя удаляемой группы
    strGroup = "XGroup"  
    
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    ' Создаем объект WshShell
    Set WshShell = WScript.CreateObject("WScript.Shell")
    
    '*************  Удаление пользователя  ***********************
    ' Удаляем пользователя
    objComputer.Delete "user", strUser
    
    ' Обрабатываем ошибки
    If Err.Number <> 0 Then  
      strMess="Ошибка при удалении пользователя "  strUser  vbCrLf  _
           "Код ошибки: "  Err.number  "Описание: "  Err.description
      WshShell.Popup strMess,0,"Удаление пользователя",vbCritical
    
      ' Очищаем свойства объекта Err
      Err.Clear
    Else
      ' Все в порядке
      strMess = "Пользователь "  strUser  " удален"
      WshShell.Popup strMess,0,"Удаление пользователя",vbInformation
    End If
    
    '*************  Удаление группы  ***********************/
    objComputer.Delete "group", strGroup
    
    ' Обрабатываем ошибки
    If Err.Number <> 0 Then  
      strMess="Ошибка при удалении группы "  strGroup  vbCrLf  _
           "Код ошибки: "  Err.number  "Описание: "  Err.description
      ' Очищаем свойства объекта Err
      Err.Clear
    Else
      ' Все в порядке
      strMess="Группа "  strGroup  " удалена"
      WshShell.Popup strMess,0,"Удаление группы",vbInformation
    End If
    '*************  Конец *********************************************/

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

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

    В приведенном в листинге 8.6 сценарии ListAllGroups.vbs для связывания с компьютером Popov мы создаем объект-контейнер objComputer, в котором содержатся все объекты рабочей станции Popov:

    Set objComputer = GetObject("WinNT://Popov")

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

    strResult = "На компьютере Popov созданы группы:"  vbCrLf   vbCrLf

    После этого в цикле For Each … In … из коллеции objComputer выбираются лишь объекты класса Group, то есть те объекты, у которых в поле Class записана строка "Group"; в strResult заносятся названия групп из поля Name:

    For Each objGroup In objComputer
      ' Выделяем объекты класса Group
      If objGroup.Class = "Group" Then
        'Формируем строку с именами групп
        strResult = strResult  objGroup.Name  vbCrLf
      End If
    Next

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

    '********************************************************************
    ' Имя: ListAllGroups.vbs
    ' Описание: Вывод на экран имен всех групп заданного компьютера 
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objComputer    ' Экземпляр объекта Computer
    Dim objGroup       ' Экземпляр объекта Group
    Dim strResult      ' Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Связываемся с компьютером Popov
    Set objComputer = GetObject("WinNT://Popov")
    
    strResult = "На компьютере Popov созданы группы:"  vbCrLf   vbCrLf
    
    ' Перебираем элементы коллекции 
    For Each objGroup In objComputer
      ' Выделяем объекты класса Group
      If objGroup.Class = "Group" Then
        'Формируем строку с именами групп
        strResult = strResult  objGroup.Name  vbCrLf
      End If
    Next
        
    'Выводим информацию на экран
    WScript.Echo strResult
    '*************  Конец *********************************************/

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

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

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

    Set objGroup = GetObject("WinNT://Popov/Пользователи,group")

    После инициализации переменной strResult мы обрабатываем в цикле For Each … In … все элементы полученной коллекции пользователей группы (данная коллекция формируется с помощью метода Members объекта Group ); на каждом шаге цикла к переменной strResult добавляется имя текущего пользователя (поле Name в объекте objUser — текущем элементе коллекции):

    strResult = "Все пользователи группы Пользователи 
     на компьютере Popov:"  vbCrLf
    ' Перебираем элементы коллекции 
    For Each objUser In objGroup.Members()
      ' Формируем строку с именами пользователей
      strResult = strResult  objUser.Name  vbCrLf
    Next

    После выхода из цикла сформированная строка strResult выводится на экран.

    '********************************************************************
    ' Имя: ListUsers.vbs                                                
    ' Язык: VBScript                                    
    ' Описание: Вывод на экран имен всех пользователей заданной группы
    '********************************************************************
    Option Explicit
    
    'Объявляем переменные
    Dim objGroup       ' Экземпляр объекта Group
    Dim objUser        ' Экземпляр объекта User
    Dim strResult      ' Строка для вывода на экран
    
    '********************** Начало *************************************
    ' Связываемся с группой Пользователи компьютера Popov
    Set objGroup = GetObject("WinNT://Popov/Пользователи,group")
    
    strResult = "Все пользователи группы Пользователи на компьютере Popov:"  vbCrLf
    
    ' Перебираем элементы коллекции 
    For Each objUser In objGroup.Members()
      ' Формируем строку с именами пользователей
      strResult = strResult  objUser.Name  vbCrLf
    Next
    
    ' Вывод информации на экран
    WScript.Echo strResult
    '*************  Конец *********************************************
    Вернуться к учебному плану