C# 如何检测机器是否加入域?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/926227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:23:08  来源:igfitidea点击:

How to detect if machine is joined to domain?

c#.net

提问by DSO

How do I detect whether the machine is joined to an Active Directory domain (versus in Workgroup mode)?

如何检测机器是否加入了 Active Directory 域(相对于工作组模式)?

采纳答案by Rob

You can PInvoke to Win32 API's such as NetGetDcNamewhich will return a null/empty string for a non domain-joined machine.

您可以 PInvoke 到 Win32 API,例如NetGetDcName,它将为未加入域的机器返回空/空字符串。

Even better is NetGetJoinInformationwhich will tell you explicitly if a machine is unjoined, in a workgroup or in a domain.

更好的是NetGetJoinInformation,它会明确告诉您机器是否未加入,是在工作组中还是在域中。

Using NetGetJoinInformationI put together this, which worked for me:

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

}

回答by Stephan

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

That should allow you to get the domain. I believe it will be null or empty if you are part of a workgroup and not a domain.

这应该允许您获得域。我相信如果您是工作组而不是域的一部分,它将为空或空。

Make sure to reference System.Management

确保参考 System.Management

回答by Austin Salonen

The Environment variables could work for you.

环境变量可以为您工作。

Environment.UserDomainName

MSDN Linkfor some more details.

MSDN 链接以获取更多详细信息。

Environment.GetEnvironmentVariable("USERDNSDOMAIN")

I'm not sure this environment variable exists without being in a domain.

我不确定这个环境变量是否存在于域中。

Correct me if I'm wrong Windows Admin geeks -- I believe a computer can be in several domains so it may be more important to know what domain, if any, you are in instead of it being in anydomain.

如果我错了,请纠正我 Windows 管理员极客 - 我相信一台计算机可以位于多个域中,因此了解您所在的域(如果有)可能比它在任何域中更重要。

回答by Joe Clancy

Don't fool with pinvoke if you don't have to.

如果不需要,请不要使用 pinvoke。

Reference System.DirectoryServices, then call:

引用 System.DirectoryServices,然后调用:

System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain()

Throws an ActiveDirectoryObjectNotFoundExceptionif the machine is not domain-joined. The Domain object that's returned contains the Name property you're looking for.

ActiveDirectoryObjectNotFoundException如果计算机未加入域,则抛出。返回的域对象包含您要查找的 Name 属性。

回答by PatTheFrog

Just wanted to drop Rob's Code in VB:

只是想在 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

As Well as Stephan's code here:

以及斯蒂芬在这里的代码:

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


I believe that only the second code will allow you to know what domain the machine joined, even if the current user IS NOT a domain member.


我相信只有第二个代码才能让您知道机器加入了哪个域,即使当前用户不是域成员。

回答by blak3r

Here's my methods with exception handling / comments which I developed based on several of the answers in this post.

这是我根据这篇文章中的几个答案开发的异常处理/评论方法。

  1. Gets you the domain the computer is connected to.
  2. Only returns the domain name if the user is actually logged in on a domain account.

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

回答by David Homer

You might want to try using the DomainRole WMI field. Values of 0 and 2 show standalone workstation and standalone server respectively.

您可能想尝试使用 DomainRole WMI 字段。0 和 2 的值分别显示独立工作站和独立服务器。

We are using this for XIA Configuration our network audit software so I've cribbed the method here...

我们将它用于 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);
    }
}

回答by neilbgr

You can check the PartOfDomain property of Win32_ComputerSystem WMI class. The MSDNsays :

您可以检查 Win32_ComputerSystem WMI 类的 PartOfDomain 属性。在MSDN说:

PartOfDomain

Data type: boolean

Access type: Read-only

If True, the computer is part of a domain. If the value is NULL, the computer is not in a domain or the status is unknown. If you unjoin the computer from a domain, the value becomes false.

部分域

数据类型:布尔型

访问类型:只读

如果为 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);
    }
}   

回答by Eric Herlitz

Can also be called by using system.net

也可以使用 system.net 调用

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

If the domain string is empty the machine isn't bound.

如果域字符串为空,则机器未绑定。

Documentation on the property returned https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.ipglobalproperties.domainname?view=netframework-4.7.2#System_Net_NetworkInformation_IPGlobalProperties_DomainName

返回的属性文档https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.ipglobalproperties.domainname?view=netframework-4.7.2#System_Net_NetworkInformation_IPGlobalProperties_DomainName

回答by Andrew Morgan

The proposed solution above returns false on a domain machine if a local user is logged in.

如果本地用户登录,上述建议的解决方案在域计算机上返回 false。

The most reliable method i have found is via WMI:

我发现的最可靠的方法是通过 WMI:

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

http://msdn.microsoft.com/en-us/library/aa394102(v=vs.85) .aspx(见域角色)