2008-08-22 38 views
5

Trong C#, tôi cần để có thểthành viên trong nhóm người dùng liệt kê Windows trên hệ thống từ xa bằng C#

  • Kết nối với một hệ thống từ xa, xác định tên người dùng/mật khẩu cho phù hợp Danh sách
  • các thành viên của một localgroup ngày rằng hệ thống
  • Fetch các kết quả lại cho máy tính thực hiện

vì vậy, ví dụ tôi sẽ kết nối với \ SOMESYSTEM với creds thích hợp, và lấy lại một danh sách quản trị địa phương inclu ding SOMESYSTEM \ Quản trị viên, SOMESYSTEM \ Bob, DOMAIN \ AlanH, "DOMAIN \ Quản trị viên miền".

Tôi đã thử điều này với system.directoryservices.accountmanagement nhưng đang gặp sự cố với xác thực. Đôi khi tôi nhận được:

Nhiều kết nối với máy chủ hoặc tài nguyên được chia sẻ bởi cùng một người dùng, sử dụng nhiều tên người dùng, không được phép. Ngắt kết nối tất cả các kết nối trước đó với máy chủ hoặc tài nguyên được chia sẻ và thử lại. (Ngoại lệ từ HRESULT: 0x800704C3)

Ở trên là thử vì sẽ có những tình huống mà tôi không thể unmap unmap ổ đĩa hiện có hoặc kết nối UNC.

Các lần khác chương trình của tôi bị lỗi L UNI và nhật ký bảo mật trên hệ thống từ xa báo cáo lỗi 675, mã 0x19 là KDC_ERR_PREAUTH_REQUIRED.

Tôi cần một cách đơn giản hơn và ít bị lỗi hơn để thực hiện việc này!

+0

bạn có giải pháp nào về vấn đề này không? Trên thực tế khi bạn gọi GroupDirectoryentry.Invoke ("Thành viên") nó không phát hành kết nối đến sự kiện máy từ xa nếu chúng ta vứt bỏ GroupDirectoryentry object.Same vấn đề xảy ra với UserDirectoryentry.Invoke ("Groups") gọi. – sagar

Trả lời

1

Điều này phải dễ dàng thực hiện khi sử dụng WMI. Ở đây bạn có một con trỏ đến một số tài liệu:

WMI Documentation for Win32_UserAccount

Thậm chí nếu bạn không có kinh nghiệm trước đó với WMI, nó nên được khá dễ dàng để chuyển mã VB Script ở dưới cùng của trang vào một số mã NET .

Hy vọng điều này sẽ hữu ích!

0

Bạn sẽ có thể thực hiện việc này với System.DirectoryServices.DirectoryEntry. Nếu bạn gặp sự cố khi chạy nó từ xa, có thể bạn có thể cài đặt một cái gì đó trên các máy từ xa để cung cấp cho bạn dữ liệu của bạn thông qua một số loại RPC, như remoting hoặc một dịch vụ web. Nhưng tôi nghĩ những gì bạn đang cố gắng có thể được thực hiện từ xa mà không quá xa lạ.

0

Nếu Windows không cho phép bạn kết nối thông qua cơ chế đăng nhập, tôi cho rằng tùy chọn duy nhất của bạn là chạy một thứ gì đó trên máy từ xa với cổng mở (trực tiếp hoặc thông qua truy cập từ xa hoặc dịch vụ web như đã đề cập).

1

Tôi khuyên bạn nên sử dụng chức năng API Win32 NetLocalGroupGetMembers. Đó là nhiều hơn nữa thẳng về phía trước hơn là cố gắng tìm ra cú pháp LDAP điên, đó là cần thiết cho một số các giải pháp khác được đề nghị ở đây. Miễn là bạn mạo danh người dùng mà bạn muốn chạy séc bằng cách gọi "Người dùng đăng nhập", bạn không nên gặp phải bất kỳ sự cố bảo mật nào.

Bạn có thể tìm mã mẫu để thực hiện mạo danh here.

Nếu bạn cần trợ giúp tìm cách gọi "NetLocalGroupGetMembers" từ C#, tôi khuyên bạn nên kiểm tra trợ lý PInvoke của Jared Parson, bạn có thể download từ codeplex.

