VB.NET: Отримайте повне ім'я від AD

Я намагаюся отримати повне ім'я користувача, вказавши свій ідентифікатор користувача "domain \ usarname". Випробували кілька різних прикладів, але ніхто не працює. Я використовую Visual Basic .Net 2010.

Спочатку я знайшов такий код у VBS і переніс на VBA і добре працював. Якщо я намагаюся використовувати той самий код у VB.NET 2010, я отримую кілька помилок, і шлях LDAP не знайдено, навіть якщо я ввожу його вручну.

Function FindUser()
 On Error GoTo Err

 Dim objRoot As Variant
 Dim LDAPdomainName As String
 Dim UserName As String
 Dim UserDomain As String

 Dim cn As Variant
 Dim cmd As Variant
 Dim rs As Variant


UserName = VBA.Environ("UserName") ' Gets Current User
UserDomain = VBA.Environ("UserDomain") 'Gets Current User's Domain


Set objRoot = GetObject("LDAP://RootDSE")
Domain= objRoot.Get("defaultNamingContext") 



 Set cn = CreateObject("ADODB.Connection")
 Set cmd = CreateObject("ADODB.Command")
 Set rs = CreateObject("ADODB.Recordset")

 cn.Open "Provider=ADsDSOObject;"

 cmd.activeconnection = cn
 'cmd.commandtext = "SELECT ADsPath FROM 'LDAP://" & Domain & "' WHERE sAMAccountName = '" & UserName & "'"
 'To see all attributes names available, connect with Active Directory Explorer and add to Select.
 cmd.commandtext = "SELECT cn, mail  FROM 'LDAP://" & Domain & "' WHERE sAMAccountName = '" & UserName & "'"
 Set rs = cmd.Execute


 Do Until rs.EOF
    Debug.Print rs("cn") & " E-mail: " & rs("mail")
    rs.MoveNext
 Loop


Exit_Err:
 If Not rs Is Nothing Then rs.Close
 If Not cn Is Nothing Then cn.Close
 Set rs = Nothing
 Set cmd = Nothing
 Set cn = Nothing
 Exit Function

Err:
 If Err <> 0 Then
    MsgBox "Error connecting to Active Directory Database: " & Err.Description
 Else
    If Not rs.BOF And Not rs.EOF Then
        rs.MoveFirst
        MsgBox rs(0)
    Else
        MsgBox "Not Found"
    End If
 End If
 Resume Exit_Err


End Function
1
що ти намагався поки що? Ви повинні додати якийсь код, який ви вже протестували, тому ми не пропонуємо те, що ви вже вивчили.
додано Автор Matthieu, джерело
Ну, те, що він намагався, не спрацював, так що все, що працює, є дійсною пропозицією.
додано Автор Yatrix, джерело

4 Відповіді

Якщо ви перебуваєте на .NET 3.5 і вище, перевірте простір імен System.DirectoryServices.AccountManagement (S.DS.AM). Прочитайте все про це тут:

В принципі, ви можете визначити контекст домену та легко знайти користувачів та/або групи в AD:

' set up domain context
Dim ctx As New PrincipalContext(ContextType.Domain)

' find a user
Dim user As UserPrincipal = UserPrincipal.FindByIdentity(ctx, "domain\username")

' do something here....     
If user IsNot Nothing Then
End If

' find the group in question
Dim group As GroupPrincipal = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere")

' if found....
If group IsNot Nothing Then
    ' iterate over members
    For Each p As Principal In group.GetMembers()
            ' do whatever you need to do to those members
        Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName)
    Next
End If

Новий S.DS.AM робить його дуже легко розігрувати з користувачами та групами в AD!

3
додано
На ctx Як новий принциповий контекст (ContextType.Domain) я отримую виняток Ldap був невиправлений повідомлення про помилку: "Зв'язок не може бути встановлений".
додано Автор Rick, джерело

Як щодо:

Імпорт System.DirectoryServices.AccountManagement

     

Dim userFullName As String = UserPrincipal.Current.DisplayName

3
додано

