.

В опубликованной в этом же номере статье «PowerShell и Active Directory» описано, как загрузить и получить доступ к модулю Active Directory, одному из новых компонентов Windows Server 2008 R2 и Windows 7. В данной статье приводится два примера использования модуля для автоматизации массовых операций.

Всеобъемлющий поиск

Одна из самых распространенных задач — поиск объектов AD, соответствующих определенным критериям, например по значению атрибута или состоянию учетной записи компьютера. Давайте начнем изучение модуля Active Directory с такой задачи.

Предположим, нам требуется найти все отключенные учетные записи компьютеров в трех организационных единицах (OU) в домене AD и переместить их в OU временного хранения, чтобы позднее избавиться от них. Один из способов это сделать — подготовить список OU, в которых будет проведен поиск, найти все отключенные учетные записи компьютеров в этих OU и перемещать их по мере обнаружения. Может показаться, что проще выполнить поиск во всем домене, но благодаря использованию списка OU сокращается количество проверяемых объектов и появляется возможность экспериментировать с входными данными для команд PowerShell (освоить эти приемы полезно).

Поэтому сначала следует выбрать способ ввода имен OU в PowerShell. Один из вариантов — записать имена в файл с разделением запятыми (CSV), а затем прочитать их с помощью команды Import-CSV и сохранить в переменной. Этот подход удобен, если в команду нужно ввести длинный список элементов. Однако, поскольку нужно выполнить поиск только в трех OU, я воспользовался массивом для хранения имен.

Имена OU становятся отправной точкой поиска (базой поиска — search base). Обычно база поиска принимает форму имени (DN) LDAP — например, OU=Marketing, DC=cpandl, DC=com — и именно эти данные сохраняются в массиве. Следующая команда создает массив OU, в котором будет выполнен поиск:

$searchBase =
   "OU=Test, DC=cpandl, DC=com",
   "OU=Sales, DC=cpandl, DC=com",
   "OU=QA, DC=cpandl, DC=com"

Команда показана на нескольких строках, но ее нужно вводить в одной строке. То же относится и к другим командам. Данная команда назначает строковый массив переменной $searchBase. Чтобы убедиться, что массив сформирован, выполните команду:

$searchBase [0]

Должен быть возвращен первый элемент массива (OU=Test, DC=cpandl, DC=com).

После этого требуется команда для поиска. Для решения данной задачи была выбрана команда Search-ADAccount. Ее достоинство в наличии всех параметров, необходимых для поиска неактивных учетных записей компьютеров, поэтому нет необходимости строить сложный фильтр LDAP. Например, чтобы найти все неактивные учетные записи компьютеров в домене, достаточно выполнить

Search-ADAccount
-AccountDisabled -ComputersOnly

На экране показано, как могут выглядеть результаты.

 

Экран. Получение списка отключенных учетных записей компьютеров с помощью Search-ADAccount

Наконец, нужна команда, которая перемещает отключенные компьютеры в OU хранения. Для перемещения используется команда Move-ADObject, с помощью которого нетрудно перенести объект или контейнер из одного места в другое внутри AD. Например, в следующей команде перемещается учетная запись компьютера в OU с именем BitBucket:

Move-ADObject -Identity
   "Cn=nT4, Cn=Computers, DC=cpandl,
   DC=com"
   -TargetPath
   "OU=BitBucket, DC=cpandl, DC=com"

В этом случае параметр -Identity указывает отличительное имя объекта, который требуется переместить (рабочая станция с именем NT4), а параметр -TargetPath указывает имя OU, в которую перемещается объект. Все очень просто.

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

Самый простой подход — выполнить поиск неактивных учетных записей компьютеров в одной OU, затем использовать встроенные возможности конвейерного выполнения для передачи результатов в команду, которая переместит учетные записи. Этого можно достичь с помощью следующего программного кода:

Search-ADAccount -AccountDisabled
   -SearchBase
   "OU=SDM, DC=cpandl, DC=com" |
   Move-ADObject -TargetPath
   "OU=BitBucket, DC=cpandl, DC=com"

В данном фрагменте команда Search-ADAccount используется для поиска отключенных учетных записей компьютеров в организационной единице SDM. Полученный список учетных записей передается в команду Move-ADObject, которая перемещает учетные записи в организационную единицу BitBucket. Обратите внимание, что у команды Move-ADObject отсутствует параметр -Identity, так как конвейер автоматически передает имя каждой отключенной учетной записи компьютера, и нет необходимости указывать их явно.

Недостаток такого подхода в том, что приходится вводить эту команду для каждой OU в списке. Чтобы преодолеть этот изъян, пригодится массив $searchBase. Используя массив, можно подготовить цикл обработки списка организационных единиц:

foreach ($ou in $searchBase)
   {Search-ADAccount -AccountDisabled
   -ComputersOnly -SearchBase $ou |
   Move-ADObject -TargetPath
   "OU=BitBucket, DC=cpandl, DC=com"}

