Getting a machine’s NetBIOS domain name in C#

I tried to find some mechanism to get the current machine’s NetBIOS domain name (the machine domain, not user domain), but couldn’t find anything in the usual places (e.g. System.Environment). If you want the fancy-schmancy Active Directory DNS domain then you can use Domain.GetComputerDomain().Name from System.DirectoryServices.ActiveDirectory, or another one that I stumbled across in Reflector was IPGlobalProperties.GetIPGlobalProperties().DomainName that lives in System.Net.NetworkInformation. But a simple way of getting the old-skool NetBIOS/LanManager-style machine domain name proved elusive.

Some googling suggested that WMI would provide the answer but I find WMI a little heavyweight, and not always reliable. The information is also probably in the registry somewhere, although I couldn’t find it after a cursory scan. The proper, supported way it would appear is to use the Network Management API. So my solution entailed P/Invoking to netapi32.dll.

If you’re after the same information I hope you find the code below useful. Once you’ve incorporated this in your project, just call the GetMachineNetBiosDomain method. It will return the machine’s Workgroup name if the machine is not domain-joined.

UPDATE: Now works on 64-bit thanks to update sent by Rp Brongers.

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

class NetUtil
{
    [DllImport("netapi32.dll", CharSet = CharSet.Auto)]
    static extern int NetWkstaGetInfo(string server,
        int level,
        out IntPtr info);

    [DllImport("netapi32.dll")]
    static extern int NetApiBufferFree(IntPtr pBuf);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    class WKSTA_INFO_100
    {
        public int wki100_platform_id;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string wki100_computername;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string wki100_langroup;
        public int wki100_ver_major;
        public int wki100_ver_minor;
    }

    public static string GetMachineNetBiosDomain()
    {
        IntPtr pBuffer = IntPtr.Zero;

        WKSTA_INFO_100 info;
        int retval = NetWkstaGetInfo(null, 100, out pBuffer);
        if (retval != 0)
            throw new Win32Exception(retval);

        info = (WKSTA_INFO_100)Marshal.PtrToStructure(pBuffer, typeof(WKSTA_INFO_100));
        string domainName = info.wki100_langroup;
        NetApiBufferFree(pBuffer);
        return domainName;
    }
}

29 thoughts on “Getting a machine’s NetBIOS domain name in C#

    1. Edward – that’s interesting, although I note it requires a query to Active Directory, so won’t work if run on say, a laptop that’s not currently connected to the corporate network.

  1. Thank you for this example, it works like a charm on 32 bits platforms. However, on Windows 7 64bits I ran into a problem, which I also fixed. Maybe you would be so kind to update the post with the fix to make it work on 64 bits as well (see below).
    On a 64bit platform, structures should not be passes to the netapi call directly (or any native dll for that matter). Instead, use an IntPtr and map the result to your structure.
    (Note: this was tested on a machine running Windows 7 64bit)

    [DllImport(“netapi32.dll”, CharSet = CharSet.Auto)]
    static extern int NetWkstaGetInfo([MarshalAs(UnmanagedType.LPWStr)]string server,
    int level,
    out IntPtr info);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    class WKSTA_INFO_100
    {
    public int wki100_platform_id;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public string wki100_computername;
    [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    public string wki100_langroup;
    public int wki100_ver_major;
    public int wki100_ver_minor;
    }

    public static string GetMachineNetBiosDomain()
    {
    IntPtr buffer = new IntPtr();

    WKSTA_INFO_100 info;
    int retval = NetWkstaGetInfo(null, 100, out buffer);
    if (retval != 0)
    throw new Win32Exception(retval);

    Int32 pointer = buffer.ToInt32();
    info = (WKSTA_INFO_100)Marshal.PtrToStructure(
    new IntPtr(pointer), typeof(WKSTA_INFO_100));
    string domainName = info.wki100_langroup;
    NetApiBufferFree(buffer);
    return domainName;
    }

  2. I’m currently testing this snippet converted to vb.net
    I couldn’t understand from the sample and comments:

    Is “Int32 pointer = buffer.ToInt32();” needed on 64 bit or not? (which is the correct function)

    Thanks for the code.

  3. Output the FQDN of a specified server NetBIOS name. Then you can query the substring from the FQDN.

    IPHostEntry he = Dns.GetHostEntry(serverNetBIOSName);
    IPHostEntry he2 = Dns.GetHostEntry(he.AddressList[0]);
    Console.WriteLine(he2.HostName);

  4. “Output the FQDN of a specified server NetBIOS name. Then you can query the substring from the FQDN.” -> don’t do this, it is not always correct.
    The netbios name can be different from the dns name

  5. Thank you for code. I tried all “official” .Net approaches but seems to be Win(32)API will live long life.

  6. Thank you for code. But this code not working, when running as a service (by LocalSystem). Any ideas?

  7. NetWkstaGetInfo Function…
    If the function fails, the return value can be one of the following error codes.

    ERROR_ACCESS_DENIED The user does not have access to the requested information.

    32 int retval = NetWkstaGetInfo(null, 100, out pBuffer);
    33 if (retval != 0)
    34 throw new Win32Exception(retval);

  8. >Is this code running on a Domain Controller?
    No. Windows Server 2003 Standard Edition, but no domain controller.

    >There’s some info about this in the docs
    > that might be relevant
    I read it, before write to you

    I think the reason is localsystem-user: he has no right to work in a network.

  9. Is there any service on the target computer needed to run in order to let this work? i couldn’t find that info on Msdn.

      1. Just curious 🙂 For WMI for example you need to have the WMI service running, why actually use that if this always works. And WMI seems the newer tech.

      2. WMI does a bunch of things, many of which are just wrappers around existing mechanisms such as this one. I always prefer the simplest possible thing that will work.

  10. Hi Duncan, is there any way we can Disable the NetBios programmatically? I’m thinking to expend your code & see if I can get it work.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s