Làm cách nào để phát hiện xem máy có được nối với miền Active Directory (so với chế độ Nhóm làm việc) không?Làm thế nào để phát hiện nếu máy được nối với miền (trong C#)?
Trả lời
Bạn có thể PInvoke để Win32 như của API như NetGetDcName mà sẽ trả về một null/chuỗi rỗng cho một máy không miền tham gia.
Thậm chí tốt hơn là NetGetJoinInformation sẽ cho bạn biết rõ ràng nếu máy không được kết nối, trong nhóm làm việc hoặc trong miền.
Sử dụng NetGetJoinInformation
tôi đặt lại với nhau này, mà làm việc cho tôi:
public class Test
{
public static bool IsInDomain()
{
Win32.NetJoinStatus status = Win32.NetJoinStatus.NetSetupUnknownStatus;
IntPtr pDomain = IntPtr.Zero;
int result = Win32.NetGetJoinInformation(null, out pDomain, out status);
if (pDomain != IntPtr.Zero)
{
Win32.NetApiBufferFree(pDomain);
}
if (result == Win32.ErrorSuccess)
{
return status == Win32.NetJoinStatus.NetSetupDomainName;
}
else
{
throw new Exception("Domain Info Get Failed", new Win32Exception());
}
}
}
internal class Win32
{
public const int ErrorSuccess = 0;
[DllImport("Netapi32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern int NetGetJoinInformation(string server, out IntPtr domain, out NetJoinStatus status);
[DllImport("Netapi32.dll")]
public static extern int NetApiBufferFree(IntPtr Buffer);
public enum NetJoinStatus
{
NetSetupUnknownStatus = 0,
NetSetupUnjoined,
NetSetupWorkgroupName,
NetSetupDomainName
}
}
ManagementObject cs;
using(cs = new ManagementObject("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'"))
{
cs.Get();
Console.WriteLine("{0}",cs["domain"].ToString());
}
Điều đó sẽ cho phép bạn lấy miền. Tôi tin rằng nó sẽ là rỗng hoặc trống nếu bạn là một phần của một nhóm làm việc và không phải là một miền.
Hãy chắc chắn để tham khảo System.Management
Nó trả về "WORKGROUP" nếu không có trong miền. Điều này sẽ làm việc (trừ khi bạn đang ở trong một tên miền "WORKGROUP"!), Nhưng tôi sẽ chờ đợi một chút để xem nếu có một phương pháp tiếp cận không dựa trên WMI trước khi chọn nó như là câu trả lời đúng. – DSO
Cảm ơn bạn đã cho tôi biết. Tôi chỉ có máy làm việc của mình để kiểm tra và tôi không thể xóa chính xác nó khỏi miền để kiểm tra. – Stephan
Tôi nghĩ rằng điều này sẽ không hiệu quả. Nó chỉ ra rằng tên của nhóm làm việc cho hộp kiểm tra của tôi thực sự là WORKGROUP. Tôi nghĩ rằng nó trả về tên nhóm làm việc, không phải là một giá trị cố định, mà từ một quan điểm API có ý nghĩa hơn, nhưng nó có nghĩa là bạn không thể sử dụng nó để xác định liệu miền của nó có tham gia hay không. – DSO
Các biến môi trường có thể làm việc cho bạn.
Environment.UserDomainName
MSDN Link để biết thêm chi tiết.
Environment.GetEnvironmentVariable("USERDNSDOMAIN")
Tôi không chắc chắn biến môi trường này tồn tại mà không nằm trong miền.
Khắc phục sự cố nếu tôi sai Máy tính bảng quản trị viên Windows - Tôi tin rằng máy tính có thể nằm trong một số miền để có thể quan trọng hơn để biết tên miền nào, nếu có, thay vì ở trong bất kỳ nào miền.
Theo như tôi biết máy tính chỉ có thể được nối với * một * miền - nhưng bạn có thể đăng nhập vào PC bằng thông tin xác thực từ nhiều miền trong rừng đó hoặc từ nhiều khu rừng nếu có tín thác lên. Tất cả đều hơi phức tạp một chút mặc dù =) – Rob
Environment.UserDomainName trả về tên máy tính nếu máy không được nối với miền. Tôi cho rằng tôi có thể so sánh điều đó với Environment.MachineName để xác định xem tên miền của nó có tham gia hay không, nhưng tôi không chắc liệu điều đó có đúng trong mọi tình huống hay không. – DSO
@ DSO - Tôi biết tôi đang nói chuyện muộn ở đây nhưng chỉ trong trường hợp ai đó tình cờ gặp chủ đề này, tôi chỉ muốn đề cập đến ngay cả trên máy tính đã tham gia miền nếu tài khoản người dùng đang chạy dưới tài khoản cục bộ hoặc hệ thống tài khoản, bạn không thể dựa vào UserDomainName! = MachineName. – Josh
Đừng đánh lừa bằng pinvoke nếu bạn không phải làm vậy.
Reference System.DirectoryServices, sau đó gọi:
System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain()
Ném một ActiveDirectoryObjectNotFoundException
nếu máy không phải là miền tham gia. Đối tượng Miền được trả về có chứa thuộc tính Tên mà bạn đang tìm kiếm.
Tôi luôn luôn thích thấy rằng tồn tại một phiên bản quản lý của hầu như bất cứ điều gì. –
Lưu ý cho người khác .. ** đảm bảo bạn sử dụng GetComputerDomain() ** (như đề xuất ở trên) và ** không GetCurrentDomain() **. GetCurrentDomain() chặn các độ tuổi nếu bạn không tham gia vào một miền. – James
Có sự cố với cuộc gọi này vì mất khoảng 2 phút trên nhiều cấu hình. –
Chỉ muốn thả Mã Rob trong VB:
Public Class Test
Public Function IsInDomain() As Boolean
Try
Dim status As Win32.NetJoinStatus = Win32.NetJoinStatus.NetSetupUnknownStatus
Dim pDomain As IntPtr = IntPtr.Zero
Dim result As Integer = Win32.NetGetJoinInformation(Nothing, pDomain, status)
If (pDomain <> IntPtr.Zero) Then
Win32.NetApiBufferFree(pDomain)
End If
If (result = Win32.ErrorSuccess) Then
If (status = Win32.NetJoinStatus.NetSetupDomainName) Then
Return True
Else
Return False
End If
Else
Throw New Exception("Domain Info Get Failed")
End If
Catch ex As Exception
Return False
End Try
End Function
End Class
Public Class Win32
Public Const ErrorSuccess As Integer = 0
Declare Auto Function NetGetJoinInformation Lib "Netapi32.dll" (ByVal server As String, ByRef IntPtr As IntPtr, ByRef status As NetJoinStatus) As Integer
Declare Auto Function NetApiBufferFree Lib "Netapi32.dll" (ByVal Buffer As IntPtr) As Integer
Public Enum NetJoinStatus
NetSetupUnknownStatus = 0
NetSetupUnjoined
NetSetupWorkgroupName
NetSetupDomainName
End Enum
End Class
Như Vâng như mã Stephan đây:
Dim cs As System.Management.ManagementObject
Try
cs = New System.Management.ManagementObject("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'")
cs.Get()
dim myDomain as string = = cs("domain").ToString
Catch ex As Exception
End Try
Tôi tin rằng chỉ có các mã thứ hai sẽ cho phép bạn biết những gì miền máy đã tham gia, ngay cả khi người dùng hiện tại KHÔNG PHẢI là thành viên miền.
Đây là phương pháp của tôi với xử lý/nhận xét ngoại lệ mà tôi đã phát triển dựa trên một số câu trả lời trong bài đăng này.
- Đưa bạn tên miền mà máy tính được kết nối.
Chỉ trả về tên miền nếu người dùng thực sự đăng nhập vào tài khoản miền.
/// <summary> /// Returns the domain of the logged in user. /// Therefore, if computer is joined to a domain but user is logged in on local account. String.Empty will be returned. /// Relavant StackOverflow Post: http://stackoverflow.com/questions/926227/how-to-detect-if-machine-is-joined-to-domain-in-c /// </summary> /// <seealso cref="GetComputerDomainName"/> /// <returns>Domain name if user is connected to a domain, String.Empty if not.</returns> static string GetUserDomainName() { string domain = String.Empty; try { domain = Environment.UserDomainName; string machineName = Environment.MachineName; if (machineName.Equals(domain,StringComparison.OrdinalIgnoreCase)) { domain = String.Empty; } } catch { // Handle exception if desired, otherwise returns null } return domain; } /// <summary> /// Returns the Domain which the computer is joined to. Note: if user is logged in as local account the domain of computer is still returned! /// </summary> /// <seealso cref="GetUserDomainName"/> /// <returns>A string with the domain name if it's joined. String.Empty if it isn't.</returns> static string GetComputerDomainName() { string domain = String.Empty; try { domain = System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain().Name; } catch { // Handle exception here if desired. } return domain; }
Bạn có thể muốn thử sử dụng lĩnh vực DomainRole WMI. Giá trị 0 và 2 cho thấy máy trạm độc lập và máy chủ độc lập tương ứng.
Chúng tôi đang sử dụng này cho XIA Cấu hình phần mềm kiểm toán mạng của chúng tôi vì vậy tôi đã cribbed phương pháp ở đây ...
/// <summary>
/// Determines whether the local machine is a member of a domain.
/// </summary>
/// <returns>A boolean value that indicated whether the local machine is a member of a domain.</returns>
/// <remarks>http://msdn.microsoft.com/en-gb/library/windows/desktop/aa394102(v=vs.85).aspx</remarks>
public bool IsDomainMember()
{
ManagementObject ComputerSystem;
using (ComputerSystem = new ManagementObject(String.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName)))
{
ComputerSystem.Get();
UInt16 DomainRole = (UInt16)ComputerSystem["DomainRole"];
return (DomainRole != 0 & DomainRole != 2);
}
}
Bạn có thể kiểm tra tài sản của lớp Win32_ComputerSystem WMI PartOfDomain. Các MSDN nói:
PartOfDomain
Data type: boolean
Tiếp cận loại: Read-only
Nếu Đúng vậy, máy tính là một phần của một tên miền. Nếu giá trị là NULL, máy tính không nằm trong miền hoặc trạng thái không xác định. Nếu bạn bỏ tham gia máy tính khỏi miền, giá trị sẽ trở thành sai.
/// <summary>
/// Determines whether the local machine is a member of a domain.
/// </summary>
/// <returns>A boolean value that indicated whether the local machine is a member of a domain.</returns>
/// <remarks>http://msdn.microsoft.com/en-us/library/windows/desktop/aa394102%28v=vs.85%29.aspx</remarks>
public bool IsDomainMember()
{
ManagementObject ComputerSystem;
using (ComputerSystem = new ManagementObject(String.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName)))
{
ComputerSystem.Get();
object Result = ComputerSystem["PartOfDomain"];
return (Result != null && (bool)Result);
}
}
Cũng có thể được gọi bằng cách sử dụng system.net
string domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName
Nếu chuỗi miền trống máy không bị ràng buộc.
Các giải pháp đề xuất ở trên trả về false trên một máy miền nếu một người dùng cục bộ được đăng nhập
Phương pháp đáng tin cậy nhất tôi đã tìm được là thông qua WMI:.
http://msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx (thấy domainrole)
Nếu vấn đề hiệu suất, sử dụng GetComputerNameEx chức năng:
bool IsComputerInDomain()
{
uint domainNameCapacity = 512;
var domainName = new StringBuilder((int)domainNameCapacity);
GetComputerNameEx(COMPUTER_NAME_FORMAT.ComputerNameDnsDomain, domainName, ref domainNameCapacity);
return domainName.Length > 0;
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool GetComputerNameEx(
COMPUTER_NAME_FORMAT NameType,
StringBuilder lpBuffer,
ref uint lpnSize);
enum COMPUTER_NAME_FORMAT
{
ComputerNameNetBIOS,
ComputerNameDnsHostname,
ComputerNameDnsDomain,
ComputerNameDnsFullyQualified,
ComputerNamePhysicalNetBIOS,
ComputerNamePhysicalDnsHostname,
ComputerNamePhysicalDnsDomain,
ComputerNamePhysicalDnsFullyQualified
}
Bạn có thể kiểm tra bằng WMI:
private bool PartOfDomain()
{
ManagementObject manObject = new ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName));
return (bool)manObject["PartOfDomain"];
}
- 1. Làm thế nào để phát hiện xem stdout được kết nối với một tty trong Perl?
- 2. Làm thế nào để có được tên miền máy chủ
- 3. Làm thế nào để phát hiện nếu Java được kích hoạt trong IE?
- 4. Làm thế nào để kết nối Sqlcmd với máy chủ?
- 5. Làm cách nào để kết nối với miền CloudSearch hiện có trong boto?
- 6. Làm thế nào để phát hiện bằng cách sử dụng C# nếu một ổ đĩa được cắm vào cổng USB?
- 7. Phát hiện gần kết nối máy khách trong node.js
- 8. Làm thế nào để phát hiện tốc độ kết nối Internet với Java?
- 9. C# phát hiện tcp ngắt kết nối
- 10. Phát hiện nếu Mod_Security được cài đặt với PHP?
- 11. Phát hiện khi CodeIgniter không kết nối được với Db
- 12. Làm thế nào để phát hiện nếu tôi đang chạy trong dịch vụ đơn?
- 13. DLLImport Int ** - Làm thế nào để làm điều này nếu nó có thể được thực hiện
- 14. Làm thế nào để phát hiện khi cáp nguồn laptop bị ngắt kết nối?
- 15. Làm thế nào để phát hiện nếu tôi đang chạy trong bảng điều khiển
- 16. Làm cách nào để phát hiện thiết bị đã được phát hiện và ghép nối có sẵn?
- 17. Làm thế nào tôi có thể phát hiện nếu một điều khiển ActiveX được tải?
- 18. Làm thế nào để phát hiện nếu Type là một loại Generic
- 19. Phát hiện nếu kết nối là wifi, 3G hoặc EDGE trong android?
- 20. Làm thế nào để phát hiện khi ổ đĩa di động được lắp bằng C#?
- 21. Làm thế nào để phát hiện nếu một chuỗi có một ngắt dòng mới trong nó?
- 22. Làm thế nào để phát hiện nếu con trỏ bị xóa và xóa an toàn?
- 23. Làm thế nào để phát hiện một khách hàng ngắt kết nối bằng cách sử dụng một máy khách ống/máy chủ được đặt tên?
- 24. Làm cách nào để phát hiện palindrome trong C?
- 25. Làm thế nào để chuyển tệp giữa hai máy tính được kết nối trong python?
- 26. Làm thế nào để có được tên miền từ Given IP trong C#?
- 27. Làm thế nào để phát hiện sự thay đổi trong mạng với Khả năng hiển thị?
- 28. Thực hiện dịch vụ phát trực tuyến WSGI: (cách phát hiện ngắt kết nối máy khách)
- 29. Làm thế nào để phát hiện chữ thường trong Python?
- 30. Làm thế nào để phát hiện deadlocks trong Mysql/innodb?
Tuyệt. Nhưng không có rò rỉ bộ nhớ nào trong hàm của bạn, dữ liệu pDomain được trả về bởi NetGetJoinInformation? – DSO
(không phải vấn đề rò rỉ quá nhiều ...vì tôi sẽ gọi nó một lần và lưu vào bộ nhớ đệm) – DSO
Ahh - mẫu mã mà tôi đã tấn công này từ trang PInvoke đang gọi NetApiBufferFree - tôi đã thêm nó vào mẫu =) – Rob