В цикле выполняются следующие действия. Сначала с помощью команды ForEach-Object (псевдоним foreach) перебираются все имена OU в списке, сохраненном в $searchBase. Для каждой OU в $searchBase вызывается команда Search-ADAccount для поиска отключенных учетных записей компьютеров в этой организационной единице. Выходные данные передаются команде Move-Object, которая выполняет перемещение. Конечный результат — все отключенные учетные записи компьютеров перемещаются из трех OU в организационную единицу BitBucket.

Внесение массовых изменений

Вторая задача, заслуживающая внимания: массовые изменения в объектах AD. Например, иногда требуется изменить определенный атрибут большого числа объектов, выбранных на основе какого-нибудь другого критерия. Опишем задачу, а потом рассмотрим способы ее решения.

Пусть нужно найти всех пользователей, членов группы Marketing Employees. Для каждого пользователя нужно записать строку «FTE» в атрибут employeeType.

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

  • Прочитать атрибут memberOf каждого пользователя, чтобы определить, является ли данный пользователь членом конкретной группы. Таким образом не всегда удается определить косвенное членство (через группы, которые являются членами других групп), но будет сделан шаг к этой цели. Если требуются сведения о косвенном членстве, можно прочитать атрибут tokenGroups пользователя (этот атрибут специального назначения представляет как прямое, так и косвенное членство в группах). Он существует в Windows Server 2003 AD и более новых версиях.
  • Выполнить поиск в каждой группе, проверяя атрибут членов, чтобы найти прямых членов этой группы. Нужно также проверить членство каждой группы, вложенной в другую группу. К счастью, выполнить эту задачу с помощью модуля Active Directory несложно. В частности, команда Get-ADGroupMember располагает параметром -Recursive для обнаружения всех косвенных членов группы.

Второй вариант обеспечивает более масштабируемое решение для поставленной задачи, поэтому будет использоваться именно он.

Затем следует выбрать оптимальный способ изменить атрибуты объектов пользователей. Для этого применяется команда Set-ADUser. Эта команда позволяет изменить свойства учетных записей пользователей. Ее набор именованных параметров содержит часто изменяемые параметры. Но можно изменить и многие другие свойства учетной записи пользователя с применением универсальных параметров? Add, -Replace, -Clear и -Remove.

Атрибут employeeType не принадлежит к числу именованных параметров Set-ADUser, поэтому приходится применять универсальные параметры. При использовании этих параметров важно знать, что рассматривается атрибут, установки которого не отличаются от атрибута, уже имеющего значение. Поэтому следует использовать параметр -Add, если атрибут не установлен, и параметр -Replace, если атрибут уже существует.

Итак, теперь все готово для массовых изменений атрибута employeeType на основе членства пользователей в группах, и можно приступать к их объединению. И вновь можно использовать конвейер PowerShell:

Get-ADGroupMember
-Identity "Marketing Employees"
-Recursive |
where {$_.employeeType
-eq $null} |
Set-ADUser -Add
@{employeeType = "FTE"}
Get-ADGroupMember
-Identity "Marketing Employees"
-Recursive |
where {$_.employeeType
-ne $null} |
Set-ADUser-Replace
@{employeeType = "FTE"}

Рассмотрим действия, выполняемые этими командами. В первой команде используется Get-ADGroupMember с параметром -Recursive для получения всех прямых и косвенных членов группы Marketing Employees в домене. Затем вывод пересылается команде Where-Object (псевдоним as where), который проверяет значение атрибута employeeType члена группы (если NULL, значит значение не задано). Если значение равно NULL, член передается команде Set-ADUser, и атрибуту присваивается значение. Поскольку employeeType не относится к числу именованных параметров Set-ADUser и не содержит значения, ему присваивается значение FTE с помощью параметра -Add. Сложность при использовании универсальных параметров заключается в том, что необходимо передать хеш-таблицу, содержающую имя и значение атрибута. Хеш-таблица представляет собой просто пару ключ-значение, которую можно определить, ограничив ее конструкцией @{}, как в случае @{employeeType = "FTE"}.

Вторая команда в основном похожа на первую, но в измененном операторе clause выполняется проверка employeeType на NULL (если нет, то атрибут уже имеет значение). Если значение отличается от NULL, член передается в команду Set-ADUser. На этот раз для замены существующего значения на FTE используется универсальный параметр -Replace. И опять для нового значения используется хеш-таблица.

Как видно из двух примеров, поиск объектов AD легко выполнить с помощью Search-ADAccount, а перемещение — с использованием Move-ADObject. Команда Get-ADGroupMember удобна для рекурсивного извлечения всех прямых и косвенных членов группы; до появления PowerShell это была весьма трудоемкая задача. А с помощью Set-ADUser можно быстро изменить членство в группе.

В целом модуль Active Directory полезен при выполнении массовых операций с AD. Команды — мощный встроенный механизм для выполнения большинства задач автоматизации. Рекомендую изучить команды модуля, список которых можно получить, если ввести

Get-Command -Module ActiveDirectory

c консоли PowerShell.

Даррен Мар-Элиа (darren@sdmsoftware.com) — внештатный редактор Windows IT Pro, главный инженер и основатель компании SDM Software. Ведет сайт, посвященный проблемам групповых политик (www.gpoguy.com)