?
Solved

Using ActiveDirectory to return a list of all users in a given group

Posted on 2004-11-17
36
Medium Priority
?
1,086 Views
Last Modified: 2011-10-03
Hi,

I've seen many solutions to this but none actually work for me. All I want is a nice simple function as trying to get my head around the namespace is beginning to wear me down!

Using VB.NET (not C#), I want a function that will accept a string for the group name, and a string for the server. I then want it to connect, and output the list of users in that group as a string (or whatever).

Can anyone help?

Thanks.
0
Comment
Question by:OnError_Fix
  • 18
  • 16
  • +1
36 Comments
 
LVL 27

Expert Comment

by:planocz
ID: 12606250
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12608820
Use Directory Services API under System.DirectoryServices namespace is the proper way to access information stored in AD. The basic idea is that each group object in active directory has "member" attribute which stores the list of users that belong to the group.

Given a group name, you can query to AD using DirectorySearcher class to get the group object as follows

    Private m_LdapPath As String = "LDAP://SERVER_NAME/..."
    Private m_AdminAccountName As String = "Domain\UserName"
    Private m_AdminPassword As String = "password"

    Public Function GetUserRoles(ByVal groupName As String) As String()

        Dim filter As String = String.Format("(&(objectCategory=group)(cn={0}))", groupName)
        Dim entry As New DirectoryEntry(m_LdapPath, m_AdminAccountName, m_AdminPassword, AuthenticationTypes.None)
        Dim searcher As New DirectorySearcher(entry, filter)
        Dim users As New ArrayList

        Try

            Dim result As SearchResult = searcher.FindOne()
            Dim member As Object = result.Properties("member")
            If IsNothing(member) Then
                For Each dn As String In CType(member, IEnumerable)
                    users.Add(dn)
                Next
                ' returns string array of users
                Return CType(users.ToArray(GetType(String)), String())
            End If

            ' returns empty string array
            Return New String() {}

        Catch
            Throw
        Finally
            If Not IsNothing(entry) Then
                entry.Dispose()
            End If
            If Not IsNothing(searcher) Then
                searcher.Dispose()
            End If
        End Try

    End Function

For you to read:
connection string format for ldap provider
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/ldap_adspath.asp

Notes: the code listed above uses AdminAccountName and AdminPassword password. You can however ignore the two parameters and pass as null (or empty string) value instead and the current logon user credentials will be used by .NET Framework to do the job. For any user account used make sure it has proper permission rights to query and view group information in Active Directory server.
0
 

Author Comment

by:OnError_Fix
ID: 12612713
Hi iHenry,

Thanks for your post. This appears to be the closest I have come to getting what I need. That said however, when I run the code, I get an error message:

LabelSystem.Runtime.InteropServices.COMException (0x80072020): An operations error occurred at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.get_AdsObject() at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne) at System.DirectoryServices.DirectorySearcher.FindOne() at Incorpex.Olympia2004V1.ActiveDirectory.GetUserRoles(String groupName) in C:\Documents and Settings\r.parker\VSWebCache\intranet.domain.net\administration\ActiveDirectory.vb:line 23,

Now --- ActiveDirectory.vb line 23 reads:

Dim result As SearchResult = searcher.FindOne()

And here are the values of the following strings:

Dim m_LdapPath As String = "LDAP://DEV"
Dim m_AdminAccountName As String = ""
Dim m_AdminPassword As String = ""

I have also tried "LDAP://DEV.LOCAL/CN=Users" as well, to produce the same error.

Any ideas?

Thanks.

P.S. Points value increased to 200.


0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:OnError_Fix
ID: 12612824
Hi,

I found this code on the web, but alas - it's all in C#. Would this code work if it were converted to VB.NET?

