Share via


Расширяем Active Directory Powershell

Сегодня я бы хотел показать, как можно использовать силу PowerShell V2 и модуля Active Directory, и быстро писать мощные, профессиональные командлеты (со встроенной справкой, позиционными параметрами, приглашениями показывающими настройки по умолчанию, обработкой ошибок и т.д.) для AD.

 

Несколько недель назад один из моих коллег (Александр Лаш - Alexander Lash) показал мне великолепную возможность PowerShell V2 под названием Script Cmdlets. С ее помощью можно писать полнофункциональные командлеты внутри модуля с помощью самого Powershell! Я подумал о том, что стоит поэкспериментировать немного с этим и сделать несколько командлетов, которые могут расширить функциональность командлетов AD. Итогом экспериментов стал новый модуль ActiveDirectoryExtension, в котором я и некоторые члены моей команды планируем добавить функции/командлеты, сделанные с помощью командлетов модуля Active Directory Module.

Первый набор командлетов, который я публикую сегодня – это расширение командлетов Get-ADUser, Get-ADGroup, которое поддерживает в качестве идентификаторов имена учетных записей в стиле NT4 (domain\username) и UPN (UserPrincipalName, например, username@domain.com).

 

Вот пример использования нового набора командлетов. Перед всеми существительными используемыми в названиях команд, установлен префикс “XAD”, что означает eXtending AD(расширение AD).

Загружаем модуль ActiveDirectoryExtension в память

Запускаем ActiveDirectoryExtensions.ps1 в консоли Powershell и импортируем модуль ActiveDirectoryExtensions. Полный текст скрипта и инструкции по его загрузке приведены ниже.

PS C:\> C:\ActiveDirectoryExtension.ps1
PS C:\> import-module ActiveDirectory

Назаметку : Скопируйте вышеприведенные команды в файл $PROFILE,тогда ActiveDirectory и ActiveDirectoryExtension будут всегда загружаться при открытии консоли Powershell.

Примеры команд с использованием новых командлетов расширения

 

 PS C:\> Get-XADUser administrator
PS C:\> Get-XADUser fabrikam\administrator       ## имя в стиле NT4. должно работать при обращении к другим лесам и доменам.
PS C:\> Get-XDAUser administrator@fabrikam.com   ## UPN. ВНИАНИЕ: имя UserPrincipalName должно быть предварительно настроено для учетной записи, чтобы это работало. 
                                                 ## Должно работать при обращении к другим доменам. 
PS C:\> Get-XADComputer myMemberServer *         ## Извлекает весь набор атрибутов объекта computer, идентифицированного как myMemberServer.
PS C:\> Get-XADComputer myMemberServer *  | Out-SortADProperties     ## Сортирует и отображает все свойства, найденные для объекта, в виде строки.
PS C:\> Get-PossibleLdapAttributes user        ## Выводит все атрибуты Ldap, которые могут быть установлены для объекта user
PS C:\> Get-PossibleLdapAttributes computer    ## Выводит все атрибуты Ldap, которые могут быть установлены для объекта computer
PS C:\> Get-PossibleLdapAttributes group       ## Выводит все атрибуты Ldap, которые могут быть установлены для объекта group
PS C:\> Get-PossibleLdapAttributes msDS-ManagedServiceAccount  ## Выводит все атрибуты Ldap, которые могут быть установлены для объекта service account

 

Скрипт

Вот полный скрипт:

ВНИМАНИЕ: Этот скрипт сделан только для подтверждения концепции и не планировался для использования в действующей инфраструктуре.

