Когда новый сотрудник выходит на работу, обычно мало просто создать ему аккаунт в Active Directory: нужно включить его в группы безопасности, создать личную папку на сетевом диске, почтовый ящик, добавить аккаунт в ERP\CRM систему… Все это частично решается копированием аккаунта, но тогда нужно еще вовремя вспомнить и правильно настроить атрибуты Active Directory.
Но есть и более изящные варианты решения задачи. Так что, если вам надоело создавать аккаунты вручную ― приглашаю под кат.
Шаблоны и PowerShell
В качестве простой автоматизации для придания новому аккаунту нужных «форм» может выступать и скрипт на любом привычном языке. В качестве параметров он будет принимать данные пользователя и подразделения.
Я буду разбирать более интересные примеры, по сути основанные на этом методе.
Такой скрипт может являться «бэкендом», которому передается предварительно подготовленный «фронтендом» файл в любом текстовом формате: JSON, XML или вовсе CSV.
Например, можно подготовить JSON файл для создания пользователя и папки для него такого вида:
{
"ActiveDirectory": {
"UserAccounts": [
{
"FirstName" : "Иван",
"LastName" : "Иванов",
"Department": "Бухгалтерия",
"UserName": "Iivanov"
}
]
},
"UserHomeFolders" : [
{
"Name": "ИвановИ"
}
]
}
В этом примере файл обладает определенной структурой и поддерживает автоматическое создание нескольких пользователей разом. Теперь нужно написать скрипт, который будет парсить содержимое файла и выполнять определенные действия. В нашем примере подойдет такой командлет:
[CmdletBinding()]
param(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$TemplateFilePath = 'C:\temp\users.json'
)
$users = Get-Content -Path $TemplateFilePath -Raw | ConvertFrom-Json
$users.ActiveDirectory.UserAccounts | ForEach-Object {
if ($adUser = Get-AdUser -Filter "samAccountName -eq '$($_.UserName)'") {
$setParams = @{
Identity = $_.UserName
}
if ($adUser.GivenName -ne $_.FirstName) {
$setParams.GivenName = $_.FirstName
}
if ($adUser.SurName -ne $_.LastName) {
$setParams.SurName = $_.LastName
}
if (@($setParams.Keys).Count -gt 1) {
$setParams
Write-Verbose -Message "Обновляем существующего пользователя [$($_.UserName)] "
Set-AdUser @setParams
} else {
Write-Verbose -Message "Пользователь [$($_.UserName)] уже создан"
}
} else {
Write-Verbose -Message "Создание нового пользователя [$($_.UserName)]..."
New-AdUser -Name $_.UserName -GivenName $_.FirstName -SurName $_.LastName -Path "ou=$($_.Department),dc=domain,dc=com"
}
}
$fileServerShare = 'C:\HomeFolders'
$users.UserHomeFolders | ForEach-Object {
$folderPath = Join-Path -Path $fileServerShare -ChildPath $_.Name
if (-not (Test-Path -Path $folderPath -PathType Container)) {
Write-Verbose -Message "Создаем папку [$($folderPath)]..."
$null = New-Item -Path $folderPath -Type Directory
} else {
Write-Verbose -Message "Папка [$($folderPath)] уже создана"
}
}
Теперь можно запустить получившийся скрипт и насладиться его работой:
Работа командлета.
Стоит заметить, что командлет является примером, создает пользователей отключенными и не включает их ни в какую группу безопасности. Да и права на папку стоит задать. Доработать решение под вашу инфраструктуру предлагаю самостоятельно.
Если командлет можно настроить на запуск по расписанию раз в 5 минут, то осталось придумать, что будет формировать JSON. Это может быть и простой веб-интерфейс, GUI на том же PowerShell и прочие 1С. Интересный пример использования в качестве фронта Google Forms и заодно создание пользователям ящика в G Suite рассмотрен в материале «Ещё один пример автоматизации или PowerShell + Google Apps Script».
Разберу еще несколько примеров автоматизации, облегчающих жизнь.
Задаем права на папки
Бывало и так, что по регламенту для каждого нового пользователя создавалась папка на сетевом диске в подпапке подразделения. И каждый раз на почту сыпались заявки, что папки нет или к ней нет доступа ― загруженные инженеры попросту забывали про такие мелочи.
Чтобы уменьшить негатив, еще до появления PowerShell был разработан скрипт на vbs. Раз в сутки он подключался к AD и собирал оттуда свежесозданных пользователей. А потом создавал папку по стандарту и задавал нужные права при помощи xcacls.vbs такой командой:
WshShell.Run "cscript.exe C:\xcacls.vbs " + """" + folder + """" +" "+ "/I COPY /R users /G domain\"+ user+ ":F"
Где user ― это имя нового пользователя, folder ― путь к свежесозданной папке, а domain ― наш домен.
Позже для создания пользователей был уже разработан сложный механизм на AutoIT с GUI. Он формировал имя учетной записи по правилам транслитерации, создавал пользователей в 1С и даже выдавал проксимити-карты для доступа на территорию офиса. Права на папки в этом механизме задаются при помощи библиотеки Permissions.au3, которая использует системные dll advapi32.dll и kernel32.dll.
Часть скрипта для нужных разрешений:
FileWriteLine($logfile, "создаем папку "&$path)
local $aPermissions[2][3]
$aPermissions[0][0]="domain\"& $username
$aPermissions[0][1]=1
$aPermissions[0][2]=$GENERIC_ALL
$aPermissions[1][0]="Users"
$aPermissions[1][1]=1
$aPermissions[1][2]=""
_EditObjectPermissions($path, $aPermissions,$SE_FILE_OBJECT,"",1)
FileWriteLine($logfile, "задаем права")
_ClosePermissionResources()
В PowerShell аналогичная выдача прав будет выглядеть примерно так:
$acl = Get-Acl $path
$acl.SetAccessRuleProtection($true,$true)
$acl.Access |where {$_.IdentityReference -eq "Domain\Users"} | %{$acl.RemoveAccessRule($_)}
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ($username,"FullControl","ContainerInherit,ObjectInherit","None","Allow")
$acl | Set-Acl $path
Пожалуй, управление ACL ― это то немногое, что на PowerShell реализуется нетривиально. Перейдем к тому, в чем PowerShell силен и прост.
Добавляем почту и телефон
Если у вас установлен Exchange как почтовый сервер, то создавать пользователей сразу с почтовым ящиком поможет командлет New-Mailbox. Для создания пользователя в первоначальном скрипте можно использовать такую команду:
New-Mailbox -UserPrincipalName $_.UserName@example.com -Alias $_.UserName
-Database "Mailbox" -Name $_.UserName –OrganizationalUnit
CorpUsers -Password $password -FirstName $_.FirstName -LastName $_.LastName
-DisplayName "$($_.FirstName) $($_.LastName)" -ResetPasswordOnNextLogon $Right
Аналогично будет и с MS Lync:
Enable-CsUser -Identity "$($_.UserName)@domain.ru" -RegistrarPool "lync.domain.ru" -SipAddress "sip:$($_.UserName)@domain.ru"
Если у вас используются другие решения ― например, Postfix для почты и Asterisk для телефонии, ― на помощь придет возможность подключаться по SSH к *nix серверам с систем Windows. Подробно процедура описана в статье «Перекрестное опыление: управляем Linux из-под Windows, и наоборот». Я же напомню, что запуск команд производится через командлет Invoke-Command:
Invoke-Command -Hostname linux-server -ScriptBlock {some linux commands}
Интереснее дела обстоят с прочими системами, вроде 1С.
Создание пользователя в 1С
Про создание пользователей в 1С: Бухгалтерии при помощи AutoIT я уже писал в статье «Набор отверток администратора 1С». Напомню, что обращаться к 1С «снаружи» удобно при помощи COM-объекта v83.comconnector. Поскольку PowerShell тоже поддерживает COM-объекты, приведу часть скрипта для создания пользователей по-новому:
$obj=new-object -comobject V83.ComConnector
$connect=$obj.Connect("Srvr=""servername"";Ref=""basename"";Usr=""login"";Pwd=""password"";")
#создаем пользователя ИБ
$rights=$connect.Metadata.Roles.find($rght)
$newuser= $connect.ПользователиИнформационнойБазы.createuser()
$newuser.name = "$($surname) $($name)"
$newuser.fullname = "$($surname) $($name) $($fathername)"
$newuser.StandardAuthentication = "False"
$newuser.OSAuthentication="True"
$newuser.OSuser="\\DOMAINNAME\ $($Username)"
$newuser.Roles.add($rights)
$newuser.write()
#создаем пользователя в справочнике "Пользователи"
$bject=$connect.NewObject("СправочникМенеджер.Пользователи")
$newuserS=$bject.CreateItem()
$newuserS.code=$"($surname) $($name)"
$newuserS.Description="$($surname) $($name) $($fathername)"
$newuserS.write()
#Добавляем пользователя в группу
$grp=$connect.Справочники.ГруппыПользователей.НайтиПоНаименованию($group).ПолучитьОбъект()
$t=$grp.ПользователиГруппы.add()
$t.Пользователь = $newuserS.ссылка
$grp.write()
Где $rght ― это права пользователя ИБ, а $group ― нужная группа пользователя. Оба значения берутся из шаблона вместе с ФИО.
Разумеется, точный скрипт будет зависеть от вашей конкретной конфигурации 1С ― не забудьте проконсультироваться с программистом 1С.
Создаем пользователя из 1С
Если дисциплина в вашей организации на высоте не только в отделе ИТ, то можно и вовсе избавиться от создания новых пользователей. Ведь при приеме на работу сотрудника обычно вносят в базу в отделе HR, да и при увольнении делают соответствующую отметку.
Основанием для создания учетной записи пользователя, ее блокировки или перемещения будет не просто занесение пользователя в базу, а приказ о приеме на работу, об увольнении или о перемещении в другое подразделение.
В случае с 1С можно сделать регулярную выгрузку из базы новых и уволенных сотрудников хоть в том же формате JSON. А дальше уже пусть работает машина. С примером скрипта, обрабатывающего выгрузку в формате CSV можно ознакомиться в статье «Автоматизация кадровых изменений на PowerShell».
Другим вариантом будет запуск регламентных заданий сразу из 1С ― благо 1С тоже довольно богатый возможностями язык.
Например, создание пользователя в AD будет выглядеть так:
Функция СоздатьПользователя(
Логин,
ПарольПользователя,
ОрганизационнаяЕдиница,
АдресЭлектроннойПочты,
МенятьПарольПриВходе = Истина,
Описание,
ПутьПользователяAD = "",
SID = "",
ОписаниеОшибки = ""
) Экспорт
фРезультат = Истина;
Попытка
ОрганизационнаяЕдиницаОбъект = ПолучитьCOMОбъект("LDAP://" + ОрганизационнаяЕдиница);
ПользовательAD = ОрганизационнаяЕдиницаОбъект.Create("user", "CN=" + Логин);
ПользовательAD.sAMAccountName = Логин;
ПользовательAD.description = Описание;
ПользовательAD.userPrincipalName = Логин + "@" + Константы.НаименованиеДомена.Получить();
Если Не ПустаяСтрока(АдресЭлектроннойПочты) Тогда
ПользовательAD.mail = АдресЭлектроннойПочты;
КонецЕсли;
Если МенятьПарольПриВходе Тогда
ПользовательAD.pwdLastSet = 0;
Иначе
ПользовательAD.pwdLastSet = -1;
КонецЕсли;
ПользовательAD.SetInfo();
ПользовательAD.SetPassword(ПарольПользователя);
Исключение
фРезультат = Ложь;
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если фРезультат Тогда
SID = ПреобразоватьSID(ПользовательAD.objectSid);
ПутьПользователяAD = ПользовательAD.distinguishedName;
КонецЕсли;
Если фРезультат Тогда
ПользовательAD.AccountDisabled = Ложь;
ПользовательAD.SetInfo();
КонецЕсли;
Возврат фРезультат;
КонецФункции
Подробнее с механизмом работы 1С и AD, а также с примерами готовых функций можно ознакомиться в статье «Работа с Active Directory из 1С» на портале «Инфостарт».
А готовы ли вы доверить создание пользователей, пусть и опосредованно, сотрудникам HR?