development

컴퓨터가 도메인에 가입되어 있는지 감지하는 방법은 무엇입니까?

big-blog 2020. 12. 26. 16:29
반응형

컴퓨터가 도메인에 가입되어 있는지 감지하는 방법은 무엇입니까?


컴퓨터가 Active Directory 도메인에 가입되었는지 여부를 어떻게 감지합니까 (작업 그룹 모드와 비교)?


도메인에 가입되지 않은 시스템에 대해 null / 빈 문자열을 반환하는 NetGetDcName 과 같은 Win32 API에 PInvoke를 수행 할 수 있습니다 .

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
    }

}

필요하지 않은 경우 pinvoke로 속지 마십시오.

System.DirectoryServices를 참조하고 다음을 호출합니다.

System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain()

를 throw ActiveDirectoryObjectNotFoundException컴퓨터가 도메인에 가입하지 않은 경우. 반환되는 Domain 개체에는 찾고있는 Name 속성이 포함되어 있습니다.


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


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

그러면 도메인을 얻을 수 있습니다. 도메인이 아닌 작업 그룹의 일부인 경우 null이거나 비어 있다고 생각합니다.

System.Management를 참조하십시오.


VB에서 Rob의 코드를 삭제하고 싶었습니다.

 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


현재 사용자가 도메인 구성원이 아닌 경우에도 두 번째 코드 만 있으면 컴퓨터가 어떤 도메인에 가입했는지 알 수 있습니다.


환경 변수가 작동 할 수 있습니다.

Environment.UserDomainName

자세한 내용은 MSDN 링크 를 참조하십시오.

Environment.GetEnvironmentVariable("USERDNSDOMAIN")

이 환경 변수가 도메인에 있지 않고 존재하는지 확실하지 않습니다.

내가 잘못 윈도우 관리자 괴짜이야 경우 정정 해줘 - 난, 당신이 대신가에있는의에 어떤 도메인 (있는 경우)를 알고 더 중요 할 수 있도록 컴퓨터가 여러 도메인에있을 수 있다고 생각 어떤 도메인.


Win32_ComputerSystem WMI 클래스의 PartOfDomain 속성을 확인할 수 있습니다. MSDN은 말한다 :

PartOfDomain

데이터 유형 : 부울

액세스 유형 : 읽기 전용

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

다음은이 게시물의 여러 답변을 기반으로 개발 한 예외 처리 / 댓글이있는 방법입니다.

  1. 컴퓨터가 연결된 도메인을 가져옵니다.
  2. 사용자가 실제로 도메인 계정에 로그인 한 경우에만 도메인 이름을 반환합니다.

    /// <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의 값은 각각 독립형 워크 스테이션과 독립형 서버를 표시합니다.

우리는 네트워크 감사 소프트웨어를 XIA 구성에 사용하고 있으므로 여기에 방법을 작성했습니다.

/// <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"];
}

위의 제안 된 솔루션은 로컬 사용자가 로그인 한 경우 도메인 컴퓨터에서 false를 반환합니다.

내가 찾은 가장 안정적인 방법은 WMI를 사용하는 것입니다.

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

참조 URL : https://stackoverflow.com/questions/926227/how-to-detect-if-machine-is-joined-to-domain

반응형