001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 new-module -name ActiveDirectoryExtension -scriptblock {## Описание: Эта функция сортирует все свойства, найденные в ADEntity, и # записывает их в консоль в виде строки.# Протестировано в: Windows 2008 R2 Beta.# function Out-SortADProperties() {        foreach ($msADE in $input) {        $msADEProps = $msADE.PropertyNames | sort        if ($msADEProps -ne $null) {            foreach ($msADEProp in $msADEProps) {                $msADEProp.ToString().PadRight(23) + ": " + $msADE[$msADEProp]            }        }    }}## Описание: Эта функция выводит все атрибуты Ldap, которые могут быть установлены # для объекта типа objectClass.# Протестировано в: Windows 2008 R2 Beta.# function Get-PossibleLdapAttributes() {    Param ([Parameter(Mandatory=$true, Position=0)] [String] $ObjectClass)    $rootDSE = Get-ADRootDSE    $schemaObject = get-adobject  -filter { ldapdisplayname -like $ObjectClass } -Properties mayContain, SystemMayContain, SubClassOf -searchbase  $rootDSE.SchemaNamingContext    $schemaObject.MayContain    $schemaObject.SystemMayContain    if ($ObjectClass -ne "top" -and $schemaObject.SubClassOf -ne "" -and $schemaObject.SubClassOf -ne $null) {        Get-PossibleLdapAttributes $schemaObject.SubClassOf    }}## Описание: Следующие функции – это расширения над командлетами Get-ADUser, # Get-ADGroup, Get-ADComputer b Get-ADServiceAccount.# В дополнение ко всем поддерживаемым видам идентификаторов для Get-ADUser, эта функция# поддерживает имена в стиле NT4 (например: fabrikam\administrator)# и имена UserPrincipalName - UPN (например: administrator@fabrikam.com)# ВНИМАНИЕ: Имена в стиле NT4 будут работать между разными доменами и лесами,# имена UPN будут работать только между разными доменами.# Проверено в: Windows 2008 R2 Beta.# function Get-XADUser() {    Param (        [Parameter(Mandatory=$true,                    Position=0,                   ValueFromPipeline=$true,                   HelpMessage="Идентификация объекта User. ВНИМАНИЕ: Поддерживаются имена в стиле NT4 (такие как fabrikam\administrator) и UPN (такие как administrator@fabrikam.com)"                   )]        [Object] $Identity,        [Parameter(Mandatory=$false,                    Position=1,                   HelpMessage="Список извлекаемых свойств"                   )]        [Object] $Properties    )    Get-XADPrincipal -Identity $Identity -ObjectType "ADUser" -Properties $Properties}function Get-XADGroup() {    Param (        [Parameter(Mandatory=$true,                    Position=0,                   ValueFromPipeline=$true,                   HelpMessage="Идентификация объекта Group. ВНИМАНИЕ: Поддерживаются имена в стиле NT4 Style (такие как fabrikam\mymachine)"                   )]        [Object] $Identity,        [Parameter(Mandatory=$false,                    Position=1,                   HelpMessage="Список извлекаемых свойств"                   )]        [Object] $Properties    )    Get-XADPrincipal -Identity $Identity -ObjectType "ADGroup" -Properties $Properties}function Get-XADComputer() {    Param (        [Parameter(Mandatory=$true,                    Position=0,                   ValueFromPipeline=$true,                   HelpMessage="Идентификация объекта Computer. ВНИМАНИЕ: Поддерживаются имена в стиле NT4 Style (такие как fabrikam\mymachine)"                   )]        [Object] $Identity,        [Parameter(Mandatory=$false,                    Position=1,                   HelpMessage="Список извлекаемых свойств"                   )]        [Object] $Properties    )    Get-XADPrincipal -Identity $Identity -ObjectType "ADComputer" -Properties $Properties}function Get-XADServiceAccount() {    Param (        [Parameter(Mandatory=$true,                    Position=0,                   ValueFromPipeline=$true,                   HelpMessage="Идентификация объекта ServiceAccount. ВНИМАНИЕ: Поддерживаются имена в стиле NT4 (такие как fabrikam\svcacct1)"                   )]        [Object] $Identity,        [Parameter(Mandatory=$false,                    Position=1,                   HelpMessage="Список извлекаемых свойств"                   )]        [Object] $Properties    )    Get-XADPrincipal -Identity $Identity -ObjectType "ADServiceAccount" -Properties $Properties}## Внутренняя служебная функция#function GetServer() {   Param ([String] $serverName)   if ($serverName -ne $null -and $serverName -ne "") {       $portSeparatorInd = $serverName.IndexOf(":")       if ($portSeparatorInd -ge 0) {           $serverName.SubString(0, $portSeparatorInd)       }        else {           $serverName       }   }   else {       $rootdse = get-adrootdse       $rootdse.dnsHostName   }}## Внутренняя служебная функция## Описание: Это служебная функция, которая является надстройкой над Get-ADUser,# Get-ADGroup и т.д. Протестировано в: Windows 2008 R2 Beta.# function Get-XADPrincipal() {    [CmdletBinding(ConfirmImpact="Low")]    Param (        [Parameter(Mandatory=$true,                    Position=0,                   ValueFromPipeline=$true,                   HelpMessage="Идентификация учетной записи. ВНИМАНИЕ: Поддерживаются имена в стиле NT4 (такие как fabrikam\administrator)"                   )]        [Object] $Identity,        [Parameter(Mandatory=$true,                    Position=1,                   ValueFromPipeline=$false,                   HelpMessage="Тип учетной записи. Поддерживаемые типы: G или ADGroup, U или ADUser, C или ADComputer, S или ADServiceAccount"                   )]        [String] $ObjectType,        [Parameter(Mandatory=$false,                    Position=2,                   HelpMessage="Список извлекаемых свойств"                   )]        [Object] $Properties     )            BEGIN {    }    PROCESS {        if ($ObjectType -eq "ADUser" -or $ObjectType -eq "u") {            $commandStr = "Get-ADUser "        }        elseif ($ObjectType -eq "ADGroup"-or $ObjectType -eq "g") {            $commandStr = "Get-ADGroup "        }        elseif ($ObjectType -eq "ADComputer"-or $ObjectType -eq "c") {            $commandStr = "Get-ADComputer "         }        elseif ($ObjectType -eq "ADServiceAccount"-or $ObjectType -eq "s") {            $commandStr = "Get-ADADServiceAccount "         }        if ($Identity.GetType() -eq [String] ) {            #            # Допустимые имена в стиле NT4 всегда содержат обратный слэш \            # Проверяем отсутствие символа '=' .. чтобы не обработать DN с \.            #            if ($Identity.Contains("\") -and ! $Identity.Contains("=") ) {                [Int] $slashIndex = $Identity.IndexOf("\")                $xNewServer      = $Identity.SubString(0, $slashIndex)                $xNewIdentity = $Identity.SubString($slashIndex + 1)                $commandStr += " -Identity $xNewIdentity -Server $xNewServer "             }            #            # Допустимые имена UPN всегда содержат @            # Проверяем отсутствие символа '=' .. чтобы не обработать DN с @.            #            elseif ($Identity.Contains("@") -and ! $Identity.Contains("=") ) {                $xNewServer = (GetServer $null) + ":3268"     # Обращаемся к глобальному каталогу для разрешения имен UPN                $xFilter = " { userPrincipalName -eq '$Identity' } "                $commandStr += " -Filter $xFilter -Server $xNewServer "             }             else {               $commandStr += " -Identity $Identity "            }        }        else {             $commandStr += " -Identity '" + $Identity.ToString() + "'"        }        if ($Properties -ne $null) {            $commandStr += " -Properties $Properties "        }        $scriptBlock = [ScriptBlock]::Create( $commandStr )        $scriptBlock.Invoke()    }    END {    }}}

 

 

 

На здоровье!
Swami

--
Swaminathan Pattabiraman [MSFT]
Developer – Active Directory Powershell Team

 

Перевод: Илья Лушников

ActiveDirectoryExtension.ps1.txt