У мене є 2 функції, які допомогли мені зробити це з. Net 2.0 до використання. Net 4.0 після швидкого погляду на MSDN це повинно працювати у всіх версіях runtime.

2 функції:


'Determines your domain name
Private Function DomainName() As String
    Dim objRootDSE As New System.DirectoryServices.DirectoryEntry("LDAP://RootDSE")
    DomainName = objRootDSE.Properties("defaultNamingContext")(0)
End Function

'Will output user first name and last name. 
Public Sub ReturnUserName(ByVal UserAccountName As String)
    ' add a reference to System.DirectoryServices.dll
    Dim srch As System.DirectoryServices.DirectorySearcher
    Dim result As System.DirectoryServices.SearchResult
    Dim de, dir As System.DirectoryServices.DirectoryEntry

    de = New System.DirectoryServices.DirectoryEntry("LDAP://" & DomainName())
    srch = New System.DirectoryServices.DirectorySearcher(de)

    srch.SearchScope = SearchScope.Subtree
    srch.PropertiesToLoad.Add("givenName")
    srch.PropertiesToLoad.Add("sn")

    'Other field examples:
    'srch.PropertiesToLoad.Add("distinguishedName")
    'srch.PropertiesToLoad.Add("uid")

    ' users require both "user" and "person" filters
    ' and we also add the sAMAccountName to get the user passed.
    ' If you want to return all users in the domain remove the (sAMAccountName=" & UserAccountName & ")
    ' from the filter below.
    srch.Filter = "(&(objectClass=user)(objectCategory=person)(sAMAccountName=" & UserAccountName & "))"

    For Each result In srch.FindAll()
        dir = result.GetDirectoryEntry
        ' Properties are case sensitive!
        Debug.WriteLine(dir.Properties("givenname").Value & " " & dir.Properties("cn").Value)
    Next
End Sub

Прикладом заклику до цього буде:


Public Sub TestUserCall()
    'Returns the current logged in user.
    Call ReturnUserName(System.Security.Principal.WindowsIdentity.GetCurrent.Name)
End Sub

Цей приклад виклику буде працювати в режимах виконання версії 2.0-4.0, і це обов'язково, і повинно працювати у всіх версіях, випущених до цього часу.

Відповідні сторінки MSDN:

http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity.name(v=VS.100).aspx

http://msdn.microsoft.com/en -us/library/94se97ay (v = VS.80) .aspx

http://msdn.microsoft. ru/en-us/library/system.directoryservices.directoryentry (v = VS.80) .aspx

http://msdn.microsoft. ru/en-us/library/system.directoryservices.searchresult (v = VS.80) .aspx

1
додано
У рядку "DomainName = objRootDSE.Properties (" defaultNamingContext ") (0)" Я отримую COMException була невиправленою помилкою: "Шлях мережі не знайдено".
додано Автор Rick, джерело
Випробували перейти на всі різні DNS-сервери в мережі з повним іменем хоста та навіть IP-адресою, але все-таки отримують таку саму помилку.
додано Автор Rick, джерело
Я вказував на головний контролер домену, який працює в Windows Server 2008.
додано Автор Rick, джерело
Я можу лише подумати, чомусь ваша машина може не повертати сервер домену. Будь ласка, спробуйте замінити "LDAP://RootDSE" на "LDAP: //server.com/RootDSE", server.com - це DNS вашого сервера домену.
додано Автор Mako Steel, джерело
Це повинно замінити перший рядок в підменю DomainName() до Dim objRootDSE як New System.DirectoryServices.DirectoryEntry ("LDAP: //server.com/R‌ ootDSE") server.com - це DNS вашого сервера домену.
додано Автор Mako Steel, джерело
Яка версія ОС - ваш контролер домену? Чи правильно я підозрюю Windows Server 2003?
додано Автор Mako Steel, джерело
Просто помічено, що ви намагаєтеся подивитися на DNS-сервери. Вам слід вказати його на сервері контролера домену, ви можете знайти адресу, відкривши командний рядок і набравши команду "set logonserver", це повинно дати вам назву UNC DC і помістити його на місце server.com в рядок без "\\"
додано Автор Mako Steel, джерело
Ніколи не стикайтеся з цим раніше, під час мого пошуку ніхто, здається, не дає відповіді на те, чому це може статися. На жаль, лише інша публікація, яка пропонує відповідь, є досить пригнічливою відповіддю: social.msdn.microsoft.com/Forums/en/netfxnetcom/thread/…
додано Автор Mako Steel, джерело

