2012-02-29 8 views
1

이 날 쉽게 이동 직접 보고서를 얻기 위해,이 내 첫 번째 질문입니다 에 대한. 인트라넷 기반보고 도구 (VB.Net + ASP.Net Windows 통합 인증)는 SQL Server 2005 테이블에서 사용자 및 관리자를 조회하여보고를 관리자 수준으로 롤업합니다.은 관리자와

이 테이블은 현재 수동으로 유지 관리되며 훨씬 더 많은 사용자를 위해 확장 될 예정이므로 좀 더 동적으로 만들 것을 요청 받았습니다. 따라서 Active Directory와 연결하여 현재 수동으로 입력 된 Org 테이블을 백 엔드에 생성합니다.

내가 이것을 설정하는 가장 좋은 방법 할 수 있도록 확인 AD에서 사용자 데이터를 가져 오는 편안하지만, 아니에요, 나는 다음과 같은 테이블의 생각 :

CREATE TABLE dbo.Employees 
(
    EmpID  nvarchar(8) PRIMARY KEY, 
    EmpName  nvarchar(30), 
    EmpNo  nvarchar(15), 
    EmpEmail nvarChar(255), 
    EmpTitle nvarchar(255), 
    MgrID  nvarchar(8) FOREIGN KEY REFERENCES Employees(EmpID) 
) 
GO 

EmpID합니다 (NetworkID 될 것입니다 sAMAccountName).

그러면 AD에서 채워야 할 필요가 있습니다. 필드를 채우는 재귀 호출을 통해 추측하고 있습니다.

코드를 구성하는 방법을 잘 모르는 상태에서 모든 관리자가 주어진 레벨에서 시작하여 모든 직원을 캡처합니다. 나는 현재 주어진 관리자의 직접 보고서를 캡처 아래 사용하고

:

Public Function GetDirectReports(ByVal ADFullName As String) As ArrayList 

      Dim adItems As ArrayList = New ArrayList 

      Dim rootEntry As New DirectoryEntry("LDAP://" & ADFullName) 

      Dim searcher As New DirectorySearcher(rootEntry) 
      searcher.PropertiesToLoad.Add("directReports") 
      searcher.PropertiesToLoad.Add("sAMAccountName") 
      searcher.PropertiesToLoad.Add("cn") 

      searcher.PageSize = 5 
      searcher.ServerTimeLimit = New TimeSpan(0, 0, 30) 
      searcher.ClientTimeout = New TimeSpan(0, 10, 0) 

      Dim queryResults As SearchResultCollection 
      queryResults = searcher.FindAll() 

      Dim x As Integer 

      For Each result As SearchResult In queryResults 
       For x = 0 To result.Properties("directReports").Count - 1 
        adItems.Add(New ADReports(result.Properties("directReports")(x), _ 
           ExtractUser(result.Properties("directReports")(x)))) 
       Next 
      Next 
      Return adItems 
     End Function 

     Private Function ExtractUser(ByVal username) As String 
      Return Split(Split(username, "CN=")(1), ",")(0) 
     End Function 

모든 의견 제안 및 도움은 매우 극명하게 될 것이다 :

은 기본적으로 내가 할 것 인 것이다
+0

VB.NET/.NET 프레임 워크의 ** 버전 **을 사용하고 있습니까? 'directReports' 속성은 회사가 AD에 추가 한 맞춤 속성입니까 ?? –

+0

VS2005 sp1 및 2.0 아니요, 광고에 내장되어 있습니다. AFAIK – SWa

+0

아, 그래요. 예, 보고서 (LDAP 표시 이름 :'directReports')라고합니다. –

답변

1

단순히 전체 AD를 반복하고 필요한 모든 관련 정보를 가지고 모든 사용자를 확보하고 SQL Server에 저장하십시오. 열거하는 동안 계층 구조에 대해 걱정하지 마세요. 나중에 처리 할 것입니다.

데이터가 SQL Server 내에 있으면 예를 들어 다음과 같이 만들 수 있습니다. 직원의 계층 구조를 파악하는 재귀 CTE (Common Table Expression) - 누가 누구에게보고하는지 알 수 있습니다.

보조 노트 : sAMAccountName은 안정적으로 유지된다는 보장은 없습니다. - 각 사용자의 고유 식별자로 다른 항목이 필요합니까? 귀사에서 userID 속성을 사용합니까 아니면 다른 것이 있습니까? 또는 samAccountName 대신 AD 사용자 GUID (영원히 동일하게 유지됨)를 사용할 수 있습니까?

기타 : sAMAccountName을 고집하면 20 문자까지 사용할 수 있습니다. NVARCHAR(8)으로 충분하지 않습니다. 또한 : 정말 유니 코드 문자열이 필요합니까? 그것들은 비 유니 코드 인 VARCHAR(20) 문자열의 2 배에 불과합니다. 묻는다면 필요할 수도 있습니다. 그렇다면 괜찮습니다.

이 테이블의 양호한 클러스터링 키에 대한 모든 요구 사항을 처리하기 위해 테이블에 인공적인 EmployeeID (INT IDENTITY) 열을 추가하는 것이 좋습니다. A nvarchar(20)은 처음에는 가변 길이가 좋지 않으며 40 바이트까지 될 수 있습니다. 이는 다시 최적이 아닙니다.

+1

알았어, 알 겠어. 테이블 구조에 대한 조언을 해줘서 고마워. 내 고유 식별자를 제안대로 변경하겠습니다. 귀하의 답변을 주셔서 감사합니다. 귀하는 명확하고 매우 도움이되었습니다. – SWa

1

이 코드 스 니펫을 사용하여 특정 직원의 관리자 이름을 얻을 수 있습니다.관리자의 부하 직원을 알고 싶으면 직접보고를 관리자로 바꾸십시오.

lblUser.Text = My.User.Name 
    Dim _UserName As String = GetDomainUserName(My.User.Name) 
    Dim context As PrincipalContext = New PrincipalContext(ContextType.Domain) 


    ' find a user 
    Dim user As UserPrincipal = UserPrincipal.FindByIdentity(context, lblUser.Text) 

    Dim allUsers As New ArrayList() 
    Dim searchRoot As New DirectoryEntry("LDAP://DOMAIN") 
    Dim search As New DirectorySearcher(searchRoot) 
    'search.Filter = "(&(objectClass=user)(manager=" + user.DistinguishedName + "))" 
    search.Filter = "(&(objectClass=user)(directReports=" + user.DistinguishedName + "))" 
    search.PropertiesToLoad.Add("samaccountname") 

    Dim result As SearchResult 
    Dim resultCol As SearchResultCollection = search.FindAll() 
    If resultCol IsNot Nothing Then 
     For counter As Integer = 0 To resultCol.Count - 1 
      result = resultCol(counter) 
      If result.Properties.Contains("samaccountname") Then 
       allUsers.Add(DirectCast(result.Properties("samaccountname")(0), [String])) 
      End If 
     Next 
    End If 
관련 문제