Solved

Finding Real names with user names using LDAP

Posted on 2002-07-25
27
293 Views
Last Modified: 2007-11-27
If I am using the following code to find the real name of my user, what is the rs.("FieldName") I should be using to find the user name.  eg.  Joe Bloggs - real name; jbloggs - username

The username is what is in the group category for the members  and I am trying to establish a way of getting the real names from the usernames......

HERE IS THE CODE:

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

ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user));distinguishedname,name,sAMAccountName;subTree"
cnt = 0
Set rs = ocommand.Execute
rs.MoveFirst
While Not rs.EOF
 'strtext = rs.Fields("sAMAccountName").Value & "   -   " & rs.Fields("Name").Value
 strtext = rs.Fields("Name").Value
 cboName.AddItem strtext
 cnt = cnt + 1
 strtext = ""
 rs.MoveNext
Wend
rs.Close

con.Close
0
Comment
Question by:Garfy
  • 13
  • 12
  • +1
27 Comments
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
sAMAccountName if for Pre-Windows 2000 (but usually if you run ADs with backward capability,then when you create users it automatically uses the same Win2K username, unless you change it.

In your search you need to include: userPrincipalName
This is the Win2K logon name.
The format usually comes back as MyUser@MyDomain.MySuffix



0
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
learning...
0
 
LVL 3

Expert Comment

by:Gunsen
Comment Utility
Searching for <userName> would be as follows :
ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user)(sAMAccountName='" & userName & "'));distinguishedname,name,sAMAccountName;subTree"
0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
Let's try another pice of code.  I need to get the proper names.  with the below code I am getting jsmith instead of John Smith, but I need John Smith.  Combo1 contains department names.....


Dim container As IADsContainer
Dim containername As String
containername = "ARCVDOMAIN" 'Combo1.Text
Set container = GetObject("WinNT://" & containername)

container.Filter = Array("User")
Dim user As IADsUser
For Each user In container
cboName.AddItem user.Name
Next
0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
userPrincipalName did not work...  thanks anyway
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility

Hi Garfy,

Are you sure userPrincipalName does not work? Thats very weird unless you are running a WinNT4 domain only?

ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user));distinguishedname,name,sAMAccountName,userPrincipalName;subTree"

Please paste the query code here, that way I can check your syntax.


As for retrieveing the full name:

user.FirstName & " " & user.get("initials") & " " & user.LastName

If you are using the iADsUser object.

0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
problem:  I am using a container so I can find out if a user belogns to a group....

the code is as follows:

On Error Resume Next
Dim strMonth As String
Dim strMonthNumber As String

cboName.Clear
Combo2.Clear
'frmpleasewait.Show
DoEvents

Dim container As IADsContainer
Dim containername As String
containername = "ARCVDOMAIN" 'Combo1.Text
Set container = GetObject("WinNT://" & containername)

container.Filter = Array("User")
Dim user As IADsUser
For Each user In container
cboName.AddItem user.Name
Next

container.Filter = Array("Group")
Dim group As IADsGroup
For Each group In container
If Left(group.Name, 3) = "GG_" Then
    Combo2.AddItem Right(group.Name, Len(group.Name) - 3)
End If
Next

Err = 0
DoEvents
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
Are you using the WinNT provider because the domain you are talking to is WinNT which is part of a Win2K forest?

Your code above won't tell you if a user belongs to a group. All you are doing in the above code is iterating the contents of a container for users and groups. It won't tell you membership of groups.

My assumption from all the above comments is that you want to bind to a user name and then from this user name get all the groups this user is a member of right?

So 1. Search for a user using (first name, user name)?
from this get user name and 2. Display grousp this user is a member of?

Below is simple code which will give you membership of groups for a user:


----------------------CODE Start

Option Explicit

Private Enum ADSI_Group_Type
    SecurityGroup_DomainLocal = -2147483644
    SecurityGroup_Global = -2147483646
    DistributionGroup_Global = 2
    DistributionGroup_DomainLocal = 4
    DistributionGroup_Universal = 8
    SecurityGroup_BuiltinLocal = -2147483643
