Имя: Пароль:
1C
1С v8
ADO выборка из AD
0 Armando
 
30.10.11
21:18
Для выборки из AD пользую ADO. Провайдер ADsDSOObject.
Есть условно рабочий запрос:

   ТекстЗапроса =
   "SELECT
   |    sAMAccountName,
   |    mail,
   |    cn
   |FROM
   |    'LDAP://OU=mos,OU=europe,OU=oneteam_sites,DC=oneteam,DC=pharmroot,DC=net'
   |WHERE
   |    objectClass = 'user'
   |    AND objectCategory = 'Person'"

К условию динамически добавляются еще условия. Все работает пока текст запроса не превышает примерно 1600 символов. После превышения возвращается пустой рекордсет.
Скажите, это нормально? Как победить?
1 vde69
 
30.10.11
21:57
Функция ПолучитьСписокДоменов () Экспорт  
   Результат = Новый Массив();
   objNameSpace = "";                  
   Попытка  objNameSpace = ПолучитьCOMОбъект("WinNT:");  
       м = Новый Массив();  м.Добавить("domain"); // Computer User Group GlobalGroup domain  
       м2 = Новый COMSafeArray(м, "VT_VARIANT");  
       objNameSpace.Filter = м2;  
       Для каждого item Из objNameSpace Цикл  
           Результат.Добавить(item.Name);  
       КонецЦикла;
   Исключение  
       Результат.Очистить();
   КонецПопытки;  
   Возврат Результат;
КонецФункции


Функция ПолучитьСписокГруппВДомене (ИмяДомена, ТипГрупп = "GlobalGroup") Экспорт  
   Результат = Новый Массив();
   objNameSpace = "";  
   Попытка  objNameSpace = ПолучитьCOMОбъект("WinNT://"+СокрЛП(ИмяДомена));  
       м = Новый Массив();  
       м.Добавить(ТипГрупп); // Computer User Group GlobalGroup domain  
       м2 = Новый COMSafeArray(м, "VT_VARIANT");  
       objNameSpace.Filter = м2;  
       Для каждого item Из objNameSpace Цикл  
           Результат.Добавить(item.Name);  
       КонецЦикла;
   Исключение  
       Результат.Очистить();
   КонецПопытки;  
   
   Возврат Результат;
КонецФункции
   
Функция ПолучитьСписокПользователейВГруппеДомена (ИмяДомена, ИмяГруппы) Экспорт  
   Результат = Новый Массив();
   objNameSpace = "";  
   Попытка  
       objNameSpace = ПолучитьCOMОбъект("WinNT://" + СокрЛП(ИмяДомена) + "/" + СокрЛП(ИмяГруппы) + ", Group");  
       Для каждого item Из objNameSpace.Members() Цикл  
           Результат.Добавить(item.Name);  
       КонецЦикла;
   Исключение  
       Результат.Очистить();
   КонецПопытки;  
   
   Возврат Результат;    
КонецФункции

Функция ПользовательВГруппеДомена (ИмяДомена, ИмяГруппы, ИмяПользователя) Экспорт  
   Результат = Ложь;  
   Массив = ПолучитьСписокПользователейВГруппеДомена (СокрЛП(ИмяДомена), ИмяГруппы);
   Для каждого элМассив из Массив Цикл  
       Если ВРег(элМассив) = ВРег(СокрЛП(ИмяПользователя)) Тогда   // пользователь уже в группе  
           Результат = Истина;    
           Прервать;  
       КонецЕсли;
   КонецЦикла;  
   
   Возврат Результат;
КонецФункции

Функция ДобавитьПользователяВГруппуДомена (ИмяДомена, ИмяГруппы, ИмяПользователя) Экспорт  
   Результат = Ложь;
   element_user = "";
   element_group = "";  
   Попытка  
       element_user = ПолучитьCOMОбъект("WinNT://" + ИмяДомена + "/" + ИмяПользователя + ", user");  
       element_group = ПолучитьCOMОбъект("WinNT://" + ИмяДомена + "/" + ИмяГруппы + ", group");  
       element_group.Add(element_user.ADsPath);  element_group.SetInfo();  
       Результат = Истина;
   Исключение  
       Результат = Ложь;
   КонецПопытки;  
   
   Возврат Результат;
КонецФункции

Функция УдалитьПользователяИзГруппыДомена (ИмяДомена, ИмяГруппы, ИмяПользователя) Экспорт  
   Результат = Ложь;
   element_user = "";
   element_group = "";  
   Попытка  element_user = ПолучитьCOMОбъект("WinNT://" + ИмяДомена + "/" + ИмяПользователя + ", user");  
       element_group = ПолучитьCOMОбъект("WinNT://" + ИмяДомена + "/" + ИмяГруппы + ", group");  
       element_group.Remove(element_user.ADsPath);  
       element_group.SetInfo();  
       Результат = Истина;
   Исключение  
       Результат = Ложь;
   КонецПопытки;  
   
   Возврат Результат;    
КонецФункции