using System;
using System.DirectoryServices;
using System.Runtime.InteropServices;
using System.Reflection;
using activeds; // Import activeds.tlb (%windir%\system32\activeds.tlb)
class Test {
static string bindUser = "administrator"; // binding user with sufficient privileges
static string bindPwd = "hispwd"; // password of the binding user
static void ListUserAndGroups(string machineName)
{
DirectoryEntry _compContainer = new DirectoryEntry("WinNT://" + machineName + ",computer", bindUser, bindPwd);
try
{
foreach(DirectoryEntry de in _compContainer.Children)
{
switch (de.SchemaClassName.ToLower())
{
case "group":
Console.WriteLine("---------- group - {0} ---------", de.Name);
ListMembersInGroup(de.Path);
break;
case "user":
Console.WriteLine("---------- user - {0} ---------", de.Name);
ListUserProp(de.Path);
break;
default:
break;
}
}
}
finally {
_compContainer.Dispose();
}
}

private static void ListMembersInGroup(string dirPath) {
IADsMembers MembersCollection = null;
DirectoryEntry _groupEntry = new DirectoryEntry(dirPath ,bindUser, bindPwd);
try {
// call native method "members" on the IADsGroup COM interface exposed by activeds.dll
IADsGroup gr = _groupEntry.NativeObject as IADsGroup;
MembersCollection = gr.Members();
// or call Invoke on the DirectoryEntry object passing the Method to call as arg.
// cast the retruned object to IADsMembers
// MembersCollection = _groupEntry.Invoke("Members") as IADsMembers;
object[] filter = {"user"};
MembersCollection.Filter = filter;
// enumerate members of collection object that supports the IADsMembers interface
// ADSI provider doesn't support count property!!
try {
foreach (IADsUser member in MembersCollection) {
Console.WriteLine("[{0}]", member.Name);
ListUserProp(member.ADsPath);
}
}
catch (COMException e) {
Console.WriteLine("Error: {0}",e.Message);
}
}
catch (COMException e) {
Console.WriteLine(e.Message);
}
finally {
_groupEntry.Dispose();
}
}
private static void ListUserProp(string dirPath) {
DirectoryEntry userEntry = null;
try {
userEntry = new DirectoryEntry(dirPath,bindUser, bindPwd);
PropertyCollection pcoll = userEntry.Properties;
foreach(string sc in pcoll.PropertyNames)
Console.WriteLine("\t" + sc + "\t" + pcoll[sc].Value);
}
catch (COMException e) {
Console.WriteLine(e.Message);
}
finally
{
userEntry.Dispose();
}
}

public static void Main() {
ListUserAndGroups("scenic");
}
}
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12613049
>> I have also tried "LDAP://DEV.LOCAL/CN=Users" as well, to produce the same error.
Hm..are you sure the path is correct? do you really have an OU directly under you rootDSE?
0
 

Author Comment

by:OnError_Fix
ID: 12613079
I may have this bit wrong then.... I've tried several combinations. It's basically the standard setup straight "out-of-the-box". I seem to be getting confused constructing the LDAP:// string, if that is where the error is?

What would you suggest I try to retrieve (for example) just the users in the Domain Admins group?

Server name: DEV.DOMAIN.LOCAL (dns)

Thanks
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12613468
Default AD instalation will have this kind of ldap path,

LDAP://<SERVER_NAME>:389/CN=Users,DC=<DOMAIN_NAME>,DC=local

Or you can ignore the SERVER_NAME if you want to do server-less binding. That a common case when web server is part of the AD domain. And port number defaults to 389 (you can ignore this as well).

And user account on which the code is running also determine whether you need to supply user name and password. Are you using ASP.NET or just a console application?
0
 

Author Comment

by:OnError_Fix
ID: 12613849
ASP.NET using Windows Forms Authentication.
(Integrated Logon is not enabled).
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12613969
First, lets do some checking whether you can bind to AD in the first place. Run the code by commenting out line 3 and 4.
Then do the same thing with line 3 and 4.

Dim de As New DirectoryEntry()    ' ln 1
de.Path = ldapPath                      ' ln 2
de.User = userName                   ' ln 3
de.Password = password             ' ln 4
de.AuthenticationType = AuthenticationTypes.None  ' ln 5
de.RefreshCache()                      ' ln 6

Do some combination of AuthenticationTypes enum, use ServerBind if SERVER_NAME is specified in ldapPath. Then, post your ldap path and any error message occurs.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12614014
To make thing clearer, when using FormsAuthentication normally anonymous access in IIS is enabled and the app is running under IUSR_MACHINE security context. When enable anonymous access, the app is running under login user security context. So whatever user account used to bind to AD, it must be a domain user and has proper permission rights to view information in AD.
0
 

Author Comment

by:OnError_Fix
ID: 12614646
Hi IHenry:

When using a blank username and password, with the LDAP string "" I get:

System.Runtime.InteropServices.COMException (0x80072020): An operations error occurred at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.RefreshCache() at Incorpex.Olympia2004V1.ActiveDirectory.DebugAD() in C:\Documents and Settings\r.parker\VSWebCache\intranet.domain.net\administration\ActiveDirectory.vb:line 25

When using the username and password of a local administrator account on the server (with the SAME LDAP string), I get:

