Всем доброго времени суток.
Возникла необходимость работы с AD из 1с в частности создавать пользователей, группы безопасности и организационные единицы.
Нижеприведенный код распологается во общем модуле.
Для работы используется LDAP провайдер ADSI
Пример содержимого передаваемых и возвращаемых переменных:
- Организационная единица: «OU=TestOU,DC=domain,DC=internal»
- Группа безопасности: «CN=TestGroup,OU=TestOU,DC=domain,DC=internal»
- Пользователь: «CN=TestUser,OU=TestOU,DC=domain,DC=internal»
SID пользователя и группы возвращается в виде COMSafeArray. Я его преобразовывавю в читаемый вид. Он мне нужен для установки прав на каталоги и файлы.
Все функции возвращают результат выполнения Ложь/Истина. В случае возникновения ошибки описание возвращается в переменную ОписаниеОшибки.
Надо не забывать, что пользователь, от имени которого запускается 1с (или пользователь сервера приложения если процедуры будут запускаться на сервере) должен обладать соответствующими правами для работы с AD
Привожу на суд общественности результаты:
1) Cоздание организационной единицы
Функция СоздатьОрганизационнуюЕдиницу(
ИмяОрганизационнойЕдиницы,
ОрганизационнаяЕдиницаВладелец,
Описание,
ГруппаДелегат = "",
ПолноеИмяОрганизационнойЕдиницы = "", //возращается путь до созданой OU
ОписаниеОшибки = ""
) Экспорт
фРезультат = Истина;
Попытка
ОрганизационнаяЕдиницаВладелецОбъект = ПолучитьCOMОбъект("LDAP://" + ОрганизационнаяЕдиницаВладелец);
ОрганизационнаяЕдиница = ОрганизационнаяЕдиницаВладелецОбъект.Create("OrganizationalUnit", "OU=" + ИмяОрганизационнойЕдиницы);
ОрганизационнаяЕдиница.description = Описание;
Если Не ПустаяСтрока(ГруппаДелегат) Тогда
ОрганизационнаяЕдиница.managedBy = ГруппаДелегат;
КонецЕсли;
ОрганизационнаяЕдиница.SetInfo();
Исключение
фРезультат = Ложь;
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если фРезультат Тогда
ПолноеИмяОрганизационнойЕдиницы = ОрганизационнаяЕдиница.distinguishedName;
КонецЕсли;
Возврат фРезультат;
КонецФункции
2) Создание группы безопасности
Функция СоздатьГруппуБезопасности(
ИмяГруппыБезопасности,
ОрганизационнаяЕдиницаВладелец,
Описание,
ПолноеИмяГруппыБезопасности = "",
SID = "",
ОписаниеОшибки = ""
) Экспорт
фРезультат = Истина;
//ADS_GROUP_TYPE_GLOBAL_GROUP = 2;
//ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 4;
//ADS_GROUP_TYPE_LOCAL_GROUP = 4;
//ADS_GROUP_TYPE_UNIVERSAL_GROUP = 8;
//ADS_GROUP_TYPE_SECURITY_ENABLED = -2147483648;
Попытка
ОрганизационнаяЕдиницаВладелецОбъект = ПолучитьCOMОбъект("LDAP://" + ОрганизационнаяЕдиницаВладелец);
ГруппаБезопасности = ОрганизационнаяЕдиницаВладелецОбъект.Create("Group", "CN=" + ИмяГруппыБезопасности);
ГруппаБезопасности.sAMAccountName = ИмяГруппыБезопасности;
ГруппаБезопасности.displayName = ИмяГруппыБезопасности;
ГруппаБезопасности.description = Описание;
ГруппаБезопасности.groupType = -2147483646;//ADS_GROUP_TYPE_GLOBAL_GROUP + ADS_GROUP_TYPE_SECURITY_ENABLED; //глобальная группа
ГруппаБезопасности.SetInfo();
Исключение
фРезультат = Ложь;
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Если фРезультат Тогда
SID = ПреобразоватьSID(ГруппаБезопасности.objectSid);
ПолноеИмяГруппыБезопасности = ГруппаБезопасности.distinguishedName;
КонецЕсли;
Возврат фРезультат;
КонецФункции
Функция СоздатьПользователя(
Логин,
ПарольПользователя,
ОрганизационнаяЕдиница,
АдресЭлектроннойПочты,
МенятьПарольПриВходе = Истина,
Описание,
ПутьПользователя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();
КонецЕсли;
Возврат фРезультат;
КонецФункции
В константе НаименованиеДомена находится название домена типа «domain.internal».
4) Добавление пользователя в группу
Функция ДобавитьПользователяВГруппу(
ПолноеИмяГруппыБезопасности,
ПутьПользователяAD,
ОписаниеОшибки = ""
) Экспорт
фРезультат = Истина;
Попытка
ГруппаБезопасности = ПолучитьCOMОбъект("LDAP://" + ПолноеИмяГруппыБезопасности);
ГруппаБезопасности.Add("LDAP://" + ПутьПользователяAD);
ГруппаБезопасности.SetInfo();
Исключение
фРезультат = Ложь;
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Возврат фРезультат;
КонецФункции
5) Удаление пользователя из группы
Функция УдалитьПользователяИзГруппы(
ПолноеИмяГруппыБезопасности,
ПутьПользователяAD,
ОписаниеОшибки = ""
) Экспорт
фРезультат = Истина;
Попытка
ГруппаБезопасности = ПолучитьCOMОбъект("LDAP://" + ПолноеИмяГруппыБезопасности);
ГруппаБезопасности.Remove("LDAP://" + ПутьПользователяAD);
ГруппаБезопасности.SetInfo();
Исключение
фРезультат = Ложь;
ОписаниеОшибки = ОписаниеОшибки();
КонецПопытки;
Возврат фРезультат;
КонецФункции
6) Переобразование SID из массива в читаемый вид типа «S-1-5-21-3784850290-2022084444-2521399107-4676»
Функция ПреобразоватьSID(objectSid)
SID = "S-";
МассивSID = Новый Массив;
Для Каждого ЭлементSID Из objectSid Цикл
МассивSID.Добавить(ЭлементSID);
КонецЦикла;
//SID_REVISION
SID = SID + Строка(МассивSID[0]) + "-";
КоличествоДашей = МассивSID[1];
SECURITY_NT_AUTHORITY = 0;
Для Инд = 0 По 5 Цикл
SECURITY_NT_AUTHORITY = SECURITY_NT_AUTHORITY + МассивSID[2 + Инд] * Pow(2, (5 - Инд) * 8);
КонецЦикла;
SID = SID + Строка(SECURITY_NT_AUTHORITY);
Для Инд = 0 По КоличествоДашей - 1 Цикл
SID = SID + "-";
Даш = 0;
Для ИндДаш = 0 По 3 Цикл
Даш = Даш + МассивSID[8 + 4 * Инд + ИндДаш] * Pow(2, (ИндДаш) * 8);
КонецЦикла;
SID = SID + Строка(Даш);
КонецЦикла;
Возврат SID;
КонецФункции
7) Ну и бонусом привожу процедуру установки прав на каталог. Права ставятся с наследованием на нижестоящие объекты. Для установки используется утилита операционки (в моём случае win 2012 в Asure). При вызове (в толстом клиенте) у 1С теряется фокус. К сожалению как установить права другим способом (например WMI) я не нашел. Планирую копать в сторону PowerShell.
Функция УстановитьПраваНаКаталог(
ПутьККаталогу,
SIDГруппы,
Описание = "") Экспорт
фРезультат = Истина;
КодВозврата = Неопределено;
Попытка
ЗапуститьПриложение("icacls " + ПутьККаталогу + " /grant *" + SIDГруппы + ":(CI)(OI)F", , Истина, КодВозврата)
Исключение
Описание = ОписаниеОшибки();
фРезультат = Ложь;
КонецПопытки;
Если фРезультат Тогда
Если КодВозврата <> 0 Тогда
фРезультат = Ложь;
Описание = "Код возврата: " + Строка(КодВозврата);
КонецЕсли;
КонецЕсли;
Возврат фРезультат;
КонецФункции
Список использованных ссылок:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa772203%28v=vs.85%29.aspx
http://www.script-coding.com/Python/LDAP.html
http://blogs.msdn.com/b/oldnewthing/archive/2004/03/15/89753.aspx
http://technet.microsoft.com/ru-ru/library/cc753525%28v=ws.10%29.aspx
Незаменимой вешью оказалась утилита Марка Руссиновича
Большое спасибо. Будем пробовать….
права на папки можно через командную строку установить — сам не раз так делал, только какая команда сейчас не вспомню, т.к. делал лет 5 назад…
Наш суд общественности — самый гуманный суд в мире!
Может хватит морочить людям голову задачами, не имеющими практического значения.
Все эти операции: удалить, добавить, назначить права — отлично делаются специальными инструментами администрирования.
Единственное что могло бы пригодиться, это вычисление: входит ли текущий пользователь в указанную группу AD и, получение списка доступных групп AD для назначения прав своим внутренним объектам 1С.
(3) ksuman,
Ну на счет практического использования это Ваше сугубо субъективное мнение.
Алгоритмы используются на вполне боевой системе провижининга. А специальными инструментами администрирования попробуйте пакетно создать 100 пользователей AD, 100 пользователей 1с в 30 различных базах и привязать их к соответствующим учеткам.
Спасибо за потраченное время! Я тоже проводил похожие исследования для импорта пользователей из AD, но с созданием так и не хватило терпения разобраться 🙂 Обязательно в будущем воспользуюсь идеями!
(3) ksuman, немного не согласен, вы видимо не администрировали АД с хотя бы 1000 пользователей. На основании этого кода очень удобно выполнять массовые действия над учетными записями. Тоже накатал под свои нужды конфу для работы с LDAP но выложить на общее обозрение не рискну ибо код там уж больно неряшлив 🙁
Нужно в 1С.ЗУП для физических лиц формировать сетевое имя пользователя, e-mail, а потом уже глобальная задача: создавать пользователя в AD.
Вот вопрос: я сформирую для физ лица сетевое имя — мне же нужно проверить, что такого пользователя еще нет в AD. Как это сделать?
(7) user_2010, для этого необходимо выполнить запрос
Если результат пустой, то соответственно в базе нет такого юзера.
(4) есть ли у Вас реализация поиска по ГУИДу в запросе?
(9) Mi4man, SELECT ADsPath FROM ‘LDAP://10.0.0.254’ WHERE objectGUID=’4e1e1853a15ac4b81 6db440 51411 ’
(10) brr, что-то я пробовал, но никак не получалось. Эх…
(11) Mi4man, а ГУИД именно такое имел представление? Пример: b4e1e1853a15ac4b8106db44b0051411.
(12) brr, нет, вот такое: 4e1e1853a15ac4b81 6db440 51411 (строка).
А надо было просто b4e1e1853a15ac4b8106db44b0051411 ?
гдеб найти примеры работы с openLDAP из под Linux?
Спасибо.
Небольшое замечание: SID формируется с символами НПП.
(13) Mi4man, нет, просто я не понял какое представление ГУИД вы использовали
Не получается создать пользователя. Пишет «Ошибка получения объекта COM: Сервер возвратил ссылку». Что может быть?
Вроде все по схеме
element_group = ПолучитьCOMОбъект(«LDAP://OU=Папка 2,OU=Пользователи домена,OU=sim,DC=dc,DC=my_company,DC=com)»);
А каким кодом можно изменить организационную единицу (OrganizationalUnit) у существующего пользователя? Т.е. мне нужно перенести в другую папку пользователя. Пробывал изменить distinguishedName, выдает ошибку.
Разобрался сам, вот так, если кому-то интересно (первая строка куда перемещаем, вторая откуда)
set cont = GetObject(«LDAP://dc=dom,dc=com»)
set newobj = cont.MoveHere(«LDAP://cn=jeffsmith,ou=sales,dc=dom,dc=com», «cn=jeffsmith»)
Как получить список групп пользователя из AD ? хочу открывать пользователя AD и видеть его группы AD? ; нужно видеть все группы и те которые присвоены данному пользователю
(20) i_rebel, код на vbs для получения своих групп:
каким кодом можно считать данные пользователя, допустим описание, телефон и так далее
(21) Armando, мне нужно все группы, чтобы потом мог сделать интерактивно добавление или удаление из группы
Все получилось всем спасибо.
Весь инет перерыл, так и не смог найти нормального примера/описания как переименовать пользователя в AD.
Задача такая:
В 1С сотрудник сменил ФИО, зная ее доменное имя, как поменять на новое ФИО в самом AD?
(25) Danila-Master,
https://technet.microsoft.com/en-us/library/ee617215.aspx)
Попробуйте через PowerShell. Set-ADUser (
Помогите разобтаться. Почему-то не хочет работать powershell.
В 1С делаю ЗапуститьПриложение(«powershell.exe -Command {Set-ADUser -Identity «»1ctest»» -Surname «»Иванов»» -GivenName «»Иван»»}»);
Имя учетни не меняется.
В cmd.exe пишу строку: powershell.exe -Command {Set-ADUser -Identity «1ctest» -Surname «Иванов» -GivenName «Иван»}
Так же, имя учетки не меняется.
Но если в самой консоле PowerShell’а написать строку: Set-ADUser -Identity «1ctest» -Surname «Иванов» -GivenName «Иван»
То все ништяк, Имя в учетке поменялось.
1С, cmd и консоль PowerShell запущенны от именю учетки, у которой есть права на изменение данных в домене. Так что этот момент стразу отсекаю.
(27) Danila-Master, в 1С код выполняется на том же компьютере, где Вы открывали консоль PowerShell? (М.б. Вы открывали консоль на своей клиентской машине, а ЗапуститьПриложение выполняли на сервере)
(28) blackhole321,
Так оно и есть и будет. Но запуск происходит от одной и той же учетки, что на моем компе, что на сервере.
Но перед тем как писать в 1С, мне нужно из командной строки добится результата. Поэтому пока делаю все на своем компе.
Столкнулся с интересной ситуацией:
В cmd пишу powrshell.exe, проваливаюсь в сам сонсоль PS.
Далее в PS пишу: Get-ADUser -Identity «1ctest»
Выдает ошибку, что команда Get-ADUser не найдена.
Как оказалось нужно подключить модуль для работы с AD.
> Import-Module ActiveDirectory
> Get-ADUser -Identity «1ctest»
о чудо, Get-ADUser выдал результат. но при этом, даже после подключения модуля, команда Set-ADUser -Identity «1ctest» -Surname «Иванов» -GivenName «Иван»
так и выполнилась. И ошибок нет.
В общем разобрался я 🙂
1. Нужно поставить PowerShell версии 4.0 (по-умолчанию у windows 7 и 2008 R2 стоит версия 2.0)
В версии 4.0 не нужно импортировать разные модули, shell сама все делает.
2. Рабочая команда в cmd: powershell.exe Set-ADUser -Identity ‘1ctest’ -Surname ‘Иванов’ -GivenName ‘Иван’ -DisplayName ‘Иванов Иван’
где
Identity — параметр поиска (в данном случае доменное имя пользователя)
Surname — Фамилия
GivenName — Имя
DisplayName — Отображаемое имя
Все, разобралися.
Вдруг кому пригодится, вот рабочий код:
Какой командой можно добавить роль в список ролей MemberOf ? И как получить ссылку на саму группу?
(3) Вы далеки от реального управления бизнесом. В частности у нас в 1С создают новых клиентов, карточки и они автоматом прописываются в AD который как LDAP раздает в FreePBX и еще ряд специальных услуг для клиентов пароли и юзернеймы. Вы не понимаете о чем речь
Подскажите: Документ, в нет по параметром выходит список (на картинке. студент , создается пользователь в домене и пароль ). Код брал отсюда для создания пользователе. Как сделать так , чтобы при создании пользователя он проверял и выдавал предупреждение(ошибку или не создовал такого пользака) есть ли уже такой пользователь(так как студент может учится в двух разнух факультетах например.)
Можно так проверить:
Показать
Ещё раз сдравствуйте, а как добавить пользователей в группу, по пункту 4 не получается .Все пользователи в группе Учащиеся, в ней группа Студенты с подпиской. я пробывал и так и сяк, что не так делаю?)
Может вы в курсе почему стандартный метод ПользователиОС() возвращает массив структур доменов с ограничением массива пользователей в 100 элементов?
(0) Для автора, преобразование objectGUID в строку, может кому пригодиться
//https://support.microsoft.com/en-us/help/325649/how-to-retrieve-the-guid-of-an-object-from-the-active-directory
Показать
Показать
Показать