Процедура ЗаполнитьПочтовыеАдресаИзAD()
   Попытка      
       conn = ПолучитьCOMОбъект("","ADODB.Connection");  
       conn.Provider = "ADSDSOObject";  
       conn.Open("Active Directory Provider");
   Исключение  Предупреждение("Ошибка подключения к Active Directory!");  
       Возврат;
   КонецПопытки;  
   
   Для Каждого Стр из Таблица Цикл  
       Если НЕ ПустаяСтрока(Стр.Логин) Тогда  
           Попытка        
               query = "SEL ECT ADsPath FR OM 'LDAP://DC="+СокрЛП(Домен.Код)+"' WHERE SAMAccountName='"+Стр.Логин+"'";    
               rs = conn.Execute(query);    
               Пока НЕ rs.EOF() Цикл    
                   obj = ПолучитьCOMОбъект(rs.Fields(0).Value);    
                   Если obj.Class="user" Тогда      
                       Стр.НоваяПочта=СокрЛП(obj.EmailAddress);      
                       Если Стр.НоваяПочта<>Стр.СтараяПочта Тогда      
                           Стр.Установить=Истина;      
                       КонецЕсли;    
                   КонецЕсли;    
                   rs.MoveNext();    
               КонецЦикла;  
           Исключение
               Сообщить("Ошибка получения почты для логина :"+Стр.Логин);                                                                      
           КонецПопытки;
       КонецЕсли;
   КонецЦикла;
   conn.Close();    
КонецПроцедуры

Функция УдалитьПроцесс (ИмяКомпьютера, НазваниеПроцесса, Логин, Пароль) Экспорт  
   Попытка  COM = Новый COMОбъект ("WbemScripting.SWbemLocator");  
       Серв = COM.ConnectServer(СокрЛп(ИмяКомпьютера), "\root\cimv2", СокрЛП(Логин), СокрЛП(Пароль));  
       СписокПроцессов = Серв.execQuery("Sel ect * fr om Win32_Process Where Name = '"+СокрЛП(НазваниеПроцесса)+"'");  
       Для каждого item Из СписокПроцессов Цикл  
           item.Terminate();  
       КонецЦикла;
   Исключение  
       Возврат Ложь;
   КонецПопытки;  
   
   Возврат Истина;
КонецФункции
2 Diabolicum 1C
 
30.10.11
22:19
(0) простите за оффтоп, но все же: зачем такая экзотика на 1С? Просто для расширения собственного кругозора:)
3 Armando
 
30.10.11
22:26
(1) И что? Тупой копипаст какой-то.

(2) Облегчение работы админу. Выбираются уволенные сотрудники, которых еще не удалили из AD. Админ ставит галочки на нужных юзерах, нажимает кнопку и отмеченные удаляются из AD.
4 vde69
 
30.10.11
22:30
(3) этот копипаст у меня работает уже 3 года и никаких проблемм, и добавляю пользоваетелей в домены и удаляю...

единственное требуется поддержка провайдера NT, а он немного устаревает :)
5 Diabolicum 1C
 
30.10.11
22:37
(3) А я для решения такой задачи реализовал бы внешнюю компоненту. Провайдер ADsDSOobject весьма ограничен.
Кстати, а что именно из себя представляют те самые динамически добавляемые условия? Скорее всего, рекордсет пустой, потому что записей соответствующих условиям нет.
6 Armando
 
30.10.11
22:52
(4) Я же говорю все нормально работает. Перестает работать, когда текст запроса становится слишком длинным.

(5) Зачем ВК? ADsDSOobject для моей выборки более чем достаточно.

После добавления условий запрос принимает вид

   ТекстЗапроса =
   "SELECT
   |    sAMAccountName,
   |    mail,
   |    cn
   |FROM
   |    'LDAP://OU=mos,OU=europe,OU=oneteam_sites,DC=oneteam,DC=pharmroot,DC=net'
   |WHERE
   |    objectClass = 'user'
   |    AND objectCategory = 'Person'
   |    AND (mail = 'email1'
   |        OR mail = 'email2'
   |        OR mail = 'email3'
   |        OR mail = 'email4'
   |        OR mail = 'email5')"

Пользователи удаляются вот так http://msdn.microsoft.com/en-us/library/aa705988(v=VS.85).aspx
7 Armando
 
30.10.11
22:52
8 Diabolicum 1C
 
30.10.11
23:17
(7) я с таким явлением сталкивался, но так его побороть и не смог. Такое впечатление, что через адо дополнительные фильтры работают как-то криво. Пока фильруешь по полям objectClass, objectCategory, SAMAccountName и memberOf - все нормально, но как только появляются дом поля -рекордсет пустой. Возможно, что с полем mail, происходит тоже, что и с memberOf.
9 vde69
 
30.10.11
23:23
(8)(6) такой эффект бывает если прав на выполнения запроса не хватает, тогда весь рекорд сет пустой, вообще этот провайдер весьма капризный
10 Diabolicum 1C
 
30.10.11
23:28
(9) Действительно', права устанавливаются по текущему пользователю домена, который выполняет запрос. И если прав не достаточно, то может быть возвращен пустой результат. Но с другой стороны, если прочитать поле mail может даже пользователь домена, то почему он же не может провести по нему фильтрацию.
11 Diabolicum 1C
 
30.10.11
23:31
(9) Согласен, насчет капризности этого провайдера. Но куда от него деваться, тоже не понятно, если решать задачу только средствами 1С. Как вы сказали winnt - устраивает постепенно.
12 Armando
 
31.10.11
00:22
Понятно. Забил я на это условие. Без него нормально все работает. Тормозов не наблюдается. Главное не упереться в лимит 1000 записей, но пока запас есть.
Завтра еще подниму темку, мож кто-нить полезного что скажет.
13 Armando
 
31.10.11
10:45
^
14 Armando
 
31.10.11
14:39
Надо добить тему
Компьютеры — прекрасное средство для решения проблем, которых до их появления не было.