Ви можете використовувати System.DirectoryServices для простору імен для виконання такого роду завдання ( DirectoryServices - це керована обгортка для LDAP).

Try
   ' Bind to the users container.
    Dim entry As New 
          DirectoryEntry("LDAP://CN=users,DC=fabrikam,DC=com")

    ' Create a DirectorySearcher object.
    Dim mySearcher As New DirectorySearcher(entry)

    ' Create a SearchResultCollection object to hold a collection
    ' of SearchResults returned by the FindAll method.
    Dim result As SearchResultCollection = mySearcher.FindAll()

    ' Create an object to hold a single result from the 
    ' result collection.
    Dim resEnt1 As SearchResult

    ' Get search results. For more information, 
    ' see Getting Search Results.
    ' 
    ' This sample uses Try...Catch to catch errors.
    ' Create an Exception object. For more information, 
    ' see System.Exception.

Catch Exception1 As System.Runtime.InteropServices.COMException
    Console.WriteLine(Exception1.Message)

Catch Exception2 As InvalidOperationException
    Console.WriteLine(Exception2.Message)

Catch Exception3 As NotSupportedException
    Console.WriteLine(Exception3.Message)

End Try 

You can use a search string such as "(&(objectCategory=user)(objectClass=person)(sAMAccountName=" + userId + "))" to search for a user (userID would need to be replaced with the User's ID).

Щоб зв'язати все разом, ви можете змінити фрагмент нижче, щоб повернутися назад всі властивості для користувача. Потім ви можете налаштувати його, лише зосередившись на Ім'я користувача.

Dim results As SearchResultCollection = Nothing

Try
    ' Bind to the users container.
    Dim path As String = "LDAP://CN=users,DC=fabrikam,DC=com"
    path = "LDAP://CN=Users,DC=strohmadom,DC=nttest,DC=microsoft,DC=com"
    Dim entry As New DirectoryEntry(path)

    ' Create a DirectorySearcher object.
    Dim mySearcher As New DirectorySearcher(entry)

    ' Set a filter for users with the name test.
    mySearcher.Filter = "(&(objectClass=user)(anr=test*))"

    ' Use the FindAll method to return objects to a SearchResultCollection.
    results = mySearcher.FindAll()

    ' Iterate through each SearchResult in the SearchResultCollection.
    Dim searchResult As SearchResult
    For Each searchResult In results
        ' Display the path of the object found.
        Console.WriteLine("Search properties for {0}", _
            searchResult.Path)

        ' Iterate through each property name in each SearchResult.
        Dim propertyKey As String
        For Each propertyKey In searchResult.Properties.PropertyNames
            ' Retrieve the value assigned to that property name 
            ' in the ResultPropertyValueCollection.
            Dim valueCollection As ResultPropertyValueCollection = searchResult.Properties(propertyKey)

            ' Iterate through values for each property name in each SearchResult.
            Dim propertyValue As Object
            For Each propertyValue In valueCollection
                ' Handle results. Be aware that the following 
                ' WriteLine() only returns readable results for 
                ' properties that are strings.
                Console.WriteLine("{0}:{1}", _
                    propertyKey, _
                    propertyValue.ToString())
            Next propertyValue
        Next propertyKey
    Next searchResult
Finally
    ' To prevent memory leaks, always call 
    ' SearchResultCollection.Dispose() manually.
    If Not results Is Nothing Then
        results.Dispose()
        results = Nothing
    End If
End Try
0
додано
У рядку "results = mySearcher.FindAll ()" Я отримую помилку про те, що "Мережний шлях не знайдено". Я замінив рядок шляху LDAP на наш сервер LDAP.
додано Автор Rick, джерело
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug