2010-10-25 17 views
6

Tôi cần truy vấn bộ kiểm soát miền hiện tại, có thể là chính để thay đổi mật khẩu người dùng.Xác định bộ điều khiển miền hiện tại theo lập trình

(P) tên DC nên có đủ điều kiện, ví dụ: DC=pdc,DC=example,DC=com (làm thế nào để đặt tên cho đúng ký hiệu như vậy?)

Làm thế nào nó có thể được thực hiện bằng C#?

Trả lời

1

(yêu cầu System.DirectoryServices.AccountManagement.dll):

using (var context = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Domain)) 
{ 
    string server = context.ConnectedServer; // "pdc.examle.com" 
    string[] splitted = server.Split('.'); // { "pdc", "example", "com" } 
    IEnumerable<string> formatted = splitted.Select(s => String.Format("DC={0}", s));// { "DC=pdc", "DC=example", "DC=com" } 
    string joined = String.Join(",", formatted); // "DC=pdc,DC=example,DC=com" 

    // or just in one string 

    string pdc = String.Join(",", context.ConnectedServer.Split('.').Select(s => String.Format("DC={0}", s))); 
} 
+0

Điều này sẽ không hoạt động đối với trường hợp tên miền chéo (ví dụ: máy của bạn không nằm trong miền có Trình kiểm soát miền). Xem câu trả lời của tôi cho một giải pháp như vậy. –

+0

@Firo: Cảm ơn, đã khắc phục. Lỗi được cố định bởi 'string []' -> 'IEnumerable ' – abatishchev

0

Nếu bạn đang tìm kiếm để tương tác với Active Directory, bạn không cần phải biết nơi FSMO vai trò là dành cho hầu hết các phần. Nếu bạn muốn thay đổi cấu trúc liên kết AD từ chương trình của bạn (tôi sẽ không), hãy nhìn vào lớp DomainController.

Nếu bạn muốn thay đổi mật khẩu người dùng, bạn có thể gọi những hành động đó trên đối tượng người dùng và Active Directory sẽ đảm bảo rằng các thay đổi được sao chép đúng cách.

sao chép từ http://www.rootsilver.com/2007/08/how-to-change-a-user-password

public static void ChangePassword(string userName, string oldPassword, string newPassword) 
{ 
     string path = "LDAP://CN=" + userName + ",CN=Users,DC=demo,DC=domain,DC=com"; 

     //Instantiate a new DirectoryEntry using an administrator uid/pwd 
     //In real life, you'd store the admin uid/pwd elsewhere 
     DirectoryEntry directoryEntry = new DirectoryEntry(path, "administrator", "password"); 

     try 
     { 
      directoryEntry.Invoke("ChangePassword", new object[]{oldPassword, newPassword}); 
     } 
     catch (Exception ex) //TODO: catch a specific exception ! :) 
     { 
      Console.WriteLine(ex.Message); 
     } 

     Console.WriteLine("success"); 
} 
+0

bạn nghĩ thế nào, tôi có thể thay đổi mật khẩu hiện tại của mình bằng tên người dùng và mật khẩu hiện tại của riêng tôi không? – abatishchev

2

Chúng tôi đang sử dụng một cái gì đó như thế này cho các ứng dụng nội bộ của chúng tôi.

nên trở lại một cái gì đó giống như DC=d,DC=r,DC=ABC,DC=com

public static string RetrieveRootDseDefaultNamingContext() 
{ 
    String RootDsePath = "LDAP://RootDSE"; 
    const string DefaultNamingContextPropertyName = "defaultNamingContext"; 

    DirectoryEntry rootDse = new DirectoryEntry(RootDsePath) 
    { 
     AuthenticationType = AuthenticationTypes.Secure; 
    }; 
    object propertyValue = rootDse.Properties[DefaultNamingContextPropertyName].Value; 

    return propertyValue != null ? propertyValue.ToString() : null; 
} 
+0

Có bạn đã đúng. Chúng ta thường có một số mã đăng nhập tùy chỉnh trong câu lệnh catch nhưng tôi đã lấy nó ra cho ví dụ này. – Lareau

+1

@abatishchev: tuyên bố đó là sai - gọi chỉ là 'throw' sẽ ** giữ ** dấu vết ngăn xếp; tạo ra một ngoại lệ mới hoặc làm 'throw ex;' sẽ phá vỡ ngăn xếp cuộc gọi; xem: http://weblogs.asp.net/fmarguerie/archive/2008/01/02/rethrowing-exceptions-and-preserving-the-full-call-stack-trace.aspx –

+0

@marc_s: yea, bạn đúng, tôi đã sai (trong cụm từ về ngăn xếp dấu vết). dù sao điều này không có ý nghĩa cho đến khi đăng nhập, vv như @Lareau đã nói – abatishchev

5

Để lấy thông tin khi DomainController tồn tại trong một miền trong đó máy tính của bạn không thuộc, bạn cần một cái gì đó nhiều hơn nữa.

DirectoryContext domainContext = new DirectoryContext(DirectoryContextType.Domain, "targetDomainName", "validUserInDomain", "validUserPassword"); 

    var domain = System.DirectoryServices.ActiveDirectory.Domain.GetDomain(domainContext); 
    var controller = domain.FindDomainController(); 
+0

Tôi không muốn chuyển tên người dùng và mật khẩu. – abatishchev

+0

Thật không may nếu bạn đang vượt qua các tên miền, bạn cần phải. Danh tính hiện tại của bạn sẽ không được nhận dạng khác. Ngay cả với không gian tên mới "3.5" System.DirectoryServices.AccountManagement', bạn sẽ phải bao gồm tên người dùng/mật khẩu hợp lệ trên miền * bên ngoài *. –

+0

Tính năng này không hoạt động vì máy tính cục bộ của bạn sẽ không thể tìm thấy DC cho tên miền đó. – Bluebaron

Các vấn đề liên quan