System.Runtime.InteropServices.COMException (0x8007202B): A referral was returned from the server at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.RefreshCache() at Incorpex.Olympia2004V1.ActiveDirectory.DebugAD() in C:\Documents and Settings\r.parker\VSWebCache\intranet.domain.net\administration\ActiveDirectory.vb:line 25

NOTE: Line 25 is equal to Line 6 of the code you sent, that is: de.RefreshCache().

Back to the drawing board?!!!

Note: points increased to 300.
0
 

Author Comment

by:OnError_Fix
ID: 12614656
Of course it would help if I actually posted the LDAP String :)

It is:

"LDAP://DEV:389/CN=Users,DC=INCORPEX.LOCAL,DC=local"

;)
0
 

Author Comment

by:OnError_Fix
ID: 12614667
Hi iHenry:

Success?!

The following code DOES NOT produce any error:

 Dim ldapPath As String = "LDAP://DEV/CN=Users,DC=xxxx,DC=local"
            Dim username As String = "xxxxx"
            Dim password As String = "xxxxx"

            Dim de As New DirectoryEntry        ' ln 1

            de.Path = ldapPath                  ' ln 2
            de.Username = username              ' ln 3
            de.Password = password             ' ln 4
            de.AuthenticationType = AuthenticationTypes.ServerBind  ' ln 5
            de.RefreshCache()                      ' ln 6

So I think I've found an LDAP String that works. Shall I plug this into the existing code you submitted before?
0
 

Author Comment

by:OnError_Fix
ID: 12614684
Ok -- steaming along here.

Plugging the correct LDAP string into the code you gave me before now appears to NOT produce errors, but doesn't return any results.

Any ideas?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12615625
Yea, it seems to be working..
Sorry, I was busy today.lots of problems.

One more things, include this line to make sure you can retrieve some attributes from the OU object
Dim dn As String = CType( de.Properties("distinguishedName").Value, String )
Dim wc As DateTime = CType( de.Properties("whenCreated").Value, DateTime )

If everything's fine, use the same ldapPath, userName, password and AuthenticationType to the original code.
0
 

Author Comment

by:OnError_Fix
ID: 12615703
Hi iHentry, not to worry about being busy!! We all are!

I've done what you have said, but it doesn't return any users - and doesn't give an error message. Any ideas?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12615752
:o)
When do AD programming you might feel get intimidated with the error messages that do not give information about the nature of the failure. That's pretty much all you get with an LDAP bind.
0
 

Author Comment

by:OnError_Fix
ID: 12615802
True ---

The problem is no users are returned. Where do we go from here?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12615817
Hm..can you do some debugging?

'-> check if the member var is not null (nothing)
Dim member As Object = result.Properties("member")
If IsNothing(member) Then
   '-> check if it gets into the loop
   For Each dn As String In CType(member, IEnumerable)
         users.Add(dn)
   Next
   '-> check number of element of the users array
   ' returns string array of users
   Return CType(users.ToArray(GetType(String)), String())
End If
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12616116
One question,

are you sure you can find any group under the "Users" OU in “Active Directory Users and Computers” snap-ins?
-> LDAP://DEV/CN=Users,DC=xxxx,DC=local
0
 

Author Comment

by:OnError_Fix
ID: 12616346
Hi,

If I change the groupname from "Users" to something else, it throws an error:

There is no such object on the server
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) at System.DirectoryServices.DirectoryEntry.Bind() at System.DirectoryServices.DirectoryEntry.RefreshCache() at Incorpex.Olympia2004V1.ActiveDirectory.DebugAD() in C:\Documents and Settings\r.parker\VSWebCache\intranet.domain.net\administration\ActiveDirectory.vb:line 25

Yet there is: I've tried changing the LDAP String to:

"LDAP://DEV/CN=Guests,DC=xxx,DC=local"
"LDAP://DEV/CN=Administrators,DC=xxx,DC=local"
"LDAP://DEV/CN=Domain Admins,DC=xxx,DC=local"

It only wants to execute if CN=Users. But if it does that, nothing is actually returned.

Let's say I wanted to view all the users who were a member of the "Administrators" group....
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12616608
If I don't remember if there're ldap default path with names
LDAP://DEV/CN=Guests,DC=xxx,DC=local
LDAP://DEV/CN=Administrators,DC=xxx,DC=local or
LDAP://DEV/CN=Domain Admins,DC=xxx,DC=local

