• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4797
  • Last Modified:

LDAP query needed, users in exchange

Hi,

I've got the following code (it's actually VBS that runs in Script host, but ASP solutions will be fine):

Set ADOConn = CreateObject("ADODB.Connection")
ADOConn.Provider = "ADSDSOObject"
ADOConn.Open "Active Directory Provider"

Set ADOCommand = CreateObject("ADODB.Command")

Set ADOCommand.ActiveConnection = ADOConn
ADOCommand.CommandText = "<LDAP://Servername> --BLABLABLA"

Set RS = ADOCommand.Execute

if rs.eof then
wscript.echo "No details found...."
end if

While Not RS.EOF
    wscript.echo RS.Fields(0)
    Set objUser = GetObject(RS.Fields("adspath"))
    wscript.echo "Firstname: " & objuser.get("givenName")
    wscript.echo "Surname: " & objuser.get("sn")
    wscript.echo "Title: " & objuser.get("title")
    wscript.echo "SMTP: " & objuser.get("mail")
    wscript.echo "Manager: " & objuser.get("manager")
    wscript.echo "PhoneNumber: " & objuser.get("telephoneNumber")
    wscript.echo "----------------------------------------------"
    RS.MoveNext
Wend

RS.Close
Set ADOConn = Nothing
Set ADOCommand = Nothing
Set RS = Nothing


I will need a LDAP query (see BLABLABLA) that will return ALL users in our Exchange directory (including email addresses and titles and managers and Phonenumbers etc..).

The only variable it will take is the exchange servername.

I've been looking on MSDN but couldn't really find any good examples. That LDAP syntax is confusing !!

FUll points and A grade for working Query !

Cheers,
Mike.
0
kikkertm
Asked:
kikkertm
  • 8
  • 6
  • 2
1 Solution
 
clockwatcherCommented:
The following works for me:

<HTML>
<BODY>
<%
  set con = server.CreateObject("ADODB.Connection")
  set rs = server.CreateObject("ADODB.Recordset")
  con.Provider = "ADsDSOObject"
  con.Open "Exchange Server"
 
  ' <-- Replace IP Below with your Exchange Server's Name/IP in the line below
  ' <-- Replace ORGANIZATION with Exchange's Organization
  ' <-- Replace SITE with Exchange's Site

  rs.Open "<LDAP://127.0.0.1/o=ORGANIZATION/ou=SITE/cn=Recipients>;(cn=*); givenName, sn, title, mail, manager, telephoneNumber", con


  If rs.EOF Then
     Response.Write "No Records Found"
  Else
     do while not rs.EOF
        for each f in rs.Fields
             Response.Write f.name & ":" & f.value & "<BR>"
        next
        Response.Write "<BR>"
        rs.MoveNext
     loop
  End If    
  rs.Close
  set rs = nothing
  con.Close
  set con = nothing
 %>

</BODY>
</HTML>
0
 
kikkertmAuthor Commented:
I'll give it a try as soon as I can. I'm away on holiday next week, so replies might be slow.

Cheers,
Mike.
0
 
kikkertmAuthor Commented:
clockwatcher,

how can I find out what the registered organisation name would be ? Also, what would the SITE name be ?

I experimented a bit and the script comes back with:
"Provider: Table does not exist."

I think we're on the right track, just have to find the org and site names.

Cheers,
Mike.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
clockwatcherCommented:
Try the following:

<%@ Language=VBScript %>
<script language="vbscript" runat="server">
sub writeln(val)
  response.write val & "<BR>"
end sub
</script>

<HTML>
<BODY>
<%
   set con = server.CreateObject("ADODB.Connection")
   con.Provider = "ADsDSOObject"
   con.Open "Exchange Server"
   
   set rs = con.execute("<LDAP://127.0.0.1>;(o=*); o")
   
   if rs.eof then
      writeln "Can't determine organization"
   
   else  'found organization
      org = rs.fields("o").value
      if vartype(org) > 8192 then
        o=org(lbound(org))
      else
        o=org
      end if
     
      writeln "Organization: " & o
      rs.close
      set rs = nothing
     
      set rs = con.execute("<LDAP://127.0.0.1/o=" & o & ">;(ou=*); ou")
      if rs.eof then
        writeln "Can't determine organizational unit"
     
      else 'found organizational unit
        orgu = rs.fields("ou").value
        if vartype(orgu) > 8192 then
          ou=orgu(lbound(orgu))
        else
          ou=orgu
        end if

        writeln "Organizational unit: " & ou
        rs.close
        set rs = nothing

        writeln ""
        set rs = con.execute("<LDAP://127.0.0.1/o=" & o & "/ou=" & ou & "/cn=Recipients>;(cn=*); givenName, sn, title, mail, manager, telephoneNumber")

        do while not rs.EOF
           for each f in rs.Fields
                 writeln f.name & ": " & f.value
           next
           rs.MoveNext
           writeln ""
        loop
     
      end if 'find organizational unit

   end if 'find organization
   
   rs.close
   set rs = nothing
   con.close
   set con =  nothing
 %>

