Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 397

/ вопрос открыт /

Приветствую, уважаемые эксперты!
Пишу программу для автоматической блокировки учетной записи в AD при увольнении сотрудника. Список учеток необходимых заблокировать получил. Прилагаю часть кода. Осталось только заблокировать, как это сделать основываясь на моем коде? Благодарю за помощь.
P.S.Можно сразу подсказать как поставить галочку
"Скрывать в адресной книге ексченджа "

Приложение:
  1. procedure TDM.DataModuleCreate(Sender: TObject);
  2.  
  3. VAR
  4. i,j:integer;
  5.  
  6. begin
  7. ADConnection.Open;
  8. DBFConnection.Open;
  9. ADOQuery1.Open;
  10. ADOQuery2.Open;
  11. ADOQuery3.Open;
  12. ADOQuery2.First;
  13. ADOQuery3.First;
  14. for i:= 0 to ADOQuery2.RecordCount do
  15. begin
  16. for j:=0 to ADOQuery3.RecordCount do
  17. begin
  18. if Copy(ADOQuery3.FieldByName('firstname').Value,1,Pos(' ',ADOQuery3.FieldByName('firstname').Value)-1) = ADOQuery2.FieldByName('sn').AsString then
  19. if Copy(ADOQuery3.FieldByName('middlename').Value,1,Pos(' ',ADOQuery3.FieldByName('middlename').Value)-1) = ADOQuery2.FieldByName('givenName').Value then
  20. if ADOQuery3.FieldByName('dateout').AsDateTime < date then
  21. if Copy(ReverseString(IntToBin(ADOQuery2.FieldByName('userAccountControl').AsVariant)),2,1) = '0' then
  22.  
  23. begin
  24. ADOQuery2.Edit;
  25. ADOQuery2.FieldByName('userAccountControl').Value:=ADOQuery2.FieldByName('userAccountControl').Value+2;
  26. ADOQuery2.Post;
  27. end;
  28. ADOQuery3.Next;
  29. end;
  30. ADOQuery3.First;
  31. ADOQuery2.Next;
  32. end;


KilkaMS Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: KilkaMS (статус: Посетитель)
Вопрос отправлен: 8 июля 2010, 14:48
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 10; последнее сообщение — 13 июля 2010, 22:11; участников в обсуждении: 2.

8 июля 2010, 18:24: Вопрос перемещён из тематического раздела Delphi » Взаимодействие с Windows в раздел Delphi » Программирование баз данных (БД) модератором Ерёмин А.А.

Егор