End Enum

Private Sub Form_Load()

Dim oADsUser As IADsUser
Dim oADsGroup As IADsGroup
Dim varMemberOf As Variant
Dim varGroup As Variant

    On Error GoTo ErrHandler

    Set oADsUser = GetObject("LDAP://CN=testads,OU=CPSUsers,OU=CPSTNG,DC=RainDev,DC=Local")
   
    varMemberOf = oADsUser.GetEx("memberOf")
    If Not (IsEmpty(varMemberOf)) Then
       
        Debug.Print "Number of groups this user is a member of: " & (UBound(varMemberOf) + 1)
       
        For Each varGroup In varMemberOf
           
            '  varGroup is directory LDAP path so you can bind to group and display info
            Set oADsGroup = GetObject("LDAP://" & varGroup)
           
            With oADsGroup
           
                Debug.Print .Get("name")
                Select Case .Get("GroupType")
               
                    Case ADSI_Group_Type.DistributionGroup_DomainLocal
                        Debug.Print "DG Domain Local"
                    Case ADSI_Group_Type.DistributionGroup_Global
                        Debug.Print "DG global"
                    Case ADSI_Group_Type.DistributionGroup_Universal
                        Debug.Print "DG Universal"
                    Case ADSI_Group_Type.SecurityGroup_BuiltinLocal
                        Debug.Print "SG Builtin Local"
                    Case ADSI_Group_Type.SecurityGroup_DomainLocal
                        Debug.Print "SG Domain Local"
                    Case ADSI_Group_Type.SecurityGroup_Global
                        Debug.Print "SG Global"
               
                End Select
               
                Debug.Print .Description
           
               
            End With
           
            Set oADsGroup = Nothing
   
        Next varGroup
   
    End If

Exit Sub

ErrHandler:

    Select Case Err.Number
   
        Case -2147463155
            ' The Active Directory property cannot be found in the cache.
            ' This is not fatal, just means property was never set in cache.
            Err.Clear
            Resume Next
                   
        Case Else
            MsgBox "Unable to display this groups membership to other groups!" & vbCr & Err.Number & vbCr & Err.Description, vbCritical + vbOKOnly, "DisplayMemberOf Error"

    End Select
   
End Sub




----------------------Code end
Please let me know EXACTLY what you want and I can paste more code here for you.

0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
Okay,

What I have is form that is going to show a report.  The user of the form will have the ability to show the report based on a month, and then has the choice of viewing for all departments or only one of them (via a combo box).  When they choose a department there is another combo box that has the users in it that belong to that department, so that the report can be further refined.

All this info comes off our Active Directory Service.

The above code does work to a point.  I can get all of the above except that the users come in as their user name (eg. jsmith).  

This is the code that populates the user combo box

For Each user In container
'strUserName = user.FirstName & " " & user.LastName
strUserName = user.Name
'strUserName = user.OtherName
'strUserName = user.userprincipalname
cboName.AddItem strUserName
Next

Everything that is commented out gives me blanks, the user.name gives me the user name.

If you have any other way I can do this, I am all ears.

By the way this is in the Form_Load procedure.
0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
Oh and we have a Win 2K server but our network has win 95 and nt running on it.
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
By the way BIND to the ADs object using LDAP not WinNT provider. Try the code below.















Dim oCont As IADsContainer
Dim oADsUser As IADsUser
Dim bCacheRetError As Boolean
Dim strFullName As String

    On Error GoTo ErrHandler
   
    Set oCont = GetObject("LDAP://OU=ARCVDOMAIN,DC=yourDomain,Dc=domainsuffix")
    oCont.Filter = Array("user")
    For Each oADsUser In oCont
        strFullName = oADsUser.FirstName & " "
        strFullName = strFullName & oADsUser.LastName
        Debug.Print strFullName
        Debug.Print oADsUser.Get("userPrincipalName")
        If bCacheRetError = True Then
            ' If the userPrincipalName is not set, then assume this is WinNT or Win95
            ' account so get the SAM account name
            Debug.Print oADsUser.Get("sAMAccountName")
            bCacheRetError = False
        End If
       
    Next
   
