VB.NET: verkrijg de volledige naam van ADVERTENTIE

Ik probeer de volledige naam van een gebruiker te krijgen, gegeven hun gebruikers-ID "domain \ usarname". Heb een aantal verschillende voorbeelden geprobeerd, maar geen enkele lijkt te werken. Ik gebruik Visual Basic .Net 2010.

Ik had oorspronkelijk de volgende code gevonden in VBS en geporteerd naar VBA en werkte goed. Als ik dezelfde code in VB.NET 2010 probeer te gebruiken, krijg ik meerdere fouten en wordt het LDAP-pad niet gevonden, ook al voer ik het handmatig in.

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
wat heb je tot nu toe geprobeerd? Je moet een code toevoegen die je tot nu toe hebt getest, dus we stellen niets voor dat je al hebt onderzocht.
toegevoegd de auteur Matthieu, de bron
Welnu, wat hij heeft geprobeerd heeft niet gewerkt, dus alles wat werkt is een geldig voorstel.
toegevoegd de auteur Yatrix, de bron

4 antwoord

Als u. NET 3.5 en hoger gebruikt, moet u de naamruimte System.DirectoryServices.AccountManagement (S.DS.AM) bekijken. Lees er hier alles over:

Kortom, u kunt een domeincontext definiëren en gemakkelijk gebruikers en/of groepen in AD vinden:

' 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

De nieuwe S.DS.AM maakt het heel gemakkelijk om met gebruikers en groepen in AD te spelen!

3
toegevoegd
Op ctx als nieuwe principalcontext (ContextType.Domain) Ik krijg een Ldap-uitzondering is onveranderd foutbericht: "De verbinding kan niet worden gemaakt."
toegevoegd de auteur Rick, de bron

Hoe zit het met:

Importeert System.DirectoryServices.AccountManagement

     

Dim userFullName As String = UserPrincipal.Current.DisplayName

3
toegevoegd

Ik heb 2 functies die me hebben geholpen om dit te doen vanuit .Net 2.0 helemaal tot .Net 4.0 na een snelle blik op MSDN zou dit moeten werken in alle versies van de .Net-runtimes.

De 2 functies zijn:


'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

Een voorbeeld van een oproep hiervoor is:


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

Deze voorbeeldaanroep werkt in runtime-versies 2.0 tot 4.0 en zeker moet werken in alle tot nu toe uitgebrachte versies.

De gerelateerde MSDN-pagina's zijn:

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. com/en-US/library/system.directoryservices.directoryentry (v = VS.80) Aspx

http://msdn.microsoft. com/en-US/library/system.directoryservices.searchresult (v = VS.80) Aspx

1
toegevoegd
Op de regel "DomainName = objRootDSE.Properties (" defaultNamingContext ") (0)" Ik krijg een COMException was unhandled error: "Het netwerkpad is niet gevonden."
toegevoegd de auteur Rick, de bron
Geprobeerd om te veranderen naar alle verschillende DNS-servers op het netwerk, met de volledige hostnaam en zelfs het IP-adres, maar krijgt nog steeds dezelfde foutmelding.
toegevoegd de auteur Rick, de bron
Ik wees naar de hoofddomeincontroller die op Windows Server 2008 wordt uitgevoerd.
toegevoegd de auteur Rick, de bron
Ik kan alleen maar denken dat je machine de domeinserver mogelijk niet retourneert. Probeer "LDAP://RootDSE" te vervangen door "LDAP: //server.com/RootDSE" server.com als DNS van uw domeinserver.
toegevoegd de auteur Mako Steel, de bron
Dat moet de eerste regel in de subdomeinnaam() vervangen door Dim objRootDSE als nieuwe System.DirectoryServices.DirectoryEntry ("LDAP: //server.com/R‌ ootDSE") waarbij server.com de DNS is van uw domeinserver.
toegevoegd de auteur Mako Steel, de bron
Op welke versie van het besturingssysteem draait uw domeincontroller? Heb ik gelijk als ik Windows Server 2003 vermoed?
toegevoegd de auteur Mako Steel, de bron
Je hebt net gemerkt dat je probeert naar de DNS-server (s) te kijken. U moet het naar uw domeincontroller-server wijzen, u kunt het adres vinden door een opdrachtprompt te openen en "set logonserver" te typen. Dit zou u de UNC-naam van de DC moeten geven en die in plaats van de server.com in de string zonder de "\\"
toegevoegd de auteur Mako Steel, de bron
kom dit nooit eerder tegen, tijdens mijn zoektocht lijkt niemand een antwoord te geven waarom dit zou kunnen gebeuren. alleen een andere post die een antwoord biedt, is helaas een nogal deprimerend antwoord: social.msdn.microsoft.com/Forums/en/netfxnetcom/thread/…
toegevoegd de auteur Mako Steel, de bron

U kunt de System.DirectoryServices naamruimte gebruiken om dit soort taken uit te voeren ( DirectoryServices is een beheerde wrapper voor 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).

Om alles samen te voegen, kunt u het onderstaande fragment aanpassen om alle eigenschappen voor een gebruiker. U kunt het vervolgens aanpassen om alleen op de gebruikersnaam te focussen.

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
toegevoegd
Op de regel "results = mySearcher.FindAll ()" krijg ik de foutmelding dat "Het netwerkpad niet is gevonden". Ik heb de LDAP-padstring vervangen door onze LDAP-server.
toegevoegd de auteur Rick, de bron