</BODY>
</HTML>
0
 
kikkertmAuthor Commented:
Thanks Clockwatcher, I just arived back from holiday and I will test it tuesday and will let you know. Please have a bit of patience..

Cheers,
Mike.
0
 
kikkertmAuthor Commented:
Clockwatcher, I tried it, but I'm getting an error back:
-----------------------------------------------
Active Directory error '80040e37'

An invalid Active Directory pathname was passed

/ldap/getdetails.asp, line 16
-----------------------------------------------
Where line 16 is the line:

  set rs = con.execute("<LDAP://127.0.0.1>;(o=*); o")



.... Help ?
0
 
clockwatcherCommented:
Are you sure LDAP is enabled on the box you're trying to connect to and that it's running on the default port (389)?

Can you connect to the Exchange server with IE/Outlook Express (e.g., type ldap://ipnumber in IE's address bar) and query the server?  If not, it's probably not running LDAP or it's running it on a non-standard port.
0
 
kikkertmAuthor Commented:
LDAP is running on the exchange machine. When I open a browser and type in: ldap://exchangeserver
a 'find people' box pops up which as far as I know proves It's running.
The following vbscript actually works:

on error resume next

Dim ADOConn
Dim ADOCommand
Dim RS
Dim strPath
Dim mailboxname

if wscript.arguments.count < 2 then
     usage()
     wscript.quit
end if


if wscript.arguments(0) = "" or wscript.arguments(0) = "?" then
     Call Usage()
     wscript.quit
else
     Call DoQuery()
end if


Function DoQuery()
Set ADOConn = CreateObject("ADODB.Connection")
ADOConn.Provider = "ADSDSOObject"
ADOConn.Open "Active Directory Provider"

Set ADOCommand = CreateObject("ADODB.Command")

Set ADOCommand.ActiveConnection = ADOConn
ADOCommand.CommandText = "<LDAP://" & wscript.arguments(0) & ">;(cn=" & wscript.arguments(1) & ");adspath;subtree"

Set RS = ADOCommand.Execute

if rs.eof then
wscript.echo "No details found...."
end if

While Not RS.EOF
    wscript.echo RS.Fields(0)
    Set objUser = GetObject(RS.Fields("adspath"))
    wscript.echo "Firstname: " & objuser.get("givenName")
    wscript.echo "Surname: " & objuser.get("sn")
    wscript.echo "Title: " & objuser.get("title")
    wscript.echo "SMTP: " & objuser.get("mail")
    wscript.echo "Manager: " & objuser.get("manager")
    wscript.echo "PhoneNumber: " & objuser.get("telephoneNumber")
    wscript.echo "----------------------------------------------"
    RS.MoveNext
Wend

RS.Close
Set ADOConn = Nothing
Set ADOCommand = Nothing
Set RS = Nothing

End Function

Sub Usage()

wscript.echo "USAGE:"
wscript.echo "Getinfo.vbs " & chr(34) & "[Exchangeserver]" & chr(34) & " " & chr(34) & "[mailboxname]" & chr(34)

end sub


0
 
clockwatcherCommented:
The find people box will pop up regardless of whether or not you've actually got an LDAP server there or not-- regardless of whether there's even a machine there or not.  It doesn't actually try to connect to the server until you try to find someone.

It looks like you may be querying against a Windows 2000 Active Directory rather than Exchange.  What version of Exchange are you running?  On what version OS is it running?

In your example script, what does your first messagebox contain?  If it doesn't contain an O and OU containers, you're not running against an Exchange Server (or you're running against Exchange Server 2000 and it has a completely different tree/forest structure than 5.5-- which is possible but I wouldn't think too likely).  It's more likely that you're running the query against a W2K server's Active Directory.

Try this:

class Cout
  private buffer
  sub writeln(string)
     buffer = buffer & string & vbcrlf
  end sub
  sub flush
    wscript.echo buffer
    buffer = ""
  end sub
end class

Set ADOConn = CreateObject("ADODB.Connection")
ADOConn.Provider = "ADSDSOObject"
ADOConn.Open "Active Directory Provider"
set out = new Cout

exchange = "10.0.0.1"
set rs = adoconn.execute("<LDAP://" & exchange & ">;(cn=*);adspath;subtree")

wscript.echo(rs.fields(0))
on error resume next
do while not rs.eof
   Set objUser = GetObject(RS.Fields("adspath"))
   out.writeln "CN: " & objuser.get("cn")
   out.writeln "Firstname: " & objuser.get("givenName")
   out.writeln "Surname: " & objuser.get("sn")
   out.writeln "Title: " & objuser.get("title")
   out.writeln "SMTP: " & objuser.get("mail")
   out.writeln "Manager: " & objuser.get("manager")
   out.writeln "PhoneNumber: " & objuser.get("telephoneNumber")
   out.writeln "----------------------------------------------"
   out.flush
   rs.movenext
loop

rs.Close
Set ADOConn = Nothing
Set ADOCommand = Nothing
Set RS = Nothing
0
 
kikkertmAuthor Commented:
I ran yor script and it returns the following error (I replaced the exchange IP with our own of course) :

ADODB.Field: Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a    current record.

We are running Exchange 5.5 and I'm sure LDAP works and is accesible. As I said, the script I mentioned actually returns details (It takes 2 arguments; exchange server name and mailboxname) so that works and proofs LDAP is ok. What I need is a version of that script (or maybe something completely different) that allows me to just put in the Exchange server and will return a huge recordset with ALL users plus their details..

Thanks for your help sofar,
Regards,
Mike.
0
 
kikkertmAuthor Commented:
No more follow ups.. Planning to delete this question.
Please let me know if you have a problem with this..
0
 
clockwatcherCommented:
No problem.  

Sorry, I couldn't be of help.  The scripts I posted work fine on the three exchange servers to which I have access.  It's hard to troubleshoot since I can't reproduce the problem.
0
 
kikkertmAuthor Commented:
Clockwatcher, Thanks for your help !

Regards,
Mike
0
 
Tom KnowltonWeb developerCommented:
ADODB.Field: Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a    current record.


I am also getting this.


Did you have any luck figuring this out?

Been a few years so it is a longshot I know.  :)
0
 
