Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Get simple phone list from AD using GC

Status
Not open for further replies.

mat41

Programmer
Mar 7, 2004
91
AU
I have been reading the following thread:

thread774-356151

Wow zcolton you are the most helpful person I have ever encounted in any forum. I have been strugling to get a list of users and phone numbers. The following code works to get 'a users details' however I would like to get the full list.

Why can I not change the following line:

Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname='"+strUsername+"'"

To:
Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"'"

To acieve my objective? Thank you in advance...this one had me very stuck

<%
fsCompletted = Request.QueryString("f")

If fsCompletted = 1 Then
ResultHTML = ProcessForm
else
ResultHTML = "<br>"
End If

Function ProcessForm
on error resume next
oUsername=Request.Form("username")
oPassword=Request.Form("password")
strUserName = Right(oUsername, Len(oUsername) - InStrRev(oUsername, "\"))
if InStr(strUserName, "@")>0 then
strUserName = Left(strUserName, InStr(strUserName, "@")-1)
end if
Set objDomain = GetObject("GC://rootDSE")
objADsPath = objDomain.Get("defaultNamingContext")
Set objDomain = Nothing
Set con = Server.CreateObject("ADODB.Connection")
con.provider ="ADsDSOObject"
con.Properties("User ID") = oUsername
con.Properties("Password") = oPassword
con.Properties("Encrypt Password") = False
con.open "Active Directory Provider"
Set Com = CreateObject("ADODB.Command")
Set Com.ActiveConnection = con
Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname='"+strUsername+"'"
Set rs = Com.Execute
if err.number=0 then
HTML = "<p>"+rs("name")+"<br>"+rs("telephonenumber")+"<br>"+rs("mail")+"</p>"
else
HTML = "<p>Not Authenticated</p>"
end if
rs.Close
con.Close
Set rs = Nothing
Set con = Nothing
ProcessForm=HTML
End Function
PostURL = Request.ServerVariables("SCRIPT_NAME") & "?f=1" %>
<HTML>
<HEAD>
</HEAD>
<BODY>
<%=ResultHTML%>
<%if request.querystring("f")="" then %>
<form method="post" Action="<%=PostURL%>">
<p>Username : <input type="text" Name="username" value="" Size="25">(yourDomain/username)</p>
<p>Password : <input type="password" Name="password" Size="25"></p>
<input Name=SubmitButton Value="Authenticate User" Type=submit>
</form>
<%end if%>
</BODY>
</HTML>
 
I have been given this as a path:

ou=users,ou=frame,ou=e8group,dc=e8group,dc=net;

That is the LDAP? I have learnt the difference between LDAP and GC from zcolton's wealth of information however am getting alot of 'table does not exist errors'

Very much looking forward to and appreciate any assistance

TYIA
 
Try this instead:

Code:
Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname like'"+*+"'"

I would highly suggest you visit the vbscript forum here.

The LDAP query you need to use to get what you want needs to retrieve the values from objects that have ANY value in sAMAccountName.

Here is something that should work for you:

Code:
' '*******************************************************************
' * This script will lookup user information                       '*
' * Script Author: djtech2k  Created May 2006                       '*
' '*******************************************************************

Option Explicit

Dim objRootDSE, strDNSDomain, objCommand, objConnection 
Dim objRecordSet, strAlias, strName, strSAM
Dim strQuery, strBase, strFilter, strAttributes
Dim strPhone, strEmail, strDisplayName, strMail

' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection

' Search for all user objects. Return Values.
' Sort recordset by DisplayName.
strBase = "<LDAP://" & strDNSDomain & ">"
strFilter = "(&(objectCategory=person)(objectClass=user))"
strAttributes = "displayName,mailNickname,sAMAccountName,telephoneNumber,mail,name"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False
objCommand.Properties("Sort On") = "displayName"
Set objRecordSet = objCommand.Execute
  
    Do Until objRecordSet.EOF
  strDisplayName = objRecordSet.Fields("displayName")
  strAlias = objRecordSet.Fields("mailNickname")
  strSAM = objRecordSet.Fields("sAMAccountName")
  strPhone = objRecordSet.Fields("telephoneNumber")
  strName = objRecordSet.Fields("name")
  strEmail = objRecordSet.Fields("mail")
  Wscript.Echo "UserName: " & strSAM & vbcrlf & "Display Name: " & strDisplayName & vbcrlf & "Name: " & strName &_
  vbcrlf & "Email: " & strMail & vbcrlf & "Alias: " & strAlias & vbcrlf & "Phone: " & strPhone
  	
    objRecordSet.MoveNext
	Loop

objConnection.Close
 
Thank you for your post. This objective has not got any closer of late.

I replaced my query in the original post with your suggestion:

Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname like'"+*+"'"

The * looked like and is a syntax error. I tryed:
like '*' "
Which I believe to be correct SQL

The syntax error goes away however authentication fails. Please note, the code I posted is cut n paste, works for 'a users details' requiring no alterations.

The 'lookup user information' you kindly posted gives me a server 500 error type (0x8007054B) on line 15. The syntax on this line is:

Set objRootDSE = GetObject("LDAP://RootDSE")

Do I need to make alteations to your code to get it working? Forgive my newbieness to this GC/LDAP thing. The path to the AD tables and IP address of the AD server, should this go somewhere? I have been playing with:

SELECT displayName FROM 'LDAP://10.61.20.21/ou=users,ou=frame,ou=e8group,dc=e8group,dc=net' WHERE objectClass='*'"

I am so stuck on this one, further assistance would be very much appreciated. I would be stoked to get a simple phone list. the network guys here reckon the following information is all the local information needed:

'LDAP://10.61.20.21/ou=users,ou=frame,ou=e8group,dc=e8group,dc=net'

TYIA
 
Ok, do you have to use a GC or can you just do an LDAP lookup? My script is modular and should work in any AD environment. You should not need to adjust anything.

To make this a GC lookup instead of a regular LDAP lookup, change this line:

Code:
Set objRootDSE = GetObject("LDAP://RootDSE")

to this:

Code:
Set objRootDSE = GetObject("GC://RootDSE")

or

Set objRootDSE = GetObject("GC://SERVERNAME")

In the last example, you would replace SERVERNAME with your GC server name. I would try them in the order I posted though. The first is more modular and should not require changes.
 
Thank you again for your time.

;;;do you have to use a GC or can you just do an LDAP lookup?
I would prefer to use LDAP. For what reason Im not sure, this was the look up I was told to create. To be honest, anything that works will do but LDAP would be prefered.

;;;My script is modular and should work in any AD environment
mmmm, thats odd. I am testing from inside the network on a trusted part of the domain. Since the script I posted works I would say there is no network issue. This script is also 'modular' and requires no change to get a users details. Does it work in your environment?

Detailed behavior of your code (Created May 2006):

1..Cut, paste and run - Error Type (0x8007054B) on line 16. Line 16 contains:
Set objRootDSE = GetObject("LDAP://RootDSE")

2..As suggested change (which happens to be line 16 also):
Set objRootDSE = GetObject("LDAP://RootDSE")
To:
Set objRootDSE = GetObject("GC://RootDSE")
Result:
Error Table does not exist line 39.
Line 39 is (problem with the query it seems):
Set objRecordSet = objCommand.Execute

3..As suggested change (which happens to be line 16):
Set objRootDSE = GetObject("LDAP://RootDSE")
To:
Set objRootDSE = GetObject("GC://SERVERNAME")
Result:
500 server Error Type: (0x80072020) NOTE: No line specified, a nasty ambiguoes erorr...

mmmmm, a little frustrating. This path I have been given:
ou=users,ou=frame,ou=e8group,dc=e8group,dc=net'
Should this be in the code somewhere? it is the path to where the users information is?

Still stuck however appreciating the assistance, any other ideas?

 
Ok. My script runs in 4 different environments just fine and I have given it to dozens of people and it worked. Lets try to diagnose it..

Try this code and report the output:

Code:
Option Explicit

Dim objRootDSE, strDNSDomain, objCommand, objConnection
Dim objRecordSet, strAlias, strName, strSAM
Dim strQuery, strBase, strFilter, strAttributes
Dim strPhone, strEmail, strDisplayName, strMail

' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

wscript.echo strDNSDomain

Here is another question...

Are you running this code from a machine that is a member of the domain? Does your logged-in user have admin permissions or permissions to read the entire directory? Some of the errors that you have posted many times point to a permissions problem which prevents the code from working. If you look at your original code and how iot attaches to the directory, then compare it to mine, its almost identical.

One other thing that I just noticed that may answer this issue...are you running my code in an ASP page? If so it will not work. My code is meant to be run from a command prompt as a vbscript...ie "cscript c:\myscript.vbs". My code is a test for the functionality that you want...it can then be adapted for the web.
 
Thank you for your prompt reply.

> Yes I am a member of the domain
> My account is not an admin acount
> Yes I am running in a classic ASP page (mmmm, now I feel a bit silly 'wscript.echo' did look foreign to me)

FYI: I can get logged on as a admin type acount

As a result of me running this in an ASP page your domain detection code above error's however the folowing code returns 'DC=E8Group,DC=Net'

-----------------code start----------------------
<%@ Language=VBScript %>
<%
Option Explicit
Dim objADsPath,objDomain
%>
<html>
<head>
</head>
<body>
<%
Set objDomain = GetObject ("GC://RootDSE")
objADsPath = objDomain.Get("defaultNamingContext")
Set objDomain = Nothing
Response.Write objADsPath & "<BR>"
%>
</body>
</html>
-----------------code fnish----------------------

I have been told my account does have the ability to see all user info from AD.

Thank you for your time
 
Well if is running on an ASP page then it depends on the type of authentication you are using. If you are using integrated with impersonation, then it will pass on your logged in use creds. If not, it is running as permissions of a service account in IIS or even worse, anonymous access.


As for the code, I think using my code in your asp is part of the problem or related to it.

As for your code, the whole key to an LDAP query or search string is the format. Yours is using a SQL type query and it will work, BUT it has to limit the search to user accounts only. Try the following in your original code:

Change this line to:

Code:
Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname='"+strUsername+"'"

to this:

Code:
Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where objectClass='"user"'"

In this line, you are telling it to limit the search to usrr accounts ONLY. I do not know classic ASP formatting, so mine may be off. Basically, you want to tell it to search for items with "objectClass=user". The "user" is a real value, not a variable.

If that does not work, you can do a straight LDAP query instead.

For kicks, get rid of the old:

Code:
Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname='"+strUsername+"'"

And put this in its place:

Code:
Com.CommandText = "<GC://"+objADsPath+">;(&(objectCategory=person)(objectClass=user));displayName,mailNickname,sAMAccountName,telephoneNumber,mail,name;subtree"

Again, if the syntax with quotes and such are bad for ASP, fix them. I think either of these last 2 changes should work for you.



 
Additionaly, If I run the above code using:

Set objDomain = GetObject ("LDAP://RootDSE")

I get a server 500 Error Type: (0x8007054B) on that line

TYIA
 
using:

Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where objectClass='"+user+"'"

Nothing seems to get rendered to the browser however no errors (NOTE I changed "user" to "+user+")

Then using:

Com.CommandText = "<GC://"+objADsPath+">;(&(objectCategory=person)(objectClass=user));displayName,mailNickname,sAMAccountName,telephoneNumber,mail,name;subtree"

I have the same behavior, nothing rendered to the browser. I guess no erros is a good sign. I will place some conditions in there to look closer at the record set and identify if its empty or not.

I feel like I am closer and appreciate your help
 
You are welcome.

It looks like the first should work, but I never write my code that way. I write everything the last way. In that case, just remember that the key is to get your command correct. Read my script code and see how the LDAP search string comes together and apply it to your code. The major differences being that your syntax is for ASP and that you are using the the GC (even though the LDAP attachment should work to get some data to display).


 
GC and LDAP are spinning through my head. I am determined to get this working and will work on using:

Com.CommandText = "<GC://"+objADsPath+">;(&(objectCategory=person)(objectClass=user));displayName,mailNickname,sAMAccountName,telephoneNumber,mail,name;subtree"

type of command as you suggest. Best I investigate the record set to find out why I have a blank browser. My ASP is of very different standard to my, shall we say 'binding to AD' - I will be sure to post my progress for others who may benefit from this post - and indeed post any LDAP/GC related issues which arise in the process
 
djtech2k - Thanking you for your help. The following code works a treat. You have a fine day mate...

--------------cut n past code----------------------

<%
fsCompletted = Request.QueryString("f")

If fsCompletted = 1 Then
ResultHTML = ProcessForm
else
ResultHTML = "<br>"
End If

Function ProcessForm
on error resume next
'oUsername=Request.Form("username")
'oPassword=Request.Form("password")
strUserName = Right(oUsername, Len(oUsername) - InStrRev(oUsername, "\"))
if InStr(strUserName, "@")>0 then
strUserName = Left(strUserName, InStr(strUserName, "@")-1)
end if
Set objDomain = GetObject("GC://rootDSE")
objADsPath = objDomain.Get("defaultNamingContext")
Set objDomain = Nothing
Set con = Server.CreateObject("ADODB.Connection")
con.provider ="ADsDSOObject"
con.Properties("User ID") = oUsername
con.Properties("Password") = oPassword
con.Properties("Encrypt Password") = False
con.open "Active Directory Provider"
Set Com = CreateObject("ADODB.Command")
Set Com.ActiveConnection = con
'works for a user
'Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname='"+strUsername+"'"
'fails wip:
'Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where objectClass='"+user+"'"
'fails wip:
'Com.CommandText ="select name,telephonenumber,mail FROM 'GC://"+objADsPath+"' where sAMAccountname LIKE '*'"
'gets all users :eek:)
Com.CommandText = "<GC://"+objADsPath+">;(&(objectCategory=person)(objectClass=user));displayName,mailNickname,sAMAccountName,telephoneNumber,mail,name;subtree"
Set rs = Com.Execute %>
<HTML>
<HEAD>
</HEAD>
<BODY>
<% if not rs.eof then %>
<table>
<tr>
<td>Display Name</td>
<td>Phone</td>
</tr>
<% do until rs.eof %>
<tr>
<td><%= rs(1) %></td>
<td><%= rs(3) %></td>
</tR>
<% rs.moveNext
loop %>
</table>
<% end if
rs.Close
con.Close
Set rs = Nothing
Set con = Nothing
ProcessForm=HTML
End Function
PostURL = Request.ServerVariables("SCRIPT_NAME") & "?f=1" %>
<%=ResultHTML%>
<%if request.querystring("f")="" then %>
<form method="post" Action="<%=PostURL%>">
<p>Username : <input type="text" Name="username" value="" Size="25">(yourDomain\username)</p>
<p>Password : <input type="password" Name="password" Size="25"></p>
<input Name=SubmitButton Value="Authenticate User" Type=submit>
</form>
<%end if%>
</BODY>
</HTML>



-----------------finish----------------------------
 
Glad I could help. I have never written any ASP to connect to AD, although I have written a few things in ASP.Net to admin functions in AD.

Good Luck!
 
does anyone know how I can generate a list of all user accounts (not terminated or expired accounts) in specific OUs? If someone could give me the basics, I can change the script so that it reflects the correct OU...

Many thanks!
Brandon
 
Something like this should work:

Code:
set objParent = GetObject("LDAP://OU=Users,DC=domain,DC=local")
objParent.Filter = Array("user")
for each objUser in objParent
wscript.echo "Username = " & objUser.sAMAccountName &_
vbcrlf & "DisplayName = " & objUser.displayName & vbcrlf
next

If you use that, you can change the OU to search by entering the correct DN of that OU.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top