2011-10-27 26 views
1

ユーザーID「domain \ usarname」が与えられているユーザーのフルネームを取得しようとしています。いくつかの異なる例を試してみましたが、うまくいかないようです。 私はVisual Basic .NETを使用しています。VB.NET:ADからフルネームを取得

私はもともとVBSで次のコードを見つけ、VBAに移植してうまくいきました。 VB.NET 2010で同じコードを使用しようとすると、複数のエラーが発生し、手動で入力してもLDAPパスが見つかりません。あなたは、タスクのこの種を行うためにSystem.DirectoryServices名前空間を使用することができます

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 
+0

これまでに何を試しましたか?これまでにテストしたコードをいくつか追加する必要があります。既に検討していることは提案しません。 – Matthieu

+0

さて、彼が試したことは働いていないので、うまくいくものは有効な提案です。 – Yatrix

答えて

0

(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 

あなたが(ユーザーIDと交換する必要があるだろうユーザID)search stringなど"(&(objectCategory=user)(objectClass=person)(sAMAccountName=" + userId + "))"search for a userに使用することができます。

これをすべてつなぎ合わせると、下のスニペットを変更して、ユーザーのためにall of the propertiesを取り戻すことができます。ユーザー名にのみフォーカスするように調整できます。

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

3

は、.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のユーザーやグループで簡単に遊ぶことができます。

+0

ctxで新しいPrincipalContext(ContextType.Domain)としてLdap例外が発生しました。処理できなかったエラーメッセージ:「接続を確立できません」 – Rick

1

私は私は、.NETランタイムのすべてのバージョンでこのはず仕事はMSDNで一目を持った後、.NET 4.0 には、.NET 2.0からすべての方法をこれを行うに役立ってきた2つの機能を持っています。

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ではrk、確かには今までリリースされたすべてのバージョンで動作するはずです。

関連の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.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

+0

"DomainName = objRootDSE.Properties(" defaultNamingContext ")(0)" COMExceptionが発生しました。 "ネットワークパスが見つかりませんでした"というエラーが処理されました。 – Rick

+0

あなたのマシンがドメインサーバを返さないかもしれない何らかの理由しか考えられません。 "LDAP:// RootDSE"をドメインサーバーのDNSである "LDAP://server.com/RootDSE" server.comに置き換えてみてください。 –

+0

これは、DomainName()サブツリーの最初の行をDim objRootDSEとして新しいSystem.DirectoryServices.DirectoryEntry( "LDAP://server.com/RootDSE")server.comに置き換える必要があります。 –

3

何について:

Imports System.DirectoryServices.AccountManagement

Dim userFullName As String = UserPrincipal.Current.DisplayName

関連する問題