Nếu bạn đang chạy mã trong ứng dụng ASP.NET đang chạy trong IIS và muốn mạo danh người dùng truy cập trang web để thực hiện cuộc gọi, thì bạn có thể cần cấp quyền "Ủy quyền cho ủy quyền" cho sản xuất máy chủ web.

Nếu bạn đang chạy trên máy tính để bàn, sau đó sử dụng thông tin đăng nhập bảo mật của người dùng đang hoạt động không phải là vấn đề.

Có thể quản trị viên mạng của bạn có thể đã thu hồi quyền truy cập vào "Đối tượng bảo mật" cho máy cụ thể mà bạn đang cố gắng truy cập. Thật không may rằng truy cập là cần thiết cho tất cả các chức năng network management api để hoạt động. Nếu đúng như vậy, bạn sẽ cần cấp quyền truy cập vào "Đối tượng bảo mật" cho bất kỳ người dùng nào bạn muốn thực hiện. Tuy nhiên, với cài đặt bảo mật cửa sổ mặc định, tất cả người dùng được xác thực phải có quyền truy cập.

Tôi hy vọng điều này sẽ hữu ích.

-Scott

2

davidg đang đi đúng hướng và tôi đang ghi nhận câu trả lời cho anh ấy.

Nhưng truy vấn WMI cần thiết là một chút ít hơn thẳng, vì tôi không chỉ cần danh sách người dùng cho toàn bộ máy, mà là tập con của người dùng và các nhóm, cho dù địa phương hay miền là thành viên của nhóm Quản trị viên cục bộ. Đối với hồ sơ, rằng WMI truy vấn là:

SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = "Win32_Group.Domain='thehostname',Name='thegroupname'" 

Dưới đây là đoạn mã đầy đủ:

public string GroupMembers(string targethost, string groupname, string targetusername, string targetpassword) 
     { 
      StringBuilder result = new StringBuilder(); 
      try 
      { 
       ConnectionOptions Conn = new ConnectionOptions(); 
       if (targethost != Environment.MachineName) //WMI errors if creds given for localhost 
       { 
        Conn.Username = targetusername; //can be null 
        Conn.Password = targetpassword; //can be null 
       } 
       Conn.Timeout = TimeSpan.FromSeconds(2); 
       ManagementScope scope = new ManagementScope("\\\\" + targethost + "\\root\\cimv2", Conn); 
       scope.Connect(); 
       StringBuilder qs = new StringBuilder(); 
       qs.Append("SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = \"Win32_Group.Domain='"); 
       qs.Append(targethost); 
       qs.Append("',Name='"); 
       qs.Append(groupname); 
       qs.AppendLine("'\""); 
       ObjectQuery query = new ObjectQuery(qs.ToString()); 
       ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query); 
       ManagementObjectCollection queryCollection = searcher.Get(); 
       foreach (ManagementObject m in queryCollection) 
       { 
        ManagementPath path = new ManagementPath(m["PartComponent"].ToString());           
        { 
         String[] names = path.RelativePath.Split(','); 
         result.Append(names[0].Substring(names[0].IndexOf("=") + 1).Replace("\"", " ").Trim() + "\\"); 
         result.AppendLine(names[1].Substring(names[1].IndexOf("=") + 1).Replace("\"", " ").Trim());      
        } 
       } 
       return result.ToString(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error. Message: " + e.Message); 
       return "fail"; 
      } 
     } 

Vì vậy, nếu tôi gọi Groupmembers ("Server1", "Quản trị viên", "myusername", "my password "); Tôi nhận được một chuỗi duy nhất trở lại với:

SERVER1 \ Administrator
MYDOMAIN \ Domain Admins

Các thực tế WMI trở lại là như thế này:

\\ SERVER1 \ root \ cimv2: Win32_UserAccount.Domain = "SERVER1", Tên = "Quản trị viên"

... để bạn có thể thấy, tôi phải thực hiện một thao tác chuỗi nhỏ để thực hiện nó.

+0

Lưu ý cho người dùng: Bạn cần thêm System.Management.dll vào tham chiếu dự án của mình để sử dụng mã ở trên. – Rama

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