How to detect if machine is joined to domain?
Don't fool with pinvoke if you don't have to.
Reference System.DirectoryServices, then call:
System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain()
Throws an ActiveDirectoryObjectNotFoundException
if the machine is not domain-joined.
The Domain object that's returned contains the Name property you're looking for.
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
}
}
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
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
Just wanted to drop Rob's Code in 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
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.