Solved

Setting Criteria on an Active Directory search from SQL Server

Posted on 2004-10-06
10
771 Views
Last Modified: 2008-01-09
I've linked my Active Directory to SQL Server as a linked server and I've managed to run queries on the directory.

I can run a query to return all users in the directory, e.g. :

SELECT     *
FROM         OPENQUERY(ADSI,
                         '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person));name, mail, sAMAccountName, userPrincipalName, title, department')

And I wanted to place this into a view or a stored procedure which our ASP web developers can call from their web pages.  However, whenever I try to limit the recordset to only one user by setting a WHERE clause in the statement I get no results returned even though I know the user name I've used is valid, e.g. :

SELECT     *
FROM         OPENQUERY(ADSI,
                         '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person));name, mail, sAMAccountName, userPrincipalName, title, department')
WHERE sAMAccountName = 'donait'

I've tried this from both an ASP page and from within SQL Query Analyzer itself, but I get no rows returned.  If I place the criteria within the LDAP syntax itself, then I do get the user's details returned but I can't use this method because I need to place the value of a passed parameter as the sAMAccountName, e.g.:

SELECT     *
FROM         OPENQUERY(ADSI,
                         '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)(sAMAccountName=donait));name, mail, sAMAccountName, userPrincipalName, title, department')

Does anyone know where I'm going wrong, or can you suggest a different way to achieve a solution?
0
Comment
Question by:ian_r
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
10 Comments
 
LVL 34

Expert Comment

by:arbert
ID: 12240683
If you're using ASP, build the connection string in VBS and then pass that:

Dim sSQL
Dim sAccountName
sAccountName="donait"

sSql="SELECT     *
FROM         OPENQUERY(ADSI,
                        '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)"
sSql=sSql & "(sAMAccountName=" & sAccountName
sSql=sSql & "));name, mail, sAMAccountName, userPrincipalName, title, department')"

set rs=connection.execute(sSql)

0
 
LVL 34

Expert Comment

by:arbert
ID: 12240693
Ooops, it wrapped, but you get the idea:

sSql="SELECT     * FROM         OPENQUERY(ADSI, '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)"
sSql=sSql & "(sAMAccountName=" & sAccountName
sSql=sSql & "));name, mail, sAMAccountName, userPrincipalName, title, department')"
0
 
LVL 6

Expert Comment

by:mcp111
ID: 12240758
probably you need to specify domainname\username
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!

 

Author Comment

by:ian_r
ID: 12241253
You can run the query directly from the ASP page but I didn't want to do this because it's slower than running it from within a stored procedure and will have a higher impact on the network bandwidth.  Also, it would be easier to place this functionality within one stored procedure so I can nest it within others and allow more than one ASP application access to the same procedure without having to cut 'n paste code.

What I'm trying should be possible according to:

I don't think I need to specify the domain name with the username because the domain is part of the LDAP string, and the query works fine if I put the username in next to the "objectCategory=Person" rather than use a WHERE clause  (see original post).

I'm really keen to get this working, any suggestions?
0
 
LVL 34

Expert Comment

by:arbert
ID: 12241303
Have you tried changing the = on the outside to a like to see if there are spaces?

SELECT     *
FROM         OPENQUERY(ADSI,
                        '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person));name, mail, sAMAccountName, userPrincipalName, title, department')
WHERE sAMAccountName like 'donait%'

You could also use Dynam sql in the stored proc (as a last resort) to put the where on the inside of the linked server.  It's actually better there anyway because you KNOW the criteria is applied at AD and not at SQL Server...
0
 

Author Comment

by:ian_r
ID: 12241583
Thanks for the comments arbert, I'll try the 'like' when I'm back at work tomorrow.

How do I use dynamic sql within the stored proc?  I've tried inserting an input parameter within the string but I get a syntaxt error, e.g. :

SELECT     *
FROM         OPENQUERY(ADSI,
                        '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)(sAMAccountName=' + @username + '));name, mail, sAMAccountName, userPrincipalName, title, department')

Is that what you mean, or have I got the wrong end of the stick?

The links I missed of the previous post were:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/creating_a_heterogeneous_join_between_sql_server_and_active_directory.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/creating_a_heterogeneous_join_between_sql_server_and_active_directory.asp

0
 
LVL 34

Accepted Solution

by:
arbert earned 250 total points
ID: 12241687
Close, you have to generate the string and then use EXEC(yourstring) to run.

Haven't tested, but something like this:

declare @sql varchar(2000)

select @sql='SELECT     * FROM         OPENQUERY(ADSI, ' + char(39) + '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)(sAMAccountName=' + @username + '));name, mail, sAMAccountName, userPrincipalName, title, department' + char(39) + ')'

exec(@sql)
0
 

Author Comment

by:ian_r
ID: 12241737
Cheers arbert, that looks great.  I'll try it tomorrow and tell you how I go on.
0
 

Author Comment

by:ian_r
ID: 12246455
arbert,

Your last suggestion worked just as you suggested, without me needing to change any of your syntax - who needs testing eh?

Thanks again, I was working on this all day and I'm new to stored procedures, so I was getting pretty frustrated :-).
0
 
LVL 34

Expert Comment

by:arbert
ID: 12251331
Good deal.  I wouldn't say that dynamic SQL is ideal, but sometimes there really isn't a way around it.  With openquery, if you can pass the criteria on the "inside" you will usually get MUCH better performance than applying it on the outside.

Glad it all worked.

Brett
0

Featured Post

Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

JSON is being used more and more, besides XML, and you surely wanted to parse the data out into SQL instead of doing it in some Javascript. The below function in SQL Server can do the job for you, returning a quick table with the parsed data.
Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question