8

Tôi đang sử dụng System.DirectoryServices.AccountManagement.dll để xử lý Active Directory để nhận tất cả người dùng trong nhóm "Người dùng miền".Chỉ nhận tài khoản đã kích hoạt từ Active Directory

Điều này đang trả lại tất cả người dùng trong miền nhưng tôi chỉ cần có được những người dùng đã bật.

Dưới đây là một số mẫu mã:

List<string> users = new List<string>(); 

PrincipalContext pcContext = GetPrincipalContext(); 

GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext, 
           IdentityType.Name, 
           "Domain Users"); 

foreach (Principal user in grp.GetMembers(true).OfType<UserPrincipal>()) 
{ 
    if (user.Enabled != false) 
    { 
     users.Add(user.Name); 
    } 
} 

nhóm khác hoạt động tốt, nhưng khi nhóm là "Domain Users", giá trị của các tài sản Enabledfalse cho tất cả người dùng. Điều này làm cho nó không thể phân biệt giữa người dùng được kích hoạt và bị vô hiệu hóa mà không cần thực hiện thêm truy vấn cho mỗi người dùng.

+0

Bạn chỉ cần tên tài khoản? Có yêu cầu sử dụng không gian tên AccountManagement không? Bạn có làm bất cứ điều gì với đối tượng UserPrincipal khác ngoài lưu trữ tên không? Tôi chỉ hỏi vì yêu cầu của bạn có thể được phục vụ tốt hơn bằng cách sử dụng không gian tên DirectoryServices và DirectorySearcher với Bộ lọc LDAP như sau: (& (objectclass = user) (memberOf = CN = Người dùng miền, dc = company, dc = com) (! (userAccountControl: 1.2.840.113556.1.4.803: = 2))) Sẽ trả về tất cả người dùng trong nhóm đó được kích hoạt. – randcd

+1

randcd: Tôi muốn sử dụng không gian tên AM vì nó cung cấp một API rất sạch sẽ. Tôi chắc chắn có thể sử dụng LDAP, nhưng sau đó mọi thứ trở nên phức tạp hơn (đặc biệt trong trường hợp người dùng chỉ là thành viên của Người dùng miền vì đó là nhóm chính của họ, vì nó không được liệt kê trong 'memberOf' trong trường hợp đó). – RobSiklos

+0

"Hiệu trưởng" trong vòng lặp ForEach thực sự phải là "UserPrincipal" - "Đã bật" không phải là phương thức hoặc thuộc tính có thể truy cập trên đối tượng Princpal. Ít nhất không phải trong .net 4.6.1. Điều này tất cả có thể được thực hiện với không gian tên System.DirectoryServices.AccountManagement. – DtechNet

Trả lời

1

Đối tượng UserPrinciple có thuộc tính Kích hoạt bool cho điều này.

http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.userprincipal_properties.aspx

// Add this to GetUserDetails 
objUserDetails.EmployeeId = UserPrinical.EmployeeId; 


// Then condition the add to only add enabled 
if (objUserDetails.Enabled) { 
    objUserDetails.Add(GetUserDetails(p.Name)); 
} 
+0

Điều này không giải quyết được vấn đề, vì thuộc tính 'Đã bật' dường như không được điền đúng cách khi nhóm được truy vấn là" Người dùng miền " – RobSiklos

0

Có một nhận xét trên MSDN page of the Enabled property nói:

Nếu hiệu trưởng đã không được tiếp tục tồn tại các cửa hàng, khách sạn này trả về null. Sau khi hiệu trưởng được duy trì, cài đặt được bật mặc định phụ thuộc vào cửa hàng. Các cửa hàng AD DS và AD LDS vô hiệu hóa các hiệu trưởng mới khi chúng được duy trì, trong khi SAM cho phép các hiệu trưởng mới khi chúng được duy trì. Ứng dụng chỉ có thể đặt thuộc tính này thành một giá trị sau khi nó đã được duy trì trong cửa hàng.

Có thể nó liên quan nếu mặc định là sai?

Ngoài ra, có một bài đăng trên diễn đàn MSDN khoảng UserPrincipal.Enabled returns False for accounts that are in fact enabled? và điều đó thực sự giống với vấn đề của bạn. Theo bài đăng có thể có giải pháp ở đây:

Tôi nghĩ rằng tôi đã hiểu lầm. Bỏ qua những gì tôi đã đăng trước đây. Tôi nghĩ rằng tôi biết điều gì đang xảy ra. Phương thức GetMembers dường như không tải dữ liệu UserPrincipal. Tôi không biết nếu có một giải pháp tốt hơn, nhưng các công trình sau đây (ít nhất là trên AD của tôi):

foreach (UserPrincipal user in group.GetMembers(false)) 
{ 
    UserPrincipal tempUser = UserPrincipal.FindByIdentity(context, user.SamAccountName); 
    // use tempUser.Enabled 
    // other code here 
} 
+0

Người dùng đã tiếp tục tồn tại, vì vậy phần đầu tiên của câu trả lời không liên quan đến câu hỏi. Đối với phần còn lại, có - tôi biết tôi có thể làm điều này - câu hỏi nói rằng chúng tôi muốn có giá trị chính xác cho thuộc tính 'Đã bật' * mà không cần phải thực hiện thêm bất kỳ truy vấn nào (đặc biệt không phải là một người dùng trong đó vòng lặp). Bài đăng bạn đang trích dẫn thậm chí còn nói rằng giải pháp này quá chậm để hữu ích. – RobSiklos

1

Một phương pháp xung quanh vấn đề này có thể là để tìm kiếm đầu tiên dành cho người dùng kích hoạt bằng cách sử dụng PrincipalSearcher và sau đó sử dụng phương thức của Principal là IsMemberOf()

List<string> users = List<string>(); 
PrincipalContext pcContext = GetPrincipalContext(); 
GroupPrincipal grp = GroupPrincipal.FindByIdentity(pcContext, IdentityType.Name, "Domain Users"); 
UserPrincipal searchFilter = new UserPrincipal(pcContext){ Enabled = true } 
PrincipalSearcher searcher = new PrincipalSearcher(searchFilter); 
PrincipalSearchResult<Principal> results = searcher.FindAll(); 
foreach (Principal user in results) 
    if (user.IsMemberOf(grp)) 
     users.Add(user.SamAccountName); 
Các vấn đề liên quan