I think that should be
LDAP://DEV/CN=USERS,CN=Guests,DC=xxx,DC=local
LDAP://DEV/CN=USERS,CN=Administrators,DC=xxx,DC=local or
LDAP://DEV/CN=USERS,CN=Domain Admins,DC=xxx,DC=local

What's the Administrators group's parent container? sorry, I don't have access to AD now.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12616692
You can check using “Active Directory Users and Computers” console. Or do you have other utility to browse active directory object like ADSI viewer or ldap browser for windows (download for free). Such utilities can make your life much easier.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12616708
0
 

Author Comment

by:OnError_Fix
ID: 12616892
The parent container for the Administrators group is "Builtin". I'm just trying to solve this now using the ldap browser program you suggested.
0
 

Author Comment

by:OnError_Fix
ID: 12616975
Hi,

I am increasing the reward for this question to 750 points. I need an answer, and soon!

Points go to s/he who can give me a VB.NET function that has the server to bind to and the group name to find as parameters (strings), and search the Active Directory server for that group, and then return a list of all the group's members.

Thank you.

Note to iHenry: still no joy. I'm not having any luck here.

In ASP classic this was so simple. What happened in .NET?!
Thanks.
0
 

Author Comment

by:OnError_Fix
ID: 12616981
Whoops - I cannot increase to 750 so I am setting to the max of 500.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12617355
I think you don't get the idea here, query groups to AD via DirectorySearcher should be the easiest way.

This is a user object, not a container object. A user object cannot contain any object and does not have "member" attribute.
LDAP://DEV/CN=Guests,DC=xxx,DC=local

These two are group objects, not container objects. A group object cannot contain any object and has "member" attribute.
LDAP://DEV/CN=Administrators,DC=xxx,DC=local
LDAP://DEV/CN=Domain Admins,DC=xxx,DC=local

When you create a DirectorySearcher object the constructor needs two parameters. First, the DirectoryEntry which represents a node (a container) in the Active Directory hierarchy where the search starts.

Let say you are searching for Administrators group which is under a container with this dn format "CN=BuiltIn, DC=<domain>, DC=", so your ldapPath should looks something like this "LDAP://DEV/CN=BuiltIn,DC=xxx,DC=local"

And the query filter is the search criteria, so "(&(objectCategory=group)(cn=Administrator)" means you are searching in AD for any object with objectCategory as group and has name exactly match to "Administrator".

And finally, this is how to call the function
Dim groups As String = GetUserRoles("Administrators")

Furthermore, path of an AD object actually depends on your AD structure. So knowing your own structure is the first priority here.

Active Directory default groups naming is pretty well documented here..
http://www.microsoft.com/resources/documentation/WindowsServ/2003/all/techref/en-us/Default.asp?url=/Resources/Documentation/windowsserv/2003/all/techref/en-us/w2k3tr_princ_how.asp
0
 

Author Comment

by:OnError_Fix
ID: 12618024
Right,

You're right: I don't quite understand the ins and outs of the DirectoryServices namespace.... hence my desire to find an answer here on EE.

I know how to CALL the function. It is the function itself which is returning an error for me. So my question is the same: who can write a simple function that will show me the users in the given group? I have tried the code you have sent me, and quite a few variations on it, and I either get an error message, or no users returned.

If you're able to continue trying I'd appreciate it.

Thank you.

0
 
LVL 20

Accepted Solution

by:
ihenry earned 2000 total points
ID: 12621737
Dear OnError_Fix,

Today was a tough day for me, my apologize if I have offended you in any way. I claim this as temporarily insanity. I found something in my code and I think it is the source of confusion.

instead of,
      If IsNothing(member) Then       <-- I should have noticed this..

it should be
      If Not IsNothing(member) Then

Again my apology if because of that you're losing some of your hair. I fixed the culprit and tested it using two environments, console and web application. And it works great. Now I paste here the full source code.

Public Function GetUserGroups(ByVal groupName As String)

      Dim ldapPath = "LDAP://THE_SERVER_NAME/CN=Builtin,DC=theDomainName,DC=local"
      Dim adminUserName = "theDomainName\theAdministrator"
      Dim adminPassword = "thePassword"

      Dim filter As String = String.Format("(&(objectCategory=group)(cn={0}))", groupName)
      Dim entry As New DirectoryEntry(ldapPath, adminUserName, adminPassword, AuthenticationTypes.None)
      Dim searcher As New DirectorySearcher(entry, filter)
      Dim users As New ArrayList

      Try

          Dim result As SearchResult = searcher.FindOne()
          Dim member As Object = result.Properties("member")
          If Not IsNothing(member) Then
            For Each dn As String In CType(member, IEnumerable)
                users.Add(dn)
            Next
            ' returns string array of users
            Return CType(users.ToArray(GetType(String)), String())
          End If

          ' returns empty string array
          Return New String() {}

      Catch
          Throw
      Finally
          If Not IsNothing(entry) Then
            entry.Dispose()
          End If
          If Not IsNothing(searcher) Then
            searcher.Dispose()
          End If
      End Try

