Как перестать быть демиургом и поручить создание сущностей PowerShell

в 9:00, , рубрики: active directory, powershell, аккаунты, Блог компании Сервер Молл, Серверное администрирование, системное администрирование

Как перестать быть демиургом и поручить создание сущностей PowerShell - 1

Когда новый сотрудник выходит на работу, обычно мало просто создать ему аккаунт в Active Directory: нужно включить его в группы безопасности, создать личную папку на сетевом диске, почтовый ящик, добавить аккаунт в ERPCRM систему… Все это частично решается копированием аккаунта, но тогда нужно еще вовремя вспомнить и правильно настроить атрибуты Active Directory.

Но есть и более изящные варианты решения задачи. Так что, если вам надоело создавать аккаунты вручную ― приглашаю под кат.

Шаблоны и PowerShell

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

Я буду разбирать более интересные примеры, по сути основанные на этом методе.

Такой скрипт может являться «бэкендом», которому передается предварительно подготовленный «фронтендом» файл в любом текстовом формате: JSON, XML или вовсе CSV.

Например, можно подготовить JSON файл для создания пользователя и папки для него такого вида:

{
    "ActiveDirectory": {
        "UserAccounts": [
            {
                "FirstName" : "Иван",
                "LastName" : "Иванов",
                "Department": "Бухгалтерия",
                "UserName": "Iivanov"
            }
        ]
    },

    "UserHomeFolders" : [
        {
            "Name": "ИвановИ"
        }
    ]
}

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

[CmdletBinding()]
param(
    [Parameter()]
    [ValidateNotNullOrEmpty()]
    [string]$TemplateFilePath = 'C:tempusers.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)] уже создана"
    }
}

Теперь можно запустить получившийся скрипт и насладиться его работой:

Как перестать быть демиургом и поручить создание сущностей PowerShell - 2
Работа командлета.

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

Если командлет можно настроить на запуск по расписанию раз в 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 "DomainUsers"} | %{$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?

Автор: Tri-Edge

Источник

* - обязательные к заполнению поля