Егор (статус: 10-ый класс), 8 июля 2010, 18:53 [#1]:

форматирование кода писец, конечно...
и комментариев до фига

procedure TDM.DataModuleCreate(Sender: TObject);
 
VAR
i,j:integer;
name, middlename : string;  // вот давайте не будем писать эти жуткие
                            // "ADOQuery3.FieldByName('middlename').Value"
                            // по сто раз?
 
begin
  ADConnection.Open;
  DBFConnection.Open;
  ADOQuery1.Open;
  ADOQuery2.Open;
  ADOQuery3.Open;
  ADOQuery2.First;
  ADOQuery3.First;
  for i:= 0 to ADOQuery2.RecordCount do
  begin
    for j:=0 to ADOQuery3.RecordCount do
    begin
      name:=ADOQuery3.FieldByName('firstname').Value;  // вынесем это дело в отдельную переменную
      if Copy(name, 1, Pos(' ',name)-1) = ADOQuery2.FieldByName('sn').AsString then
      begin
        middlename:=ADOQuery3.FieldByName('middlename').Value;  // вынесем это дело в отдельную переменную
        if Copy(middlename,1,Pos(' ',middlename)-1) = ADOQuery2.FieldByName('givenName').Value then
          if ADOQuery3.FieldByName('dateout').AsDateTime < date then
            if Copy(ReverseString(IntToBin(ADOQuery2.FieldByName('userAccountControl').AsVariant)),2,1) = '0' then
              if MessageDlg('Вы действительно хотите заблокировать пользователя ' + #13 + 
                            ADOQuery2.FieldByName('sn').AsString + ' ' +
                            ADOQuery2.FieldByName('givenName').Value, mtConfirmation, [mbYes, mbNo], 0) = 6 then
              begin
                ADOQuery2.Edit;
                ADOQuery2.FieldByName('userAccountControl').Value:=ADOQuery2.FieldByName('userAccountControl').Value+2;
                ADOQuery2.Post;
              end;
              ADOQuery3.Next;
      end;
    end;
    ADOQuery3.First;
    ADOQuery2.Next;
  end;
// закрывающего end-а нет. но я так понял, это лишь фрагмент кода, т.е. продолжение следует?

ADOQuery2.FieldByName('userAccountControl').Value:=ADOQuery2.FieldByName('userAccountControl').Value+2;
это что? зачем увеличиваем на 2?

if MessageDlg('Вы действительно хотите...', mtConfirmation, [mbYes, mbNo], 0) = 6
что такое "6"?

Цитата (KilkaMS):

Осталось только заблокировать, как это сделать основываясь на моем коде?

а что должно быть и в какой таблице/поле, чтобы учётка считалась заблокированной?

Цитата (KilkaMS):

P.S.Можно сразу подсказать как поставить галочку
"Скрывать в адресной книге ексченджа "

аналогично - что и где должно быть записано, чтобы AD посчитал, что галочка стоит?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
KilkaMS

KilkaMS (статус: Посетитель), 9 июля 2010, 00:07 [#2]:

"ADOQuery2.FieldByName('userAccountControl').Value:=ADOQuery2.FieldByName('userAccountControl').Value+2;это что? зачем увеличиваем на 2?"

2 это изменение 2-го с конца бита...понимаю что замудрено но это единственное что смог придумать, 'userAccountControl' это состовная, так сказать, переменная, тут включено много атрибутов, второй с конца бит это как раз атрибут блокировки как мне удалось выяснить. Есть часть кода преобразовывающая Int в Bin.


"if MessageDlg('Вы действительно хотите...', mtConfirmation, [mbYes, mbNo], 0) = 6"

6 это значит что была нажата кнопка ДА

это основная часть кода которая и работает с AD

" begin
ADOQuery2.Edit;
ADOQuery2.FieldByName('userAccountControl').Value:=ADOQuery2.FieldByName('userAccountControl').Value+2;
ADOQuery2.Post;
end;"

эта часть кода не работает, т.е. изменения не сохраняются, здесь видимо нужно команды посылать... открывал все для записи, права так же есть на редактирование схемы у пользователя

Код заграможден изза кривизны базы кадровика, приходилось всякие обрезания добавлять

"а что должно быть и в какой таблице/поле, чтобы учётка считалась заблокированной?"

как раз увелечение 'userAccountControl' на 2 в десятичнов системе, а именно так я к ней получаю доступ, и означает блокировку

"“Цитата” (KilkaMS)
P.S.Можно сразу подсказать как поставить галочку
"Скрывать в адресной книге ексченджа "

аналогично - что и где должно быть записано, чтобы AD посчитал, что галочка стоит? ""
вот это еще не выяснил

простите что без цитат,чтото не разобрался как их ставить
Егор

Егор (статус: 10-ый класс), 9 июля 2010, 05:14 [#3]:

если нужно установить 2-ой бит, то не прибавляем - потому что если там уже стоит 2-ой бит, то он обнулится.
пользуемся оператором or
ну и мой личный опыт говорит о том, что свойство Value лучше не использовать, а получать/записывать данные в том формате, который нужен, явно указывая тип. в данном случае - AsInteger. хотя в этом утверждении я могу и ошибаться.
ADOQuery2.FieldByName('userAccountControl').AsInteger:=ADOQuery2.FieldByName('userAccountControl').AsInteger or 2;

ещё возможно, что база открывается в пакетном режиме - тогда сохранения не будет. нигде нет подобной команды:
ADOQuery2.LockType:=ltBatcOptimistic;
?

если есть, то, значит, открываем таблицу в пакетном режиме. и сохранять надо так:
  ADOQuery2.Post;
  ADOQuery2.UpdateBatch;

отпишитесь по результатам - там посмотрим, что ещё может быть
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
KilkaMS

KilkaMS (статус: Посетитель), 9 июля 2010, 10:05 [#4]:

Указанные изменения внес в код, ошибок не выскакивает, изменения не сохраняются

дельное замечание по поводу or но я все равно проверяю сначало стоит он или нет, хотя можно хорошенько сократить код. изменил код таким образом

procedure TDM.DataModuleCreate(Sender: TObject);
 
VAR
 i,j:integer;
 
begin
ADConnection.Open;
DBFConnection.Open;
ADOQuery2.LockType:=ltBatchOptimistic;
ADOQuery1.Open;
ADOQuery2.Open;
ADOQuery3.Open;
ADOQuery2.First;
ADOQuery3.First;
for i:= 0 to ADOQuery2.RecordCount do
  begin
   for j:=0 to ADOQuery3.RecordCount do
      begin
         if Copy(ADOQuery3.FieldByName('firstname').Value,1,Pos(' ',ADOQuery3.FieldByName('firstname').Value)-1) =
ADOQuery2.FieldByName('sn').AsString then
           if Copy(ADOQuery3.FieldByName('middlename').Value,1,Pos(' ',ADOQuery3.FieldByName('middlename').Value)-1) =
ADOQuery2.FieldByName('givenName').Value then
             if ADOQuery3.FieldByName('dateout').AsDateTime < date then
               if ADOQuery2.FieldByName('userAccountControl').Value <> ADOQuery2.FieldByName('userAccountControl').Value
or 2 then
                 if MessageDlg('Вы действительно хотите заблокировать пользователя 
'+#13+ADOQuery2.FieldByName('sn').AsString+' '+ADOQuery2.FieldByName('givenName').Value,mtConfirmation,[mbYes,
mbNo],0)=6 then
                   begin
                      ADOQuery2.Edit;
 
ADOQuery2.FieldByName('userAccountControl').Value:=ADOQuery2.FieldByName('userAccountControl').Value or 2;
                      ADOQuery2.Post;
                      ADOQuery2.UpdateBatch;
                   end;
         ADOQuery3.Next;
      end;
      ADOQuery3.First;
      ADOQuery2.Next;
  end;
end;
Егор

Егор (статус: 10-ый класс), 9 июля 2010, 20:24 [#5]:

ну вот
ADOQuery2.LockType:=ltBatchOptimistic;
и
ADOQuery2.UpdateBatch;
как раз таки и не стоило делать :)

а вот переделать
ADOQuery2.FieldByName('userAccountControl').Value
в
ADOQuery2.FieldByName('userAccountControl').AsInteger
может быть стоит

и ещё вопрос - какой запрос прописан в ADOQuery2? если возвращается не-live ответ, то соранить изменения в нём не удастся. правда, там вроде бы ошибка должна выскакивать.

короче. меняем Value на AsInteger и приводим текст запроса.
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
KilkaMS

KilkaMS (статус: Посетитель), 11 июля 2010, 11:03 [#6]:

ну вот
 
 
ADOQuery2.LockType:=ltBatchOptimistic;и
 
ADOQuery2.UpdateBatch;как раз таки и не стоило делать :)
А что нужно оставить?

ADOQuery2.FieldByName('userAccountControl').AsInteger
Тип и так интеджер и определяется также,смысла менять нет

select givenName,sn,userAccountControl
from 'LDAP://DC=мой_домен, DC=ru' 
where objectCategory='person' and objectClass='user'
order by sn
Запрос ADOQuery2
Егор

Егор (статус: 10-ый класс), 11 июля 2010, 17:07 [#7]:

Цитата (KilkaMS):

А что нужно оставить?

да ладно, фиг с ним, пусть остаётся. не страшно

Цитата (KilkaMS):

ADOQuery2.FieldByName('userAccountControl').AsInteger
Тип и так интеджер и определяется также,смысла менять нет

смысл менять ЕСТЬ. я же написал - совет из личного опыта. в одном месте поменять - трудно, что ли?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
KilkaMS

KilkaMS (статус: Посетитель), 12 июля 2010, 08:34 [#8]:

“Цитата” (KilkaMS)
 
ADOQuery2.FieldByName('userAccountControl').AsIntegerТип и так интеджер и определяется также,смысла менять нет
 
смысл менять ЕСТЬ. я же написал - совет из личного опыта. в одном месте поменять - трудно, что ли?

поменял, никакого положительного результата. (
Егор

Егор (статус: 10-ый класс), 13 июля 2010, 18:09 [#9]:

хм...
надо бы к Вадиму обратиться - может он подскажет. Он базы лучше знает

а с помощью ADOTable не пробовали с таблицей работать?
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
KilkaMS

KilkaMS (статус: Посетитель), 13 июля 2010, 22:11 [#10]:

все дело в том,что нельзя получить доступ с помощью Table, только запрос, вот я и думаю что командами нужно блочить,это всетаки не совсем база данных, это глобыльный каталог AD, а как к вадиму можно обратиться?

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 12:02
Выполнено за 0.06 сек.