Как определить, подключен ли компьютер к домену Active Directory (в режиме рабочей группы)?
Как определить, подключен ли компьютер к домену?
Ответ 1
Вы можете выполнить PInvoke для Win32 API, например NetGetDcName, который будет возвращать пустую/пустую строку для компьютера, не присоединенного к домену.
Еще лучше NetGetJoinInformation, которая сообщит вам явно, если машина не присоединена, в рабочей группе или в домене.
Используя 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
}
}
Ответ 2
Не обманывайте pinvoke, если вам это не нужно.
Reference System.DirectoryServices, затем вызовите:
System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain()
Выбрасывает ActiveDirectoryObjectNotFoundException
, если машина не подключена к домену.
Возвращаемый объект Domain содержит свойство Name, которое вы ищете.
Ответ 3
Также можно вызвать с помощью system.net
string domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName
Если строка домена пуста, машина не привязана.
Документация по возвращенному свойству https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.ipglobalproperties.domainname?view=netframework-4.7.2#System_Net_NetworkInformation_IPGlobalProperties_DomainName
Ответ 4
ManagementObject cs;
using(cs = new ManagementObject("Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'" ))
{
cs.Get();
Console.WriteLine("{0}",cs["domain"].ToString());
}
Это позволит вам получить домен. Я считаю, что он будет пустым или пустым, если вы являетесь частью рабочей группы, а не домена.
Обязательно укажите System.Management
Ответ 5
Просто хотел сбросить код Rob в 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
Как и код Стефана здесь:
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
Я считаю, что только второй код позволит вам узнать, к какой области присоединился компьютер, даже если текущий пользователь НЕ является членом домена.
Ответ 6
Переменные среды могут работать для вас.
Environment.UserDomainName
Ссылка MSDN для получения более подробной информации.
Environment.GetEnvironmentVariable("USERDNSDOMAIN")
Я не уверен, что эта переменная среды существует, не находясь в домене.
Исправьте меня, если я ошибаюсь. Гикеры Windows Admin - я считаю, что компьютер может находиться в нескольких доменах, поэтому может быть более важно знать, в каком домене вы находитесь, а не в каком-либо домене.
Ответ 7
Вы можете проверить свойство PartOfDomain класса WMI Win32_ComputerSystem. MSDN говорит:
PartOfDomain
Тип данных: boolean
Тип доступа: только для чтения
Если 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);
}
}
Ответ 8
Здесь мои методы с обработкой исключений/комментариями, которые я разработал на основе нескольких ответов в этом сообщении.
- Получает домен, к которому подключен компьютер.
-
Возвращает только имя домена, если пользователь действительно зарегистрирован в учетной записи домена.
/// <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 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; }
Ответ 9
Возможно, вы захотите попробовать использовать поле DomainRole WMI. Значения 0 и 2 показывают автономную рабочую станцию и автономный сервер соответственно.
Мы используем это для XIA Configuration нашего программного обеспечения для сетевого аудита, поэтому я тут же подкрепил метод...
/// <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);
}
}
Ответ 10
Если производительность имеет значение, используйте 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
}
Ответ 11
Вы можете проверить с помощью WMI:
private bool PartOfDomain()
{
ManagementObject manObject = new ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName));
return (bool)manObject["PartOfDomain"];
}
Ответ 12
Предлагаемое решение выше возвращает false на машине домена, если локальный пользователь зарегистрирован.
Самый надежный метод, который я нашел, - через WMI:
http://msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx (см. domainrole)