如何检测机器是否join到域(在C#中)?
如何检测计算机是否joinActive Directory域(与工作组模式相比)?
您可以PInvoke到Win32 API的,如NetGetDcName这将返回一个空/空string为非域join的机器。
更好的是NetGetJoinInformation将明确地告诉你,如果一台机器是unjoined,在工作组或域。
使用NetGetJoinInformation
我把这个,这对我工作:
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 } }
如果你不需要的话,不要欺骗。
引用System.DirectoryServices,然后调用:
System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain()
如果机器未join域,则会引发ActiveDirectoryObjectNotFoundException
。 返回的Domain对象包含您正在查找的Name属性。
也可以使用system.net来调用
string domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName
如果域string为空,则机器未绑定。
ManagementObject cs; using(cs = new ManagementObject("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'" )) { cs.Get(); Console.WriteLine("{0}",cs["domain"].ToString()); }
这应该允许你获得域名。 我相信如果你是一个工作组的一部分而不是一个域,它将是空的或空的。
确保引用System.Management
只想在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
以及Stephan的代码在这里:
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
我相信只有第二个代码才能让你知道机器join了哪个域,即使当前用户不是域成员。
环境variables可以为你工作。
Environment.UserDomainName
MSDN链接了解更多细节。
Environment.GetEnvironmentVariable("USERDNSDOMAIN")
我不确定这个环境variables是否存在,而不在域中。
纠正我,如果我错了Windowspipe理员的怪才 – 我相信一台计算机可以在几个域,所以它可能是更重要的是知道什么域,如果有的话,而不是在任何域。
您可以检查Win32_ComputerSystem WMI类的PartOfDomain属性。 MSDN说:
PartOfDomain
数据types:布尔值
访问types:只读
如果为True,则该计算机是域的一部分。 如果值为NULL,则说明计算机不在域中或者状态未知。 如果您从域中脱离计算机,则该值将变为false。
/// <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); } }
这里是我的exception处理/注释方法,我基于这篇文章中的几个答案开发的。
- 获取计算机连接的域。
-
只有当用户实际login到域帐户时才返回域名。
/// <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; }
如果性能很重要,请使用GetComputerNameEx函数:
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 }
您可能想尝试使用DomainRole WMI字段。 0和2的值分别显示独立工作站和独立服务器。
我们正在使用这个XIAconfiguration我们的networking审计软件,所以我在这里cribbed的方法…
/// <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); } }
您可以使用WMI进行检查:
private bool PartOfDomain() { ManagementObject manObject = new ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName)); return (bool)manObject["PartOfDomain"]; }
如果本地用户login,上面提出的解决scheme会在域计算机上返回false。
我发现的最可靠的方法是通过WMI:
http://msdn.microsoft.com/en-us/library/aa394102 (v=vs.85) .aspx (请参阅domainrole)