¿Cómo detectar si la máquina está unida al dominio (en C #)?

¿Cómo puedo detectar si la máquina está unida a un dominio de Active Directory (frente al modo de grupo de trabajo)?

Puede invocar a Win32 API como NetGetDcName, que devolverá una cadena nula / vacía para una máquina que no esté unida al dominio.

Aún mejor es NetGetJoinInformation, que le dirá explícitamente si una máquina no está unida, en un grupo de trabajo o en un dominio.

Usando NetGetJoinInformation esto, que funcionó para mí:

 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 } } 

No engañes con pinvoke si no tienes que hacerlo.

Referencia System.DirectoryServices, luego llame:

 System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain() 

Lanza una ActiveDirectoryObjectNotFoundException si la máquina no está unida a un dominio. El objeto de dominio que se devuelve contiene la propiedad Name que está buscando.

También se puede invocar mediante system.net

 string domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName 

Si la cadena de dominio está vacía, la máquina no está vinculada.

 ManagementObject cs; using(cs = new ManagementObject("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'" )) { cs.Get(); Console.WriteLine("{0}",cs["domain"].ToString()); } 

Eso debería permitirle obtener el dominio. Creo que será nulo o vacío si usted es parte de un grupo de trabajo y no un dominio.

Asegúrese de hacer referencia a System.Management

Solo quería dejar el código de Rob en 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 

Así como el código de Stephan aquí:

 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 

Creo que solo el segundo código le permitirá saber a qué dominio se unió la máquina, incluso si el usuario actual NO ES un miembro del dominio.

Las variables de entorno podrían funcionar para usted.

 Environment.UserDomainName 

MSDN Link para más detalles.

 Environment.GetEnvironmentVariable("USERDNSDOMAIN") 

No estoy seguro de que esta variable de entorno exista sin estar en un dominio.

Corrígeme si me equivoco Geeks de administración de Windows: creo que una computadora puede estar en varios dominios, por lo que puede ser más importante saber qué dominio, en caso de haber, se encuentra en lugar de estar en cualquier dominio.

Puede verificar la propiedad PartOfDomain de la clase Win32_ComputerSystem WMI. MSDN dice:

PartOfDomain

Tipo de datos: booleano

Tipo de acceso: solo lectura

Si es True, la computadora es parte de un dominio. Si el valor es NULL, la computadora no está en un dominio o el estado es desconocido. Si desvincula la computadora de un dominio, el valor se convierte en falso.

 ///  /// Determines whether the local machine is a member of a domain. ///  /// A boolean value that indicated whether the local machine is a member of a domain. /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa394102%28v=vs.85%29.aspx 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); } } 

Aquí están mis métodos con manejo de excepciones / comentarios que desarrollé basados ​​en varias de las respuestas en esta publicación.

  1. Obtiene el dominio al que está conectada la computadora.
  2. Solo devuelve el nombre de dominio si el usuario ha iniciado sesión en una cuenta de dominio.

     ///  /// 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 ///  ///  /// Domain name if user is connected to a domain, String.Empty if not. 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; } ///  /// 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! ///  ///  /// A string with the domain name if it's joined. String.Empty if it isn't. static string GetComputerDomainName() { string domain = String.Empty; try { domain = System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain().Name; } catch { // Handle exception here if desired. } return domain; } 

Si el rendimiento importa, use la función 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 } 

Es posible que desee intentar usar el campo WMI de DomainRole. Los valores de 0 y 2 muestran una estación de trabajo independiente y un servidor independiente, respectivamente.

Estamos usando esto para XIA Configuration, nuestro software de auditoría de red, así que he descifrado el método aquí …

 ///  /// Determines whether the local machine is a member of a domain. ///  /// A boolean value that indicated whether the local machine is a member of a domain. /// http://msdn.microsoft.com/en-gb/library/windows/desktop/aa394102(v=vs.85).aspx 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); } } 

Puede verificar usando WMI :

 private bool PartOfDomain() { ManagementObject manObject = new ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName)); return (bool)manObject["PartOfDomain"]; } 

La solución propuesta arriba devuelve falso en una máquina de dominio si un usuario local está conectado.

El método más confiable que he encontrado es a través de WMI:

http://msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx (see domainrole)