clockwatcherCommented:
I managed to reproduce this a while back.

Exchange 5.5 (and maybe 2000) has a "maximum number of search results returned" value.  It's accessible for 5.5 via the Exchange Admin program under Site, Configuration, Protocols, LDAP, Search.  I think it defaults to 100.  If your query returns more than whatever that is set at, you get the EOF or BOF error message.

If you can't modify that value, you can modify the query so that it returns a smaller set of results.  I never bothered to look for a way to do any form of paging and don't know if it's possible.  I had the luxury of changing the value.

Here's a sample that cuts it down into smaller result sets.

class Cout
  private buffer
  sub writeln(string)
     buffer = buffer & string & vbcrlf
  end sub
  sub flush
    wscript.echo buffer
    buffer = ""
  end sub
end class

Set ADOConn = CreateObject("ADODB.Connection")
ADOConn.Provider = "ADSDSOObject"
ADOConn.Open "Active Directory Provider"
set out = new Cout

exchange = "10.0.0.1"

on error resume next

for letter = asc("a") to asc("z")

   set rs = adoconn.execute("<LDAP://" & exchange & ">;(cn=" & chr(letter) & "*);adspath;subtree")
   wscript.echo(rs.fields(0))
   do while not rs.eof
      Set objUser = GetObject(RS.Fields("adspath"))
      out.writeln "CN: " & objuser.get("cn")
      out.writeln "Firstname: " & objuser.get("givenName")
      out.writeln "Surname: " & objuser.get("sn")
      out.writeln "Title: " & objuser.get("title")
      out.writeln "SMTP: " & objuser.get("mail")
      out.writeln "Manager: " & objuser.get("manager")
      out.writeln "PhoneNumber: " & objuser.get("telephoneNumber")
      out.writeln "----------------------------------------------"
      out.flush
      rs.movenext
   loop

   rs.Close
next

on error goto 0

Set ADOConn = Nothing
Set ADOCommand = Nothing
Set RS = Nothing
0
 
Tom KnowltonWeb developerCommented:
There are only like 4 emails in the folder.  :(
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 8
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now