Как определить, подключен ли компьютер к домену? - программирование
Подтвердить что ты не робот

Как определить, подключен ли компьютер к домену?

Как определить, подключен ли компьютер к домену Active Directory (в режиме рабочей группы)?

4b9b3361

Ответ 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)