sergey vasin

The IT blog

Set-sthADAttribute — v1 — Toolmaking на примере функции для изменения значений атрибутов объекта пользователя Active Directory

leave a comment »

В первой статье этой серии мы начнем с того, что напишем функцию, задачей которой будет являться изменение значения определенного атрибута для всех пользователей указанного организационного подразделения (Organizational Unit) Active Directory.

Начнем с определения функции:

function Set-sthADAttribute
{

}

Откуда мы взяли такое имя? В соответствии с рекомендациями по созданию скриптов и функций, имя (хотя бы в общих чертах) должно отражать, что эта функция собирается делать. Причем общепринятая структура имен: Verb-Noun — Глагол-Существительное. То есть «Что_мы_делаем-С_чем_мы_это_делаем».
Список рекомендованных глаголов можно получить, введя Get-Verb.

Мы хотим изменить значение атрибута в Active Directory. Следовательно, имя функции может быть чем-то вроде Set-ADAttribute. Однако, для того, чтобы имена наших собственных функций вдруг случайно не совпали с именами уже существующих командлетов, рекомендуется добавить к существительному (тому, что после дефиса) какой-либо префикс. В моем случае — это sth. В итоге получаем: Set-sthADAttribute

Param

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

Следовательно нам нужно задать эти параметры:

function Set-sthADAttribute
{
    Param(
    $OU,
    $Attribute,
    $Value
    )
}

Параметр $OU — будет определять организационное подразделение, $Attribute — атрибут, значение которого мы собираемся изменить, $Value — его новое значение.

Мы ожидаем, что значения параметров $OU и $Attribute будут строками.
$Attribute — это имя атрибута, так что его значение будет именно строкой.

Что именно мы будем указывать в качестве значения параметра $OU, мы еще обсудим, но каждый из этих вариантов также может быть представлен в виде строки.

Для параметра $Value мы не будем указывать какой-либо конкретный тип данных, так как значения изменяемых атрибутов могут быть разного типа, поэтому в данном случае он будет зависеть от задаваемого значения.

function Set-sthADAttribute
{
    Param(
    [string]$OU,
    [string]$Attribute,
    $Value
    )
}

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

Сделаем мы это следующим образом:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    $Value
    )
}

Тут есть еще одна деталь. В данном виде мы можем задать новое значение для определенного параметра. Но мы не можем его удалить. Сделать это можно задав в качестве значения $Null, но только что добавленная запись — [Parameter(Mandatory=$True)] нам этого не позволит. Так что нам потребуется разрешить для параметра $Value указывать $Null в качестве значения. Сделать мы это можем указав для параметра еще один атрибут — [AllowNull()].

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value
    )
}

И, заканчивая с параметрами, давайте рассмотрим еще одно обстоятельство. Каждое организационное подразделение может содержать в себе еще несколько. Как мы будем поступать с объектами пользователей, находящихся во вложенных организационных подразделениях?

Предлагаю переложить этот вопрос на плечи пользователя этой функции и добавить еще один параметр — $Recursive. Тип этого параметра — [switch]. Это означает, что его значениями могут быть $True, либо $False. Причем указывать их (значения) нам вовсе не обязатьельно, так как присутствие этого ключа среди параметров будет означать, что его значение равно $True, а отсутствие, соответственно, $False.

В данном же случае его наличие будет означать, что изменение значения атрибута касается всех объектов пользователей, включая тех, что находятся во вложенных организационных подразделениях. А в его отсутствие (что будет значением по умолчанию) изменения будут касаться только непосредственно расположенных в указанном OU пользователей.

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )
}

Теперь перейдем непосредственно с содержимому функции.

Module