Exit Sub

ErrHandler:

    Select Case Err.Number
   
        Case -2147463155
            'The Active Directory property cannot be found in the cache.
            ' This is not fatal, just means property was never set in cache.
            Err.Clear
            bCacheRetError = True
            Resume Next
           
        Case Else
       
            MsgBox "Error occured retrieveing users" & vbCr & Err.Number & vbCr & Err.Description, vbCritical + vbOKOnly
   
    End Select
0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
I have changed the above code to reflect my organisation but it still errors out

Dim oCont As IADsContainer
Dim oADsUser As IADsUser
Dim bCacheRetError As Boolean
Dim strFullName As String

   On Error GoTo ErrHandler
   
   Set oCont = GetObject("LDAP://OU=ARCVDOMAIN,dc=vic,dc=redcross,dc=org,dc=au")
   oCont.Filter = Array("user")
   For Each oADsUser In oCont
       strFullName = oADsUser.FirstName & " "
       strFullName = strFullName & oADsUser.LastName
       Debug.Print strFullName
       Debug.Print oADsUser.Get("userPrincipalName")
       If bCacheRetError = True Then
           ' If the userPrincipalName is not set, then assume this is WinNT or Win95
           ' account so get the SAM account name
           Debug.Print oADsUser.Get("sAMAccountName")
           bCacheRetError = False
       End If
       
   Next
   
Exit Sub

ErrHandler:

   Select Case Err.Number
   
       Case -2147463155
           'The Active Directory property cannot be found in the cache.
           ' This is not fatal, just means property was never set in cache.
           Err.Clear
           bCacheRetError = True
           Resume Next
           
       Case Else
       
           MsgBox "Error occured retrieving users" & vbCr & Err.Number & vbCr & Err.Description, vbCritical + vbOKOnly
   
   End Select






To get users for another form I use the following:

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

ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user));distinguishedname,name,sAMAccountName;subTree"




I am trying to find the users' real name...
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
Try the below code:

ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user));distinguishedname,name,sAMAccountName,firstname,initials,sn;subTree"



Where Firstname = Firstname, initials = Initials, sn = Surname


0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Author Comment

by:Garfy
Comment Utility
but how is this going to find out if the user is part of the particular group or not.....
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
If you want to find out if the user is part of a group then you will have to Bind to the Group and call the IsMember method of the group e.g,


bind to the user then get ADsPath or if you already know it then:


Dim oADsGroup As IADsGroup

   Set oADsGroup = GetObject("LDAP://CN=" & YourGroupName & ",DC=YourDomain,DC=YourDomainSuffix" )

   If oADsGroup.IsMember(ADsPathOfADsUser) = True Then
      Debug.Print "User is member"
   Else
      Debug.Print "User is NOT member"
   End If
0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
I can't find a way to get your code to work for me....

here is the code I use is in First lot of code.  Member.name gives me jsmith where I want the propername ie John Smith

Second lot of code is how I find the proper name for another combo box on the form.  however, first lot has the group as iadsgroup and second lot has user

*********************************************************
First Lot of Code
*********************************************************
Dim group As IADsGroup
Dim groupname As String
Dim groupdomain As String

groupname = "GG_" & Combo2.Text
groupdomain = "ARCVDOMAIN"
Set group = GetObject("WinNT://" & groupdomain & "/" & groupname & ",group")
cboName.AddItem "- All Users in Group -"
For Each member In group.Members
cboName.AddItem member.Name
Next
FindAllInCombo cboName, "- All Users in Group -"
Err = 0
DoEvents
*********************************************************

*********************************************************
Second Lot of code
*********************************************************

Dim container As IADsContainer
Dim containername As String
containername = "ARCVDOMAIN" 'Combo1.Text
Set container = GetObject("WinNT://" & containername)

container.Filter = Array("User")
Dim user As IADsUser
For Each user In container
'strUserName = user.FirstName & " " & user.LastName
strUserName = user.Name
'strUserName = user.OtherName
'strUserName = user.userprincipalname
cboName.AddItem strUserName
Next
*********************************************************