End Function

And this how I used it

'-- in aspx.vb
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      'Put user code to initialize the page here
      Dim users As String() = GetUserGroups("Administrators")
      If users.Length = 0 Then
          Response.Write("No user suscribed to this group.<BR>")
      Else
          For Each user As String In users
            Response.Write(user + "<BR>")
          Next
      End If
End Sub

And the return values as follows (it's varied by your own AD structure)

CN=adminTest,CN=Users,DC=theDomainName,DC=local
CN=kilman.tom,CN=Users,DC=theDomainName,DC=local
CN=lim.shirley,CN=Users,DC=theDomainName,DC=local
CN=Jazayeri.Sean,CN=Users,DC=theDomainName,DC=local
CN=taylor.andrew,CN=Users,DC=theDomainName,DC=local
CN=white.trevor,CN=Users,DC=theDomainName,DC=local
CN=barbaro.ezio,CN=Users,DC=theDomainName,DC=local
CN=Domain Admins,CN=Users,DC=theDomainName,DC=local      <- this should exist
CN=Enterprise Admins,CN=Users,DC=theDomainName,DC=local  <- this should exist
CN=Administrator,CN=Users,DC=theDomainName,DC=local         <- this should exist

Note:
In Windows 2000 or Windows 2003 server, when you install Active directory via dcpromo this structure (see the following ldap path) will be created by default (should exists as well in your AD)

"LDAP://THE_SERVER_NAME/CN=Builtin,DC=theDomainName,DC=local"

DC=local could be DC=com or anything, it depends how you setup the DNS.


Hope this time could help.
0
 

Author Comment

by:OnError_Fix
ID: 12622935
iHenry,

No offence was taken so don't worry! I was getting quite frustrated; I thought the code you'd given me was OK but I was doing something wrong! Still, never mind, all that's history now because you've cracked it; it works brilliantly. I will award points to you. Just one mini question (still related) which you may be able to answer.

When the output comes back, it returns the users Full Name instead of their "username". For example:

CN=Test User,OU=HighRisk,DC=xxx,DC=local

"Test User" is actually the full name of the user (the concatenation of Firstname and Lastname), and the username should be "Test.User".

Any ideas?

If not no worries - I really appreciate your help so far.

0
 
LVL 20

Expert Comment

by:ihenry
ID: 12623889

The return value is actually "distinguishedName" attribute value of each user object.

CN=Test User,OU=HighRisk,DC=xxx,DC=local

The "Test User" is taken from cn attribute, it is not always as full name. That because it depends heavily on how the user object is created. For instance, you create one user object using the “Active Directory Users and Computers” console, the names default as follows. You specify the first name, initials, and last name of the user and it is displayed as <firstname> <initials>. <last name>. The source of confusion is when you create a user object programmatically, it is displayed as the cn attribute's value. You can overwrite this behaviour by set the cn attributes the same way as when you create a user via “Active Directory Users and Computers” console.

And also given a "distinguishedName" attribute you can get the associated object, example

Dim dn As String = "CN=white.trevor,CN=Users,DC=theDomainName,DC=local"
Dim de As New DirectoryEntry()
de.Path = "LDAP://THE_SERVER_NAME/" + dn
de.Username = userName
de.Password = password
de.RefreshCache()

Dim firstName = de.Properties("givenName").Value
Dim lastName = de.Properties("sn").Value

Just concatenate the two string whatever you like.
0
 

Author Comment

by:OnError_Fix
ID: 12624165
At long last!

It's here. And it works. Thanks to the very kind member iHenry and all the support given to me from EE, I am posting here my final solution to the initial problem for the world to see. It's basically two functions. One which iterates through ActiveDirectory to return all the objects within a given DN. The second, for each DN given to it, binds to it, checks to see if it is a user, and then adds it to a list which can be used elsewhere.

Triumph!

Enjoy the code :)

