Всем администраторам Active Directory периодически приходится сталкиваться с рутинными задачами, которые хотелось бы так или иначе автоматизировать. Как правило, это делается с использованием скриптов на наиболее известных языках программирования: VBScript, Jscript, PowerShell. Последний я считаю наиболее удобным. Благодаря некоторым из его особенностей те же процедуры, которые занимают в VBScript десяток строк и требуют понимания работы WMI, LDAP и еще многих китайских слов – в PowerShell занимает всего пять строк и требуют всего лишь знания программирования на уровне школьных уроков информатики. В настоящей статье мы рассмотрим типовые задачи администрирования Active Directory, и их автоматизацию с помощью PowerShell.
P.S. Статья рассчитана на полных, или почти полных «чайников», пару раз видевших или где-то слышавших о PowerShell. На звание Терминатора не претендую, по сему просьба ногами не пинать.
Общие положения
Предполагается, что читатели уже хотя бы немного знакомы с оболочкой PowerShell и написанием скриптов. Тех, кто не знаком – хотелось бы отослать к списку ресурсов в конце статьи.
В первую очередь, необходимо заметить, что для того, чтобы все нормально работало – необходимо иметь хотя бы один контроллер домена Windows Server 2008 R2 с установленной компонентой ActiveDirectory Web Services. Увы и ах, Windows Server 2003 уходит на свалку истории. Для работы с модулем ad_powershell необходимо установить Remote Server Administration Tools, его так же можно установить на рабочем компьютере и запускать скрипты оттуда. Разумеется, ОС на компьютере должна быть не ниже Windows 7. На контроллерах домена Windows Server 2008 R2 необходимые компоненты уже установлены.
Перед тем, как выполнять скрипты – необходимо установить политику выполнения скриптов. По умолчанию, в целях безопасности включена политика Restricted, что означает, что на данном компьютере вообще запрещен запуск любых PowerShell-скриптов. О том, какие еще бывают политики выполнения – можно почитать в мануале:
Get-Help Set-ExecutionPolicy –Detailed
В нашем случае я рекомендую установить политику RemoteSigned, что позволит запускать любые собственноручно написанные скрипты, при этом запуск скриптов, скачанных из Интернета будет возможен только при наличии цифровой подписи с доверенным сертификатом. Запустите оболочку PowerShell с правами администратора (Run as Administrator) и выполните команду
Set-ExecutionPolicy RemoteSigned
Можно так же выбрать политику Unrestricted, что вообще позволит запускать любой скрипт, независимо от того, откуда он взялся – но я делать этого не рекомендую из соображений безопасности.
Теперь можно проверить работу скриптов – написать простейший скрипт «Hello World!». Я предпочитаю пользоваться PowerShell ISE, хотя можно писать и в простейшем Notepad’е. PowerShell ISE – удобная среда програмирования для PowerShell с возможностью отладки. Входит в состав ОС Wondows 7 и 2008 R2. Вобщем, рекомендую.
Теперь переходим непосредственно к автоматизации. Для того, чтобы создать объекты в Active Directory, или изменить какие-либо свойства, нам необходим список объектов со всеми необходимыми параметрами. Например, список пользователей может содержать следующие парамеры: Имя, Фамилия, Логин, Пароль. Проще всего для этого использовать CSV-файл. CSV – это текстовый файл, содержащий список объектов (например – пользователей), с разделением параметров каким-либо символом (как правило, это запятая «,», хотя может быть и точка с запятой, знак табуляции и т.д.). Каждый объект обозначается одной строчкой. Так же, первая строчка может содержать список параметров.
Пример:
Name;Surname;Login;Password
Ivan,Ivanov;i.ivanov;p@ssw0rd1
Petr,Petrov;p.petrov;p@ssw0rd2
Sidor;Sidorov;s.sidorov;p@ssw0rd3
Чтобы получить список объектов из CSV-файла, используется командлет Import-CSV:
$Users = Import-CSV “c:\temp\users.csv”
Такой файл можно создать и в блокноте, но проще всего будет использовать Microsoft Excel. В Excel необходимо при сохранении файла выбрать формат CSV. Интересно, что Excel при сохранении в формат CSV в качестве разделителя использует знак “;”, хотя вроде бы написано «CSV (разделители – запятые)». PowerShell же по умолчанию считает, что в качестве разделителя используется запятая («,»). Чтобы наш скрипт работал корректно – необходимо либо заменить в CSV-файле все точки с запятой на запятые (используя автозамену в блокноте) либо же, что на мой взгляд правильнее – указать в скрипте использовать точку с запятой в качестве разделителя:
$Users = Import-CSV “c:\temp\users.csv” –Delimiter “;”
Чтобы проверить, как прошел импорт – можно посмотреть, что хранится в переменной $Users.
Как видим, в переменной $Users теперь хранится массив объектов с параметрами Name, Surname, Login, Password. Эти параметры можно использовать для создания учетных записей пользователей в AD.
Прежде чем приступить к работе с Active Directory, необходимо произвести импорт соответствующего модуля в PowerShell. Только после этого появятся команды для работы с AD:
Import-Module ActiveDirectory
Эту строку можно (и даже нужно) вставлять в начало всех скриптов – чтобы не вводить эту команду вручную.
Создание учетных записей пользователей
Каждому, кто работал с ActiveDirectory, приходилось создавать учетные записи пользователей. И хотя это делается легко и просто – в несколько щелчков мышкой – иногда, особенно в крупных организациях, приходится создавать много учетных записей в течение дня. Иногда – в районе сотни.
Для нашего примера, в качестве списка пользователей будем брать CSV-файл со следующими полями:
-
Name – имя пользователя
-
Surname – фамилия пользователя
-
Password – пароль
-
OU – организационное подразделение, где будет находиться пользователь (вида Contoso_Users/Fin/Accounting)
Вначале нам нужно импортировать пользователей из списка:
$Users = Import-CSV $1 –Delimiter “;”
Параметр $1 означает, что в качестве пути к CSV-файлу будет использоваться первый по счету параметр командной строки. Запускаться скрипт будет следующим образом:
PS C:\Users\admin > Add_Users.ps1 c:\temp\users.csv
Далее нам нужно пройтись по всему массиву пользователей из списка:
Foreach($CurrentUser in $Users) {
Знак открытой фигурной скобки означает начало цикла. Этот цикл проходит по всем объектам списка, и прискаивает текущий объект переменной $CurrentUser.
Затем, для упрощения – присвоим значения соответствующих полей отдельным переменным:
$Name = $CurrentUser.Name
$Surname = $CurrentUser.Surname
$Password = $CurrentUser.Password
$OU = $CurrentUser.OU
Для того, чтобы задать пароль пользователю – необходимо перевести его в шифрованный формат SecureString:
$SecurePwd = ConvertTo-SecureString -AsPlainText -Force -String $Password
Так же, OU нам нужно перевести в формат, соответствующий стандарту LDAP (для примера выше: “OU=Accounting,OU= Fin,OU= Contoso_Users,DC=contoso,DC=com”).
Для этого вначале разделим строку $OU на отдельные составляющие:
$OUTmp = $OU –Split “/”
В результате переменная $OUTmp будет содержать массив из всех элементов пути:
PS C:\Users\admin> $OUTmp
Contoso_Users
Fin
Accounting
Далее, используя командлет Foreach-Object, получим из нашего массива первую часть LDAP-пути:
$Path = “” #незабудьте проинициализировать переменную!
$OUTmp | ForEach-Object {$Path = "OU=$_," + $Path}
В переменной $Path появляется первая часть LDAP-пути:
PS C:\Users\admin> $Path
OU=Accounting,OU=Fin,OU=Contoso_Users,
Теперь нам нужно получить полный путь, добавив к пути домен:
$Path += “DC=contoso,DC=com”
Получили полный LDAP-путь:
PS C:\Users\admin> $Path
OU=Accounting,OU=Fin,OU=Contoso_Users,DC=contoso,DC=com
Теперь сформируем дисплейное имя пользователя, его логин, User Principal Name.
$Login = $Name[0] + “.” + $Surname #логин формируется из первой буквы имени и фамилии, например: i.ivanov
$Displayname = $Name + “ “ + $Surname #Дисплейное имя: Ivan Ivanov
$UserPrincipalName = $Login + “@contoso.com”
Наконец, можно перейти к самой главной процедуре: созданию учетной записи пользователя.
New-ADUser $Displayname –SamAccountName $Login –UserPrincipalName $UserPrincipalName -DisplayName $DisplayName -AccountPassword $SecurePwd -ChangePasswordAtLogon 1 -Path $Path
Здесь, в принципе, все параметры понятны. Параметр -ChangePasswordAtLogon 1 означает, что пользователю будет предложено сменить пароль сразу после логина.
По умолчанию в PowerShell, в отличие от стандартного визарда в оснастке ActiveDirectory Users And Computers учетные записи только что созданных пользователей будут отключены (Disabled). Поэтому сразу после создания учетные записи нужно включить:
Enable-ADAccount $Login
Теперь нужно закрыть цикл знаком «}». Можно сохранять скрипт и пробовать.
Готовый скрипт будет выглядеть следующим образом:
Import-Module ActiveDirectory
$Users = Import-CSV $1 –Delimiter “;”
Foreach($CurrentUser in $Users) {
$Name = $CurrentUser.Name
$Surname = $CurrentUser.Surname
$Password = $CurrentUser.Password
$OU = $CurrentUser.OU
$SecurePwd = ConvertTo-SecureString -AsPlainText -Force -String $Password
$OUTmp = $OU –Split “/”
$Path = “” #незабудьте проинициализировать переменную!
$OUTmp | ForEach-Object {$Path = "OU=$_," + $Path}
$Path += “DC=contoso,DC=com”
$Login = $Name[0] + “.” + $Surname
$Displayname = $Name + “ “ + $Surname #в кавычках – пробел!
$UserPrincipalName = $Login + “@contoso.com”
New-ADUser $Displayname –SamAccountName $Login –UserPrincipalName $UserPrincipalName -DisplayName $DisplayName -AccountPassword $SecurePwd -ChangePasswordAtLogon 1 -Path $Path
Enable-ADAccount $Login
}
Создание учетных записей компьютеров
Как известно, для работы с Active Directory перво-наперво необходимо вводить компьютеры в домен. Сделать это можно двумя способами:
· Мышкой – самый известный способ, через «Свойства» «Моего компьютера». Легко и просто.
· Командой netdom join. Тоже несложно, и можно использовать в скриптах.
У первого способа есть существенный недостаток: учетные записи компьютеров создаются в дефолтном OU Computers. В организациях же, как правило имеются разные OU для разных типов компьютеров (сервер, десктоп, ноутбук), а так же отдельные OU для разных отделов/департаментов/и т.д., с различными групповыми политиками, действующими для разных OU. Поэтому после ввода компьютеров в домен необходимо переносить учетные записи компьютеров вручную в соответствующий OU, а затем перезагружать компьютер еще раз, чтобы на нем применились все необходимые политики. При использовании команды netdom можно указать нужное OU, но набирать все это с клавиатуры – та еще задачка, особенно – когда компьютеров много, и особенно, что часто бывают – задачку эту поручают простым эникейщикам. Где-то в какой-то букве обязательно ошибется.
Самый лучший выход из этой ситуации – создать учетные записи компьютеров заранее, в соответствующих OU. Тогда компьютер сразу после ввода в домен и перезагрузки применит все соответствующие политики.
Разумеется, учетные записи компьютеров, как и пользователей, можно создавать и вручную. Но, поскольку мы – админы, а не эникейщики – будем использовать PowerShell.
Для учетных записей, как и для компьютеров, используем CSV-файл
ComputerName;OU
Server1;Cnotoso_Computers/Servers
Server2;Cnotoso_Computers/Servers
Desktop1;Cnotoso_Computers/Desktops
Desktop2;Cnotoso_Computers/Desktops
Desktop3;Cnotoso_Computers/Desktops
Laptop1;Cnotoso_Computers/Laptops
Далее, пишем скрипт по анологии со скриптом для учетных записей пользователей, только он будет немного проще:
Import-Module ActiveDirectory
$Computers = Import-CSV $1 –Delimiter “;”
Foreach($CurrentComputer in $Computers) {
$ComputerName = $CurrentComputer.ComputerName
$OU = $CurrentComputer.OU
$OUTmp = $OU –Split “/”
$Path = “” #незабудьте проинициализировать переменную!
$OUTmp | ForEach-Object {$Path = "OU=$_," + $Path}
$Path += “DC=contoso,DC=com”
New-ADComputer –Name $ComputerName –Path $Path
}
Массовый сброс паролей
Иногда бывает необходимо массово сбросить пароли у множества пользователей.
Структура CSV-файла:
-
Login – логин пользователя
-
NewPassword – новый пароль
Import-Module ActiveDirectory
$Users = Import-CSV $1 –Delimiter “;”
Foreach($CurrentUser in $Users) {
$Login = $CurrentUser.Login
$NewPassword = $CurrentUser.NewPassword
$SecurePwd = ConvertTo-SecureString -AsPlainText -Force -String $Password
Set-ADAccountPassword –Identity $Login –Reset –NewPassword $SecurePwd
}
Массовое изменение параметров
Допустим, в вашей организации были приняты новые корпоративные стандарты, которые требуют, чтобы у каждого пользователя в AD были указаны, помимо всего остального: адрес электронной почты, номер мобильного телефона, название организации, должность. Из отдела кадров вам прислали табличку со следующими полями:
-
Имя
-
Фамилия
-
E-Mail
-
Телефон
-
Организация (у компании несколько юр.лиц)
-
Должность
Из нее мы создаем CSV-файл с полями:
-
Name
-
Surname
-
E-Mail
-
Phone
-
Organization
-
JobTitle
Скрипт будет следующего вида:
Import-Module ActiveDirectory
$Users = Import-CSV $1 –Delimiter “;”
Foreach($CurrentUser in $Users) {
$Name = $CurrentUser.Name
$Surname = $CurrentUser.Surname
$Email = $CurrentUser.E-Mail
$Phone = $CurrentUser.Phone
$Organization = $CurrentUser.Organization
$JobTitle = $CurrentUser.JobTitle
$Login = (Get-ADuser –Filter {GivenName –eq $Name –and Surname –eq $Surname}).SamAccountName #ищем юзера с заданным именем и фамилией и возвращаем его логин
Set-ADUser $Login –EmailAddress $Email –MobilePhone $Phone –Company $Organization –Title $JobTitle
}
Заключение
В этой статье я попытался рассмотреть простейшие скрипты для автоматизации наиболее часто встречающихся задач администрирования Active Directory. На самом деле, я намеренно не стал чересчур усложнять скрипты, чтобы можно было понять логику работы.
Попробуйте сами вооружиться гуглом и ресурсами, указанными в конце статьи и улучшить скрипты самостоятельно.
Например:
-
Добавить обработку ошибок (например, если пользователь с таким именем уже существует, или наоборот – не существует) – конструкции типа try… catch…
-
Автоматическую генерацию паролей заданной длины и сложности
-
Вывод логинов с автоматически сгенерированными праолями для только что созданных учетных записей в CSV-файл – командлет Export-CSV
Ресурсы
Эти ресурсы очень сильно помогут в изучении PowerShell. Во всяком случае мне они помогли.
-
http://technet.microsoft.com/ru-RU/scriptcenter/default.aspx – библиотека скриптов на TechNet. Можно попытаться найти готовый скрипт там, вместо того, чтобы писать с нуля
-
http://itband.ru/2011/10/powershell-resources/ – список полезных ресурсов по PowerShell на нашем сайте, начинать изучать язык можно как раз оттуда
-
http://itband.ru/lessons/powershell/ – видеоуроки по PowerShell
Надеюсь, эта статья была вам полезна, и кто-то, кто раньше боялся консоли – перестанет ее бояться.
Александр Косивченко
Хорошо бы упомянуть про необходимый уровень AD и необходимость включения/настройки WinRM
Ну или про (бесплатный) AD модуль от Quest, который умеет работать с AD 2003, и бесплатный же PowerGUI.
Извиняюсь. Для меня уже лет так несколько функциональный уровень один – Windows Server 2008 R2. Это как Москва – Default city 🙂
Поэтому не знал про стороние модули 🙂 Про PowerGUI в курсе, но мне кажется и ISE вполне достаточно для скриптописания, не? Хотя конечно есть маньяки, которые Visual Studio рпикручивают 🙂
Еще не мешает сказать что модуль ActiveDirectory есть только в RSAT-е от Windows 7 или в Windows 2008 R2. Так же стоит упомянуть что обязательное требование это PowerShell Второй версии и установленные ADWS.
Добавлю в статью. Мне и в мысли не приходило, что у кого-то может оказаться другая ОС.
Про режим работы леса/домена я не уверен, что нужен 2008 R2. У меня просто 2008 и всё замечательно работает из модуля ActiveDirectory для Powershell.
Да, обшибся. Тем не менее, иметь хотя бы один контроллер домена с R2 нужно. И да, как тут правильно заметили, нужна компонента ADWS. Кстати, а 2003 доменами кто-нибудь пробовал рулить через этот модуль?
Саш, а что тут используется такого, что не будет работать при режиме леса 2003?
Ну вообще говоря ADWS устанавливается автоматом при включении роли контроллера AD или даже просто экземпляра LDS, это еще постараться надо ее выпилить. Почти уверен что в уровне 2003 работать будет, так как добавить Windows 2008 R2 и сделать контроллером в таком домене можно (не забывая конечно adprep), а командлеты AD-модуля врядли схемозависимы.
Вот в том и дело что не знаю, у меня все на 2008 R2. 2003 я не видел уже давно 🙂 Возможно насчет функционального уровня я погорячидся, в технете вроде тоже говорится что достаточно просто одного КД на 2008R2.
На Windows 2003 даже в режиме работы леса/домена Windows 2000 прекрасно работает и Powershell и уже упоминавшиеся командлеты от Quest Software.
[…] Типовые задачи администрирования AD с использованием PowerShell. Думаю весьма интересна статья, которая уверен, что пригодится в будущем на проектах. Линк […]
В 2003х доменах Powershell прекрасно себя чувствует 🙂
Александр, а где ресурсы в конце статьи?
поставить этот апдейт на 2003 и тогда будет работать и там, даже без КД в доменене на 2k8
http://www.microsoft.com/en-us/download/details.aspx?id=2852
поставить этот апдейт на 2003 и тогда будет работать и там, даже без КД в доменене на 2k8
http://www.microsoft.com/en-us/download/details.aspx?id=2852
welcome, спасибо большое – не знал
“Интересно, что Excel при сохранении в формат CSV в качестве разделителя использует знак “;”, хотя вроде бы написано «CSV (разделители – запятые) ».” – Это зависит от региональных настроек,поставить везде En и будут запятые или сменить знак разделителя.
Примеры CSV,лучше без ошибок выкладывать(то запятая,то точка с запятой):
Name;Surname;Login;Password
Ivan,Ivanov;i.ivanov;p@ssw0rd1
Petr,Petrov;p.petrov;p@ssw0rd2
Sidor;Sidorov;s.sidorov;p@ssw0rd3
“Параметр $1 означает, что в качестве пути к CSV-файлу будет использоваться первый по счету параметр командной строки.” – С чего Вы решили,что $1 это первый аргумент?
$Login = (Get-ADuser –Filter {GivenName –eq $Name –and Surname –eq $Surname}).SamAccountName #ищем юзера с заданным именем и фамилией и возвращаем его логин
Set-ADUser $Login –EmailAddress $Email –MobilePhone $Phone –Company $Organization –Title $JobTitle
Если Get-ADUser вернет ошибку,то будет использоваться предыдущее значение,и предыдущий пользователь получит совсем другие значение и новичок получит сюрприз. ))
PS Z:> $login = “sasha”
PS Z:> $login = Get-ADUser sdfsdfsdf
Get-ADUser : Не удается найти объект с удостоверением: “sdfsdfsdf” в “DC=academia,DC=local”.
строка:1 знак:20
+ $login = Get-ADUser <<< $login
sasha
$Email = $CurrentUser.E-Mail – Здесь возникнет ошибка.
в чем смысл создания горы переменных в примере “создание учетных записей пользователей”? совершенно лишнее усложнение, вы зачем-то мыслите как программист там, где нужно мыслить как админ))) все же проще –
Import-CSV -Path “C:scriptsCreateUser.csv” | ForEach-Object -process {New-ADuser -Name $_.Name -Surname $_.Surname -City $_.City -Department $_.Department -GivenName $_.GivenName -Title $_.Title -Description $_.Description -DisplayName $_.DisplayName -Division $_.Division -EmailAddress $_.EmailAddress -ScriptPath $_.ScriptPath -SamAccountName $_.SamAccountName -MobilePhone $_.MobilePhone -Path “OU=Users,DC=domain,DC=ru” -CannotChangePassword $true -ChangePasswordAtLogon $false -PasswordNotRequired $true -AccountPassword (ConvertTo-SecureString $_.Password -AsPlainText -Force) -Company MyCompany}
вот сюда посмотрите, тут и проще и яснее все http://parafoxer.livejournal.com/106150.html
Отличная статья. Спасибо автору за труд.