Can we try again????
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
You have a windows 2000 server right?
If so then use the LDAP protocol, because the WinNT provider won't return certain properties of iADS interfaces, so simply change the GetObject bind to :-

Set container = GetObject("LDAP://CN=" & containername & ",DC=Microsoft,DC=COM")

0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
I keep looking at all the code you give me, and I think I am getting there, however, from what I can make out, it is lookign at whether the user is member of the server group not the grouping structure that is on server, eg.  ARCV is the server,  GG_IT is one of the groups, GG_EMERGSERV is another group.....  GG_IT has myself and several others in it and GG_EMERGSERV has other users in it, but we are all users on the system....

I am trying to work out the actual code I would need to use.
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
Slightly confused about what you want? You want code to tell you if you are part of the domain users group right?

This default membership is not displayed when you iterate the group membership properties. You have to write code to build the users RID and from that extract the SID of the users primary group. If this (You want users Primary Group) is what you want please say so then I can paste example here.

Or do you want to iterate all groups within the domain and display all members of each of the groups?

Also you must use the LDAP provider with my code. The WinNT provider does not expose all iADs interfaces which are as useful in this instance of what you are trying to achieve with ADs.




0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
what I want to be able to do is be able to get a group name and find all the members by their real names...  

users will belong to several groups at once....
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
Does not make sense what you want, maybe I am not understanding you properly.

So you want to find all groups on the domain first, then for each group you want to show all members of that group and display their real names.

Then for each member you want to display the groups of which this user is a member:-

ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user)(firstName=" & strFirstName & ")(initials=" & strInitials & ")(sn=" & strSurname & "));memberOf;subTree"

OR if you cannot break up the user name, then you could use DisplayName, BUT this is not the same as first name, initials and last name. You can change the display name to something else (See user properties in ADs Users and Computers).

ocommand.CommandText = "<LDAP://OU=ARCV,dc=vic,dc=redcross,dc=org,dc=au>;(&(objectCategory=person)(objectClass=user)(DisplayName=" & strFullName & "));memberOf;subTree"


0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
The first part is right

"So you want to find all groups on the domain first, then for each group you want to show all members of that group and display their real names."

I can find all the groups on the domain, and I can find their usernames.  How can this lead me to their real names???  I have another combo box which does display all the real names of people on the domain, but it does not divide them into their groups.  So I understand how to do that....  When it comes to finding real names of people in a group...  that is where my problem is...
0
 
LVL 5

Accepted Solution

by:
RainUK earned 200 total points
Comment Utility
Okay try this:

' First Bind to the group

Dim oIADsGroup As IADsGroup
Dim oIADsUser As IADsUser
Dim strGroupName As String
Dim strRealName As String

   On Error Goto ErrHandler

   strGroupName = "YourGroupName"

   Set oIADsGroup = GetObject("LDAP://CN=" & strGroupName & ",dc=vic,dc=redcross,dc=org,dc=au")

   For Each oIADsUser in oIADsGroup.Members
       strRealName = ""
       strRealName = oIADsUser.Get("FirstName")
       strRealName = strRealName & " " & oIADsUser.Get("Initials")
       strRealName = strRealName & " " & oIADsUser.Get("sn")
       Debug.Print strRealName
   Next oIADsUser

   

Exit Sub

ErrHandler:

    Select Case Err.Number
     
       Case -2147463155
           ' This is not a critical error, it just means the property you tried to retrieve is not in the property cache, basically the part of the user name was never input
           Resume Next

       Case Else

          MsgBox Err.Number & vbcr & Err.Description

    End Select

End Sub
0
 
LVL 1

Author Comment

by:Garfy
Comment Utility
I am going to give you the points, but I still can't get it to work.  I tried the above and all it brought back was blanks.    I am going to have to try something like querying within a for loop.....

Thanks anyway
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
okay does it actually go to the Error handler statemenmt with regards to the property not being in the cache?
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
and you are definitely using the LDAP provider ?
0
 
LVL 5

Expert Comment

by:RainUK
Comment Utility
please also paste me the code here that you use if it is possible
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

728 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now