Public Function GetUserGroups(ByVal groupName As String)

        Dim ldapPath = "LDAP://" & ServerName & "/CN=" & CN & ",DC=" & DomainName & ",DC=" & DomainSuffix
        Dim filter As String = String.Format("(&(objectCategory=group)(cn={0}))", groupName)
        Dim entry As New DirectoryEntry(ldapPath, adminUserName, adminPassword, AuthenticationTypes.None)
        Dim searcher As New DirectorySearcher(entry, filter)
        Dim users As New ArrayList

        Try

            Dim result As SearchResult = searcher.FindOne()
            Dim member As Object = result.Properties("member")
            If Not IsNothing(member) Then
                For Each dn As String In CType(member, IEnumerable)
                    Dim sAMAccountName As String = GetAccountName(dn)
                    If Len(sAMAccountName) > 0 Then
                        users.Add(sAMAccountName)
                    End If
                Next
                ' returns string array of users
                Return CType(users.ToArray(GetType(String)), String())
            End If


        Catch e As Exception
            Return e.ToString

        End Try

        entry.Dispose()
        searcher.Dispose()


    End Function


    Public Function GetAccountName(ByVal DN As String)

        Dim strOutput As String

        Dim DE As New DirectoryEntry
        DE.Path = "LDAP://" & ServerName & "/" & DN
        DE.Username = AdminUsername
        DE.Password = AdminPassword
        DE.RefreshCache()

        Try

            For Each DV As String In CType(DE.Properties("objectClass"), IEnumerable)
                If DV = "user" Then
                    strOutput = DE.Properties("sAMAccountName").Value
                End If
            Next

            If Not Len(strOutput) > 0 Then
                Exit Function
            End If

        Catch ex As Exception
            'TODO: Raise an error
            strOutput = "There was an exception of some kind. It was: " & ex.ToString
        End Try

        Return strOutput

        DE.Dispose()


    End Function
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12624411
you are very welcome :0) and well done!

just two very trivial suggestions to the GetAccountName function,
put the DE.RefreshCache() method call in the try and catch block and use DE.SchemaClassName property to get the object class name.

0
 

Author Comment

by:OnError_Fix
ID: 12624753
iHenry, you deserve a medal mate :)

I've taken your suggestions and reorganised the function. It now reads:

Public Function GetAccountName(ByVal DN As String)

        Dim strOutput As String

        Dim DE As New DirectoryEntry
        DE.Path = "LDAP://" & ServerName & "/" & DN
        DE.Username = AdminUsername
        DE.Password = AdminPassword


        Try
            DE.RefreshCache()

            If DE.SchemaClassName = "user" Then
                strOutput = DE.Properties("sAMAccountName").Value
            End If

            If Not Len(strOutput) > 0 Then
                Exit Function
            End If

        Catch ex As Exception
            'TODO: Raise an error
            strOutput = "There was an exception and I died. It was: " & ex.ToString
        End Try

        Return strOutput

        DE.Dispose()


    End Function

And it even executes slightly faster, too.

NICE ONE!!

Thanks again.
0
 

Expert Comment

by:yankeek
ID: 32813013
This is a nice clean way to find them
Public Shared Function ADAllUsers(ByVal strGroupName As String) As ArrayList
        ' ** This will return Active Directory Info for a ALL USERS belonging to a GROUP
        Dim adDS As DirectorySearcher = New DirectorySearcher("LDAP://yourdomain.local") With {.Filter = "(&(objectClass=group)(cn=" & strGroupName & "))"}
        Dim results As DirectoryServices.SearchResultCollection = adDS.FindAll()
        Dim result As DirectoryServices.SearchResult
        Dim WorkList As New ArrayList
        If (results.Count > 0) Then
            Dim strManipulateName As String
            Dim intConstLocation As Int16
            For Each result In results
                For Each member As String In result.Properties("member")
                    strManipulateName = member.Replace("CN=", "").Replace("\", "")
                    intConstLocation = InStr(strManipulateName, "OU=", CompareMethod.Text)
                    strManipulateName = Mid(strManipulateName, 1, intConstLocation - 2)
                    WorkList.Add(strManipulateName)
                Next
            Next
        Else
            WorkList.Add("NOTHING FOUND!!")
        End If
        WorkList.Sort()
        Return WorkList
    End Function
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

Question has a verified solution.

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

This article explains how to create and use a custom WaterMark textbox class.  The custom WaterMark textbox class allows you to set the WaterMark Background Color and WaterMark text at design time.   IMAGE OF WATERMARKS STEPS Create VB …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Screencast - Getting to Know the Pipeline
Suggested Courses

749 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