Для начала нам нужно проверить, что модуль ActiveDirectory присутствует, так как далее нам понадобятся входящие в него командлеты. Сделать это мы можем так:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {

    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Что мы тут делаем. Мы проверяем существование модуля ActiveDirectory при помощи командлета Get-Module.

Если бы мы писали скрипт, то мы могли бы воспользоваться выражением #Requires. Однако в функции его использование не поддерживается и поэтому проверять наличие модуля ActiveDirectory мы будем самостоятельно.

Итак, возвращаемся к проверке. Если этот модуль присутствует на системе, где мы запускаем эту функцию, то результатом выполнения командлета Get-Module будет объект этого модуля, что конструкцией if будет истолковано как $True и приведет к выполнению кода в первой части этой конструкции.

Если Get-Module не вернет ничего, это будет истолковано как $false, и выполнится код, расположенный под else, где мы выводим информацию о том, что для работы функции требуется модуль ActiveDirectory. После этого работа функции завершится.

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

Organizational Unit

Теперь нам нужно проверить существование заданного в параметре $OU организационного подразделения и, в случае его наличия, получить объект его олицетворяющий, а в случае отсутствия, выполнить какие-либо действия, сообщающие о том, что в службе каталогов Active Directory такое организационное подразделение отсутствует.

Использовать мы для этого будем еще одну конструкцию if, а в качестве условия укажем результат выполнения командлета Get-ADOrganizationalUnit. Причем, чтобы не выполнять отдельно проверку существования этого организационного подразделения и сохранение его в переменную для дальнейшего использования, мы это сделаем посредством одной операции. Вот так:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {

        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Стоит отметить, что символ ‘=’ здесь — это операция присваивания, а не сравнения. То есть, задача этого оператора — присвоить результат выполнения командлета Get-ADOrganizationalUnit переменной $OrganizationalUnit, а никак не сравнить ее текущее содержимое (которое на момент выполнения этого кода будет отсутствовать) с результатом выполнения этого командлета.

Отступая от рассматриваемой темы, упомянем, что упомянутый выше оператор сравнения в PowerShell — это ‘-eq’.

В процессе работы функции, сначала будет выполнен код, расположенный в скобках, а if будет взаимодействовать уже с его результатом. Как и в предыдущем случае, наличие какого-либо результата будет интерпретировано как $True, а его отстутвие — как $False.

Кроме того, здесь есть одна особенность. При выполнении командлета Get-ADOrganizationalUnit отсутствие указанного в качестве значения параметра -Identity организационного подразделения приведет к Terminating Error, то есть ошибке, прекращающей дальнейшее выполнение функции. Мы вернемся к этому в следующих частях серии статей.

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

$OU

Теперь давайте поговорим о значении параметра $OU.

Как видно из вышеприведенного кода, мы используем его в качестве значения параметра -Identity командлета Get-ADOrganizationalUnit. Следовательно, чтобы определить, что нам следует указывать для параметра $OU при вызове нашей функции, нам нужно узнать, какие значения может принимать параметр -Identity командлета Get-ADOrganizationalUnit.

Узнать мы это можем следующим образом:

Get-Help -Name Get-ADOrganizationalUnit -Parameter Identity

В качестве результата выполнения вышеприведенной команды мы получим часть справочной информации для командлета Get-ADOrganizationalUnit, касающуюся параметра -Identity. Оттуда мы узнаем, что этот параметр может принимать DistinguishedName и GUID определенного организационного подразделения.

В таком случае мы тоже будем ограничивать возможности нашей функции, и оставим возможность указывать любой из вариантов.

SearchScope

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

Ранее мы уже определили параметр — $Recursive — который позволит пользователю функции указать, собирается ли он изменять атрибуты только у непосредственно входящих в OU объектов пользователей или же изменение должно затронуть все объекты (опять же, пользователей) в иерархии. Теперь нам нужно связать его с командлетом, получающим из Active Directory эти объекты.

Получать объекты пользователей мы будем при помощи командлета Get-ADUser. За глубину поиска в нем (равно как и еще в нескольких командлетах Active Directory) отвечает параметр -SearchScope.

Принимает он три значения: «Base», «OneLevel» и «Subtree».

«Base» указывает на то, что возвращен будет только объект, расположенный на вершине иерархии, если он является запрашиваемым объектом. Например:

Get-ADOrganizationalUnit -Filter * -SearchBase 'OU=OU1,DC=domain,DC=com' -SearchScope Base 

Здесь мы указали обязательный параметр -Filter. Его значение — «*» — предписывает возвращать любое встретившееся организационное подразделение.

Параметр -SearchBase указывает тот объект в иерархии, откуда следует начинать поиск. А параметр -SearchScope вкупе со значением Base определяет, что нас не интересует ничего из того, что находится в указанном организационном подразделении (равно как и во вложенных OU), а только объект, находящийся на вершине иерархии, в данном случае — ‘OU=OU1,DC=domain,DC=com’.

Следовательно, мы можем предположить, что выполнение команды

Get-ADUser -Filter * -SearchBase 'OU=OU1,DC=domain,DC=com' -SearchScope Base 

не возвратит нам каких-либо результатов.

Но, возвращаемся к значениям паарметра -SearchScope.

«OneLevel», как можно догадаться, указывает что результатом выполнения командлета будет вывод только тех объектов пользователя, что расположены непосредственно в заданном организационном подразделении.

«Subtree» же, являющееся значением по умолчанию, предписывает вывести все объекты пользователя, расположенные как непосредственно в заданном OU, так и в любых организационных подразделениях, расположенных ниже по иерархии.

Как мы помним, тип параметра $Recursive — [switch], и это означает, что он может принимать значения $True либо $False. Нам нужно, чтобы наличие $True в этом параметре приводило к тому, что в командлете Get-ADUser параметр -SearchScope был указан как «Subtree», а значение $False — определяло бы его как «OneLevel».

Сделаем мы это так:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Теперь нужное нам значение параметра -SearchScope хранится в переменной $SearchScope и именно ее мы будем использовать в качестве аргумента командлета Get-ADUser.

Get-ADUser

Перейдем к получению объектов пользователя. Опять же, кроме, непосредственно, получения объектов и сохранения их в переменную, нам нужно также удостовериться, что командлет вернул какие-либо результаты.

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

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }

            if($users = @(Get-ADUser -Filter * -SearchBase $OrganizationalUnit.DistinguishedName -SearchScope $SearchScope))
            {

            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

В качестве аргумента параметра -Filter мы указали «*», так как нам нужны все объекты, расположенные в организационном подразделени.

Значение параметра -SearchBase мы определили как DistinguishedName интересующего нас объекта организационного подразделения — $OrganizationalUnit.DistinguishedName. Именно это OU и будет вершиной иерархии для поиска объектов пользователя.

А для параметра -SearchScope мы указали созданную нами чуть ранее переменную $SearchScope, содержимое которой («OneLevel» или «Subtree») зависит от значения параметра функции -Recursive.

Кроме того, при помощи оператора @() мы явным образом определили переменную $users как массив, даже если результатом выполнения командлета Get-ADUser будет только один объект. Это нам пригодится чуть позже.

Как мы уже говорили при рассмотрении кода для получения объекта организационного подразделения, сначала будет выполнен командлет (в данном случае Get-ADUser), затем его результат будет присвоен переменной $users, а после этого if будет решать, выполнять ли следующий за ней код.

Если в организационном подразделении присутствуют какие-либо объекты — это будет трактоваться как $True и код будет выполнен. Если же в указанном OU не обнаружилось ни одного объекта пользователя, if определит их отсутствие как $False и работа функции будет завершена.

Property

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

Сделаем мы это так:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }

            if($users = @(Get-ADUser -Filter * -SearchBase $OrganizationalUnit.DistinguishedName -SearchScope $SearchScope))
            {
                if(Get-ADUser -Identity $users[0] -Properties $Attribute)
                {

                }
            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Здесь мы предполагаем, что в переменной $users есть хотя бы один объект пользователя (так как в противном случае эта часть кода была бы пропущена) и обращаемся к первому объекту в массиве с целью получить значение того атрибута, которое мы и собираемся менять.

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

Если такого атрибута нет, то, как и в случае с получением объекта организационного подразделения, командлет выдаст Terminating Error, что приведет к прекращению работы функции.

Parameter

Теперь давайте поговорим о способах, при помощи которых командлет Set-ADUser может задавать значения определенных атрибутов объектов пользователя.

Один из подходов — это использование параметров командлета для задания значения определенного атрибута.

Например:

Set-ADUser -Identity User -City "City"

Но параметры существуют далеко не для всех возможных атрибутов объекта пользователя. Если вы хотите изменить какой-либо атрибут, для которого параметр не определен, вы можете использовать параметры: -Remove, -Add, -Replace и -Clear. В качестве аргумента они принимают специальным образом созданную хэш-таблицу где указываются подлежащие изменению атрибуты и их значения.

О чем тут стоит сказать, так это о том, что в этих хэш-таблицах атрибуты идентифицируются посредством LDAPDisplayName, что не всегда совпадает тем, как их обозначает PowerShell. Например, LDAPDisplayName для «City» — это «l». Но об этом в другой раз.

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

Получить список параметров определенного командлета можно при помощи Get-Command, например так:

(Get-Command -Name Set-ADUser).Parameters.Keys

Добавим условие в нашу функцию:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }

            if($users = @(Get-ADUser -Filter * -SearchBase $OrganizationalUnit.DistinguishedName -SearchScope $SearchScope))
            {
                if(Get-ADUser -Identity $users[0] -Properties $Attribute)
                {
                    if(($Attribute -in (Get-Command -Name Set-ADUser).Parameters.Keys))
                    {

                    }
                    else
                    {
                        Write-Output "No such Parameter in Set-ADUser cmdlet."
                    }
                }
            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

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

ForEach

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

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }

            if($users = @(Get-ADUser -Filter * -SearchBase $OrganizationalUnit.DistinguishedName -SearchScope $SearchScope))
            {
                if(Get-ADUser -Identity $users[0] -Properties $Attribute)
                {
                    if(($Attribute -in (Get-Command -Name Set-ADUser).Parameters.Keys))
                    {
                        ForEach($user in $users)
                        {

                        }
                    }
                    else
                    {
                        Write-Output "No such Parameter in Set-ADUser cmdlet."
                    }
                }
            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Теперь, в рамках ForEach, к каждому объекту пользователя из массива переменной $users, мы можем обратиться, используя переменную $user.

Set-ADUser

Ну что ж, перейдем непосредственно к изменению значения заданного атрибута.

Что у нас есть. Объекты пользователей, подлежащих изменению, как уже говорилось чуть выше, доступны через переменную $user, нужный атрибут находится в переменной $Attribute, а его значение — в переменной $Value.

Однако есть одна сложность. Мы уже решили, что для изменения значения какого-либо атрибута мы будем использовать одноименный параметр командлета Set-ADUser, то есть, если мы изменяем, к примеру, атрибут User, то использовать для этого мы будем параметр User. В чем эта сложность состоит, так это в том, что мы не сможем в качестве имени параметра указать переменную. То есть, если мы введем следующую команду:

Set-ADUser -Identity $User -$Attribute $Value

выполняться она откажется.

Поэтому давайте сначала составим команду в том виде, в котором она должна выполняться, назначим ее переменной $Command, а уже потом инициируем ее выполнение.

Сделаем мы это так:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }

            if($users = @(Get-ADUser -Filter * -SearchBase $OrganizationalUnit.DistinguishedName -SearchScope $SearchScope))
            {
                if(Get-ADUser -Identity $users[0] -Properties $Attribute)
                {
                    if(($Attribute -in (Get-Command -Name Set-ADUser).Parameters.Keys))
                    {
                        ForEach($user in $users)
                        {
                            $Command = "Set-ADUser -Identity `$User -$Attribute `$value"
                            Invoke-Expression $Command
                        }
                    }
                    else
                    {
                        Write-Output "No such Parameter in Set-ADUser cmdlet."
                    }
                }
            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Что мы тут сделали. Мы представили командлет Set-ADUser со всеми нужными нам параметрами в качестве строки. Так как мы использовали двойные кавычки, полученная в итоге строка вместо переменной $Attribute будет содержать уже непосредственно имя параметра.

Однако нам вовсе не обязательно заранее раскрывать значения переменных $User и $Value, поэтому перед каждым из них мы указали escape-символ PowerShell — «`», он же grave, он же backtick.

Тем самым, если к примеру в качестве значения параметра -Attribute мы указали City, в переменной $Command будет содержаться следующая строка:

Set-ADUser -Identity $User -City $Value

Для того чтобы инициировать выполнение команды, которая сейчас представлена в качестве строки, мы используем командлет Invoke-Expression. Это приведет к тому, что для всех пользователей, входящих в определенное организационное подразделение, атрибуту, указанному в параметре -Attribute, будет присвоено значение, заданное в параметре -Value.

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

Get-ADUser -Identity $user -Properties $Attribute

Полный текст функции будет выглядеть следующим образом:

function Set-sthADAttribute
{
    Param(
    [Parameter(Mandatory=$True)]
    [string]$OU,
    [Parameter(Mandatory=$True)]
    [string]$Attribute,
    [Parameter(Mandatory=$True)]
    [AllowNull()]
    $Value,
    [switch]$Recursive = $false
    )

    if(Get-Module ActiveDirectory -ListAvailable)
    {
        if($OrganizationalUnit = Get-ADOrganizationalUnit -Identity $OU)
        {
            if($Recursive)
            {
                $SearchScope = 'Subtree'
            }
            else
            {
                $SearchScope = 'OneLevel'
            }

            if($users = @(Get-ADUser -Filter * -SearchBase $OrganizationalUnit.DistinguishedName -SearchScope $SearchScope))
            {
                if(Get-ADUser -Identity $users[0] -Properties $Attribute)
                {
                    if(($Attribute -in (Get-Command -Name Set-ADUser).Parameters.Keys))
                    {
                        ForEach($user in $users)
                        {
                            $Command = "Set-ADUser -Identity `$User -$Attribute `$value"
                            Invoke-Expression $Command
                            Get-ADUser -Identity $user -Properties $Attribute
                        }
                    }
                    else
                    {
                        Write-Output "No such Parameter in Set-ADUser cmdlet."
                    }
                }
            }
        }
    }

    else
    {
        Write-Output "ActiveDirectory module required"          
    }
}

Execute

Воспользоваться нашей новой функцией мы сможем, например, так:

Set-sthADAttribute -OU "OU=OU1,DC=domain,DC=com" -Attribute Company -Value TheCompany

Или так:

Set-sthADAttribute -OU "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" -Attribute Deprtment -Value SomeDepartment -Recursive

где XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX — это GUID нужного нам организационного подразделения.

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


Страницы в социальных сетях:

Twitter: https://twitter.com/vsseth
Facebook: https://fb.com/inpowershell
VKontakte: https://vk.com/inpowershell


Реклама

Written by Сергей Васин

Апрель 26, 2017 в 14:07

Опубликовано в Active Directory, PowerShell

Добавить комментарий

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

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s