Расширяем 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
Перевод: Илья Лушников