Announcement

Collapse
No announcement yet.

LDAP query to search multple OUs

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • LDAP query to search multple OUs

    Hey guys, I did some Googling trying to find a way to search multiple OUs but came up empty handed.

    What I want to do is query two different OUs for all the computers in them.

    For example, I want to search the two locations below but I don't want to search any other OUs.
    Code:
    ou=workstations,dc=domain,dc=com
    
    ou=servers,dc=domain,dc=com
    Is there a way to do this or will I have to make two searches and put the results in an array?
    Regards,
    Jeremy

    Network Consultant/Engineer
    Baltimore - Washington area and beyond
    www.gma-cpa.com

  • #2
    Re: LDAP query to search multple OUs

    I Have tried with "&&" operator & it worked.

    eg:-
    dsquery computer "ou=workstations,dc=domain,dc=com" && dsquery computer "ou=servers,dc=domain,dc=com"
    Cheers!!
    MCSE 2003,MCSA- Messaging 2003, VCP

    Comment


    • #3
      Re: LDAP query to search multple OUs

      Thanks for the suggestion but I forgot to mention that this is for a VBScript.

      I did some reading on it yesterday and instead of searching two different places I can just filter the results like this:
      Code:
      objCommand.CommandText = _
          "<LDAP://" & strADsPath & ">;" & _
              "(&(objectCategory=computer)(|(operatingSystem=Windows XP*)(operatingSystem=Windows 2000 P*)))" & _
              ";distinguishedName,name;subtree"
      I would still like to know if I can have it search two different places in one query but I may just have to use filters.
      Regards,
      Jeremy

      Network Consultant/Engineer
      Baltimore - Washington area and beyond
      www.gma-cpa.com

      Comment


      • #4
        Re: LDAP query to search multple OUs

        I don't have an AD (and didn't want to install ADAM) at home so I can't check it, but the operand you should use is '|' (OR).

        so your LDAP search filter should look something like this:
        Code:
        (&(objectCategory=computer)(|(distinguishedName=*ou=workstations,dc=domain,dc=com)(distinguishedName=*ou=servers,dc=domain,dc=com)))
        and the strADsPath variable should hold the defaultNamingContext to your domain:
        Code:
        strADsPath = GetObject("LDAP://RootDSE").Get("defaultNamingContext")
        check out these links for more info. on LDAP search filters:
        http://technet.microsoft.com/en-us/l.../aa996205.aspx
        http://www.rlmueller.net/ADOSearchTips.htm

        Good luck!
        Martin.

        Comment


        • #5
          Re: LDAP query to search multple OUs

          Thanks Martin. Today I was going to try and find the syntax for filtering by DN but you did it for me!
          Regards,
          Jeremy

          Network Consultant/Engineer
          Baltimore - Washington area and beyond
          www.gma-cpa.com

          Comment


          • #6
            Re: LDAP query to search multple OUs

            Well I found out that you can't use wildcards in DN or CN filters.

            My options as I see them are:
            1. Perform two searches
            or
            2. Configure a custom attribute on the objects and use that to filter the results

            I heard speak of parsing the results of one query... I may try to do that.

            Any ideas anyone?
            Anything I'm missing?
            Regards,
            Jeremy

            Network Consultant/Engineer
            Baltimore - Washington area and beyond
            www.gma-cpa.com

            Comment


            • #7
              Re: LDAP query to search multple OUs

              My options as I see them are:
              1. Perform two searches
              2. Configure a custom attribute on the objects and use that to filter the results
              example of two searches:
              Code:
              ' Create an array with the OUs to want start querying from
              ' Use ADO to just Enumerate first all the computerobjects in the OU_subtrees, 
              ' and append the results to a Scripting.Dictionary
              ' Then use the dictionary object to connect to each found object in the Active Directory.
              
              'Set the ADO connection query strings
              strDNSDomain = "dc=domain, dc=local"
              strFilter = "(objectCategory=computer)"
              strAttributes = "distinguishedName,objectCategory,name"
              n=2:dim QueryPath(2) '=counted OU-roots to query from, 1 to n   ( I skipped (0) )
                    QueryPath(1)="OU=Portables,OU=Client Computers," & strDNSDomain
                    QueryPath(2)="OU=Desktops,OU=Client Computers," & strDNSDomain
              
              Set objItemsDictionary=CreateObject("Scripting.Dictionary"):x=0
              
              'Start the ADO connection
              Set objCommand = CreateObject("ADODB.Command")
              Set objConnection = CreateObject("ADODB.Connection")
              objConnection.Provider = "ADsDSOObject"
              objConnection.Open "Active Directory Provider"
              objCommand.ActiveConnection = objConnection
              
              'Create the Query
              for i = 1 to n
                strQuery = "<LDAP://" & QueryPath(i) & ">;" & strFilter & ";" _
                            & strAttributes & ";subtree"
              
                objCommand.CommandText = strQuery
                objCommand.Properties("Page Size") = 100
                objCommand.Properties("Timeout") = 30
                objCommand.Properties("Cache Results") = False
              
                Set objRecordSet = objCommand.Execute '(i)
                objRecordSet.MoveFirst
              
                'Find all computers in the domain
                While Not objRecordset.EOF
                  strItem = objRecordset.Fields("distinguishedName")
                  objItemsDictionary.Add x, strItem
                  x = x + 1
                  objRecordSet.MoveNext
                Wend
              next
              
              'connect to each computerobject from the list of results
              ' (keep a reference to the RootDSE object to  
              ' prevent additional bind requests to the server
              ' http://msdn2.microsoft.com/en-us/library/ms806997.aspx#buildingadapps_using_good_adsi )
              Set oRootDSE = GetObject("LDAP://RootDSE")
              For Each objItem In objItemsDictionary
                 strDistinguishedName = objItemsDictionary.Item(objItem)
                 'Now you can process each selected computer;
                 Set oComputer = GetObject("LDAP://" & strDistinguishedName)
              
                    msgbox mid(oComputer.name,4)
              
              Set oComputer = Nothing:next
              
              wscript.quit
              The script above will query the entire paths starting from each of the OU's,

              if you want to search only within in the OUs w/out the subOU's then replace the "ADO connection" with this code below:
              Code:
              ' Connect to an object                 *
              Set objRootDSE = GetObject("LDAP://rootDSE")
              strDNSDomain = objRootDSE.Get("defaultNamingContext")
              strFilter = Array("Computer")
              
              n=2:dim QueryPath(2) '=counted the OUs to search in, 1 to n   ( I skipped (0) )
                    QueryPath(1)="OU=Portables,OU=Client Computers," & strDNSDomain
                    QueryPath(2)="OU=Desktops,OU=Client Computers," & strDNSDomain
              
              Set objItemsDictionary=CreateObject("Scripting.Dictionary"):x=0
              
              'Create the Query
              for i = 1 to n
                 strQuery = "LDAP://" & QueryPath(i)
                 Set colItems = GetObject(strQuery):colItems.Filter = strFilter 
                 For Each objComputer in colItems
                   strItem = objComputer.distinguishedName
                   objItemsDictionary.Add x, strItem
                   x = x + 1
                 Next
              Next

              Well, this is just an idea, I did not tested it in large environments.

              \Rems

              This posting is provided "AS IS" with no warranties, and confers no rights.

              __________________

              ** Remember to give credit where credit's due **
              and leave Reputation Points for meaningful posts

              Comment


              • #8
                Re: LDAP query to search multiple OUs

                Thanks Rems. I think that will work (with a few modification )
                Since all I need is the computer names so I can connect to them through WMI, I used an array instead of the dictionary object.

                Code:
                ' Create an array with the OUs to want start querying from
                ' Use ADO to just Enumerate first all the computerobjects in the OU_subtrees, 
                ' and append the results to a Scripting.Dictionary
                ' Then use the dictionary object to connect to each found object in the Active Directory.
                
                'Set the ADO connection query strings
                strDNSDomain = "dc=domain, dc=local"
                strFilter = "(objectCategory=computer)"
                strAttributes = "name"
                n=2:dim QueryPath(2) '=counted OU-roots to query from, 1 to n   ( I skipped (0) )
                      QueryPath(1)="OU=Portables,OU=Client Computers," & strDNSDomain
                      QueryPath(2)="OU=Desktops,OU=Client Computers," & strDNSDomain
                
                Dim arrComputers():intSize=0
                
                'Start the ADO connection
                Set objCommand = CreateObject("ADODB.Command")
                Set objConnection = CreateObject("ADODB.Connection")
                objConnection.Open "Provider=ADsDSOObject;"
                objCommand.ActiveConnection = objConnection
                
                'Create the Query
                for i = 1 to n
                  strQuery = "<LDAP://" & QueryPath(i) & ">;" & strFilter & ";" _
                              & strAttributes & ";subtree"
                
                  objCommand.CommandText = strQuery
                  objCommand.Properties("Page Size") = 100
                  objCommand.Properties("Timeout") = 30
                  objCommand.Properties("Cache Results") = False
                
                  Set objRecordSet = objCommand.Execute '(i)
                  objRecordSet.MoveFirst
                
                  'Find all computers in the domain
                  While Not objRecordset.EOF
                    ReDim Preserve arrComputers(intSize)
                    arrComputers(intSize) = objRecordset.Fields("Name")
                    intSize = intSize + 1
                    objRecordSet.MoveNext
                  Wend
                next
                
                
                For i = 0 to intSize - 1
                   ClearQueue arrComputers(i)
                next
                
                wscript.quit
                
                Sub ClearQueue(strComputer)
                  
                  On Error Resume Next
                  Set objWMIService = GetObject("winmgmts:" _
                    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
                  Set colPrinters = objWMIService.ExecQuery("SELECT * FROM win32_Printer")
                
                  For Each objPrinter in colPrinters
                    objPrinter.CancelAllJobs
                  Next
                
                End Sub
                Regards,
                Jeremy

                Network Consultant/Engineer
                Baltimore - Washington area and beyond
                www.gma-cpa.com

                Comment


                • #9
                  Re: LDAP query to search multple OUs

                  in addition

                  define a constant named ADS_SCOPE_SUBTREE for to ADO connection and set the value to 2. If you want to search the OU and its sub-OUs you have to use that constant when defining the search scope:

                  'Start the ADO connection
                  Const ADS_SCOPE_SUBTREE = 2

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

                  'Create the Query
                  ..
                  ..
                  objCommand.Properties("Page Size") = 1000 ' <--(1000 = the maximum value)
                  objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
                  ..
                  ..


                  When the Searchscope property is set to 2, a search will be conducted in a container/ou and all its sub-containers (and all their sub-containers). If you wanted to search just an OU (ignoring its sub-OUs) then set Searchscope to 1.

                  next,
                  By default, any time you run a query against Active Directory you only get back the first 1,000 objects! That is why you have to specify a Page Size. So if you don’t specify one, Active Directory returns only the first 1,000 items. If you do specify a Page Size, however, Active Directory will return the first x items, then pause for a split second and return the next x items, then pause for a split second, and so on. This will continue until all the items have been returned.
                  (For more information about using scripts to search Active Directory, see this Scripting Guys' webcast.

                  finally,
                  After both AD queries are done you can ' Clean up' to free memory;
                  objRecordSet.Close
                  objConnection.Close



                  This posting is provided "AS IS" with no warranties, and confers no rights.

                  __________________

                  ** Remember to give credit where credit's due **
                  and leave Reputation Points for meaningful posts

                  Comment


                  • #10
                    Re: LDAP query to search multple OUs

                    Many thanks again!

                    I'll change the page size (though this is an SBS environment so I can't get any more than 75 computers ) and add the lines for closing the record set and connection.

                    One question though. Is specifying "subtree" in the query not enough to search the sub OUs? I did test the script I posted and it did pick up the computers from the sub OUs.
                    Regards,
                    Jeremy

                    Network Consultant/Engineer
                    Baltimore - Washington area and beyond
                    www.gma-cpa.com

                    Comment


                    • #11
                      Re: LDAP query to search multple OUs

                      Originally posted by JeremyW View Post
                      One question though. Is specifying "subtree" in the query not enough to search the sub OUs?
                      Yes you are right.
                      The Searchscope is the property that also can be included in the querystring, like you did in your script. So it won't be nessesary to specify it twice in a script.

                      (about the 'subtree' in particular, this is also the deault setting when no Searchscope was specified)

                      \Rems

                      This posting is provided "AS IS" with no warranties, and confers no rights.

                      __________________

                      ** Remember to give credit where credit's due **
                      and leave Reputation Points for meaningful posts

                      Comment


                      • #12
                        Re: LDAP query to search multple OUs

                        Thanks Rems.
                        Regards,
                        Jeremy

                        Network Consultant/Engineer
                        Baltimore - Washington area and beyond
                        www.gma-cpa.com

                        Comment

                        Working...
                        X