none
Помогите правильно составить запрос в AD RRS feed

  • Вопрос

  • Есть скрипт, который должен делать выборку всех заблокированных пользователей в домене, следующего вида:

    Образец кода

    Const ADS_UF_SCRIPT = &H0001
    Const ADS_UF_ACCOUNTDISABLE = &H0002
    Const ADS_UF_HOMEDIR_REQUIRED = &H0008

    Const ADS_UF_LOCKOUT = &H0010
    Const ADS_UF_PASSWD_NOTREQD = &H0020
    Const ADS_UF_PASSWD_CANT_CHANGE = &H0040
    Const ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = &H0080
    Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000
    Const ADS_UF_SMARTCARD_REQUIRED = &H40000
    Const ADS_UF_PASSWORD_EXPIRED = &H800000


    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"

    Set    objCommand = CreateObject("ADODB.Command")
    objCommand.ActiveConnection = objConnection
    objCommand.Properties("Size Limit")= 10000
    objCommand.Properties("Page Size")= 10000
    objCommand.Properties("Sort on") = "distinguishedName"

    objCommand.CommandText = _
        ";(objectCategory=User)" & _
        ";userAccountControl,distinguishedName;subtree"


    Set objRecordSet = objCommand.Execute '<---- Произошла одна или несколько ошибок во время обработки комманды. Код: 80040E14 (Здесь ошибка)

    objRecordSet.MoveFirst
    intCounter = 0
    Do Until objRecordSet.EOF
        intUAC=objRecordset.Fields("userAccountControl")
        If intUAC AND ADS_UF_LOCKOUT Then
            WScript.echo objRecordset.Fields("distinguishedName") & " is locked"
        intCounter = intCounter + 1
        End If
        objRecordset.MoveNext
    Loop
     
    WScript.Echo VbCrLf & "A total of " & intCounter & " accounts are locked."
    objConnection.Close


    Но вот при выполнении, ругается. Подозреваю, что неправильно составил запрос objCommand.CommandText = ...
    Подскажите правильное решение?
    1 ноября 2007 г. 9:47

Ответы

