NetJoinDomain (netapi32)
Last changed: -203.20.245.12

.
Summary
The NetJoinDomain function joins a computer to a workgroup or domain.

C# Signature:

[DllImport("netapi32.dll", CharSet=CharSet.Unicode)]
static extern int NetJoinDomain(
          string lpServer,
          string lpDomain,
          string lpAccountOU,
          string lpAccount,
          string lpPassword,
          JoinOptions NameType);

VB Signature:

Declare Unicode Function NetJoinDomain Lib "Netapi32.dll" _
        (ByVal lpServer As String, _
        ByVal lpDomain As String, _
        ByVal lpAccountOU As String, _
        ByVal lpAccount As String, _
        ByVal lpPassword As String, _
        ByVal fJoinOptions As Integer) As Integer

User-Defined Types:

        [Flags]
        public enum JoinOptions
        {
          NETSETUP_JOIN_DOMAIN = 0x00000001,
          NETSETUP_ACCT_CREATE = 0x00000002,
          NETSETUP_ACCT_DELETE = 0x00000004,
          NETSETUP_WIN9X_UPGRADE = 0x00000010,
          NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020,
          NETSETUP_JOIN_UNSECURE = 0x00000040,
          NETSETUP_MACHINE_PWD_PASSED = 0x00000080,
          NETSETUP_DEFER_SPN_SET = 0x00000100,
        }

Notes:

Be careful to specify CharSet.Unicode as otherwise the strings will be encoded as Ansi whereas the function only supports Unicode.

If the function succeeds, the return value is NERR_Success.

If the function fails, the return value can be one of the following error codes or one of the system error codes.

Return code Description:

ERROR_INVALID_PARAMETER
A parameter is incorrect.
ERROR_NO_SUCH_DOMAIN
The specified domain did not exist.
NERR_SetupAlreadyJoined
The computer is already joined to a domain.
NERR_InvalidWorkgroupName
The specified workgroup name is not valid.

Tips & Tricks:

To join a machine to a domain the same way that netdom.exe does, use the flags NETSETUP_JOIN_DOMAIN and NETSETUP_ACCT_CREATE. (I determined this by using a debugger to watch which flags netdom used.)

NOTE
If the machine is already in a domain use (JoinOptions.NETSETUP_JOIN_DOMAIN + JoinOptions.NETSETUP_DOMAIN_JOIN_IF_JOINED). JoinOptions.NETSETUP_DOMAIN_JOIN_IF_JOINED used on it's own always returns NERR_SetupAlreadyJoined.

Sample Code:

C# Sample:

    public class join
    {

    [DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
    static extern uint NetJoinDomain(
      string lpServer,
      string lpDomain,
      string lpAccountOU,
      string lpAccount,
      string lpPassword,
      JoinOptions NameType);

    [Flags]
    enum JoinOptions
    {
        NETSETUP_JOIN_DOMAIN = 0x00000001,
        NETSETUP_ACCT_CREATE = 0x00000002,
        NETSETUP_ACCT_DELETE = 0x00000004,
        NETSETUP_WIN9X_UPGRADE = 0x00000010,
        NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020,
        NETSETUP_JOIN_UNSECURE = 0x00000040,
        NETSETUP_MACHINE_PWD_PASSED = 0x00000080,
        NETSETUP_DEFER_SPN_SET = 0x10000000
    }

    public static uint domainjoin(string server, string domain, string OU, string account, string password)
    {
        try
        {
        uint value1 = NetJoinDomain(server, domain, OU, account, password, (JoinOptions.NETSETUP_JOIN_DOMAIN | JoinOptions.NETSETUP_DOMAIN_JOIN_IF_JOINED | JoinOptions.NETSETUP_ACCT_CREATE));
        return value1;
        }
        catch (Exception e)
        {
        MessageBox.Show(e.Message);
        return 11;
        }
    }
    }

Alternative Managed API:

Do you know one? Please contribute it!

Documentation