How do I detect whether the machine is joined to an Active Directory domain (versus in Workgroup mode)?
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
You can check the PartOfDomain property of Win32_ComputerSystem WMI class. The MSDN says :
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.
/// <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);
}
}
If performance matters, use GetComputerNameEx function:
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
}
You can check using WMI:
private bool PartOfDomain()
{
ManagementObject manObject = new ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName));
return (bool)manObject["PartOfDomain"];
}
Can also be called by using 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
You can PInvoke to Win32 API's such as NetGetDcName which will return a null/empty string for a non domain-joined machine.
Even better is NetGetJoinInformation which will tell you explicitly if a machine is unjoined, in a workgroup or in a domain.
Using NetGetJoinInformation
I put together this, which worked for me:
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
}
}