Все ответы

  • У вас в строке запроса отсутствует указание домена. Должно быть что-то а-ля:

    Образец кода

    objCommand.CommandText = _
        "<GC://dc=fabrikam,dc=com>;(objectCategory=User)" & _
            ";userAccountControl,distinguishedName;subtree"

    В общем вот готовый скрипт для вашего случая:

    Образец кода
    Const ADS_UF_ACCOUNTDISABLE = 2 Set objConnection = CreateObject("ADODB.Connection")objConnection.Open "Provider=ADsDSOObject;"Set objCommand = CreateObject("ADODB.Command")objCommand.ActiveConnection = objConnectionobjCommand.CommandText = _    "<GC://dc=fabrikam,dc=com>;(objectCategory=User)" & _        ";userAccountControl,distinguishedName;subtree"  Set objRecordSet = objCommand.Execute intCounter = 0Do Until objRecordset.EOF    intUAC=objRecordset.Fields("userAccountControl")    If intUAC AND ADS_UF_ACCOUNTDISABLE Then        WScript.echo objRecordset.Fields("distinguishedName") & " is disabled"        intCounter = intCounter + 1    End If    objRecordset.MoveNextLoop WScript.Echo VbCrLf & "A total of " & intCounter & " accounts are disabled." objConnection.Close

     

     

    Источник: http://www.microsoft.com/technet/scriptcenter/scripts/ad/users/status/usstvb03.mspx?mfr=true

    2 ноября 2007 г. 7:55
  • Спасибо. Теперь работает без ругани. Но все равно не показывает залоченных пользователей, хотя если поменять признак поиска по заблокированным пользователям (ADS_UF_ACCOUNTDISABLE) - все нормально отображается.

     

    и еще подскажите как в цикле проверки разблокировать такого пользователя. Есть свойство в объекте пользователя IsLocked а дальше к какому объекту применять...

     

    2 ноября 2007 г. 12:26
  • Ну нпример вот так:

    Образец кода

    Set objUser = GetObject _
        ("LDAP://cn=MyerKen,ou=Management,dc=NA,dc=fabrikam,dc=com")

    objUser.IsAccountLocked
    = False
    objUser.SetInfo

     

     

    Источник: http://www.microsoft.com/technet/scriptcenter/scripts/ad/users/status/usstvb03.mspx?mfr=true
    2 ноября 2007 г. 13:51
  • Все верно, но в этом примере идет установка свойства в контексте обекта из запроса LDAP. Мне нужно устанавливать свойство залоченности в контексте объекта objRecordSet который в свою очередь является выборкой ADODB.

     

    как я уже писал выборка

     

        intUAC=objRecordset.Fields("userAccountControl")
        If intUAC AND ADS_UF_LOCKOUT Then
            WScript.echo objRecordset.Fields("distinguishedName") & " is locked"
        End If

     

    не работает.

     

    Значение AND ADS_UF_LOCKOUT = 16 т.е. определяющим является 4 бит, если он равен 1 то запись не заблокирована (или наоборот ?)

    В общем если изменить условие на If NOT (intUAC AND ADS_UF_LOCKOUT) Then... то показываются вообще все учетки. Вроде так и должно быть...

    ну и допустим с выборкой разберусь, далее как поменять значение бита? так?

     

    objRecordset.Fields("userAccountControl").Value = intUAC AND 16  ' (Const ADS_UF_LOCKOUT = &H0010 )

     

    или вообще c objRecordset ничего "делать" нельзя, нужно открывать новый объект?

    2 ноября 2007 г. 15:22
  • В общем, порылся на форумах, посмотрел примеры на microsoft, в итоге родился такой скрипт:

     

    Образец кода

    Const  ADS_UF_LOCKOUT = 16      '// 0x10

    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Open "Provider=ADsDSOObject;"
    Set objCommand = CreateObject("ADODB.Command")
    objCommand.ActiveConnection = objConnection
    objCommand.CommandText = _
        "<GC://OU=otdel1;dc=office,dc=contora,dc=loc>;(objectCategory=User)" & _
            ";userAccountControl,distinguishedName,name;subtree" 

    Set objRecordSet = objCommand.Execute

    intCounter = 0
    Do Until objRecordset.EOF
        intUAC=objRecordset.Fields("userAccountControl")
        If intUAC AND NOT ADS_UF_LOCKOUT Then
            WScript.echo "Учетная запись " & objRecordset.Fields("name") & " заблокирована"
            intCounter = intCounter + 1
        End If
        objRecordset.MoveNext
    Loop
     
    WScript.Echo VbCrLf & "Всего " & intCounter & " записей заблокировано."
     
    objConnection.Close

     

     

    Вот вроде бы все должно работать... но не работает (выводит вообще список всех пользователей OU)

    на каком-то англоязычном форуме видел предположение, что провайдер ADsDSOObject криво работает  с полем userAccountControl.

    Эй Scripting Guys из Microsoft Corporation подскажите уж, что я не правильно делаю?

     

    6 ноября 2007 г. 7:51
  • Пользуясь первоисточниками, любезно предоставленными sae, нашел что флаг ADS_LOCKOUT не работает в домене 2003. :-) 

     

    Цитата:

    Примечание В домене под управлением Windows Server 2003 флаги LOCK_OUT и PASSWORD_EXPIRED заменены новым атрибутом ms-DS-User-Account-Control-Computed. Для получения дополнительных сведений о данном атрибуте посетите веб-узел:...

     

    Попытался проанализировать запрос составляемый в оснастке "Пользователи и компьютеры" для заблокированных пользователей, вот так выглядит запрос:

    (&(&(objectCategory=person)(objectClass=user)(name=*)(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2)))

     

    Для флага ms-DS-User-Account-Control-Computed

    Attribute-Id: 1.2.840.113556.1.4.1460

     

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

    (&(&(objectCategory=person)(objectClass=user)(name=*)(objectCategory=person)(objectClass=user)(ms-DS-User-Account-Control-Computed:1.2.840.113556.1.4.1460:=16)))

     

    но не отображает ни одного пользователя.... смотрел свойства залоченного пользователя adsiedit'ом

    ms-DS-User-Account-Control-Computed = 16 (объект есть и = 16 в случае если он залочен)

    ну что еще надо???

    15 ноября 2007 г. 7:05
  • Решился вопрос. В общем работает вот такой запрос, из оснастки Users and Computers, впрочем и в скрипте будет работать:

     

    (&(&(objectCategory=person)(objectClass=user)(LockoutTime>=1)))

     

    Спасибо всем, кто откликнуля и навел на путь истинный :-)

     

     

    5 декабря 2007 г. 12:44
  • BTW Оч неплохой гайд по поиску в AD :

    http://www.rlmueller.net/ADOSearchTips.htm

     

     

    5 декабря 2007 г. 13:25
  • Попутно возник еще вопрос. Как отфильтровать пользователей, имеющих непустой логон скрипт (тот, что задается через свойства пользователя в оснастке Users and Computers)?
    30 января 2008 г. 14:59
  • (&(&(objectCategory=person)(objectClass=user)(scriptPath=*)))

    30 января 2008 г. 15:17
    Модератор
  • Вот спасибо! Может, кто еще готовые запросы выложит? Удобно.

    31 января 2008 г. 11:19
  • Какие?! Их же бесконечно много

     

    31 января 2008 г. 11:21
    Модератор
  • Ну еще интересуют запросы фильтрации пользователей у которых Bad Password Count > 0.

    lastlogon/logoff = {определенная дата}

     

    вообще, те которые позволят как можно меньше пользоваться гиеной и dameware...
    31 января 2008 г. 15:15
  • Атрибут lastlogon не реплицируемый! Т.е. надо выполнять поиск по всем DC!!! http://msdn2.microsoft.com/en-us/library/ms676823.aspx

    Есть атрибут lastLogonTimeStamp Он реплицирутся, но редко (раз в 9 - 14 дней)http://msdn2.microsoft.com/en-us/library/ms676824.aspx

    Можно посмотреть это

    И это

    Хороший пример http://www.rlmueller.net/Programs/LastLogon.txt

     

    Куча примеров с запросами http://www.petri.co.il/ldap_search_samples_for_windows_2003_and_exchange.htm

     

     

    Здесь List Bad Password Count
    Атрибут тоже не реплицируемый! http://msdn2.microsoft.com/en-us/library/ms675244(VS.85).aspx

     

    Еще одна ссылка на последок http://www.rlmueller.net/freecode4.htm

    1 февраля 2008 г. 10:19
    Модератор