using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Vanara.Extensions; using Vanara.InteropServices; namespace Vanara.PInvoke { public static partial class NetApi32 { /// /// Specifies the possible ways that a device can be joined to Microsoft Azure Active Directory. /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/ne-lmjoin-_dsreg_join_type typedef enum _DSREG_JOIN_TYPE { // DSREG_UNKNOWN_JOIN, DSREG_DEVICE_JOIN, DSREG_WORKPLACE_JOIN } DSREG_JOIN_TYPE, *PDSREG_JOIN_TYPE; [PInvokeData("lmjoin.h", MSDNShortId = "E29BCBE0-222F-4CA8-97BC-6FE1B6F97A67")] public enum DSREG_JOIN_TYPE { /// The type of join is not known. DSREG_UNKNOWN_JOIN, /// The device is joined to Azure Active Directory (Azure AD). DSREG_DEVICE_JOIN, /// An Azure AD work account is added on the device. DSREG_WORKPLACE_JOIN, } /// The type of the name queried in NetEnumerateComputerNames. [PInvokeData("lmjoin.h", MSDNShortId = "c657ae33-404e-4c36-a956-5fbcfa540be7")] public enum NET_COMPUTER_NAME_TYPE { /// The primary computer name. NetPrimaryComputerName, /// Alternate computer names. NetAlternateComputerNames, /// All computer names. NetAllComputerNames, /// Indicates the end of the range that specifies the possible values for the type of name to be queried. NetComputerNameTypeMax } /// A set of bit flags defining domain join options. [PInvokeData("lmjoin.h", MSDNShortId = "4efcb399-03af-4312-9f1d-6bc38f356cac")] [Flags] public enum NETSETUP { /// Joins the computer to a domain. If this value is not specified, joins the computer to a workgroup. NETSETUP_JOIN_DOMAIN = 0x00000001, /// Creates the account on the domain. NETSETUP_ACCT_CREATE = 0x00000002, /// The account is disabled when the unjoin occurs. NETSETUP_ACCT_DELETE = 0x00000004, /// The join operation is occurring as part of an upgrade. NETSETUP_WIN9X_UPGRADE = 0x00000010, /// Allows a join to a new domain even if the computer is already joined to a domain. NETSETUP_DOMAIN_JOIN_IF_JOINED = 0x00000020, /// /// Performs an unsecured join. /// /// This option requests a domain join to a pre-created account without authenticating with domain user credentials. This option /// can be used in conjunction with NETSETUP_MACHINE_PWD_PASSED option. In this case, lpPassword is the password of the /// pre-created machine account. /// /// /// Prior to Windows Vista with SP1 and Windows Server 2008, an unsecure join did not authenticate to the domain controller. All /// communication was performed using a null (unauthenticated) session.Starting with Windows Vista with SP1 and Windows Server /// 2008, the machine account name and password are used to authenticate to the domain controller. /// /// NETSETUP_JOIN_UNSECURE = 0x00000040, /// /// Indicates that the lpPassword parameter specifies a local machine account password rather than a user password. This flag is /// valid only for unsecured joins, which you must indicate by also setting the NETSETUP_JOIN_UNSECURE flag. /// /// If you set this flag, then after the join operation succeeds, the machine password will be set to the value of lpPassword, if /// that value is a valid machine password. /// /// NETSETUP_MACHINE_PWD_PASSED = 0x00000080, /// /// Indicates that the service principal name (SPN) and the DnsHostName properties on the computer object should not be updated /// at this time. /// /// Typically, these properties are updated during the join operation. Instead, these properties should be updated during a /// subsequent call to the NetRenameMachineInDomain function. These properties are always updated during the rename operation. /// For more information, see the following Remarks section. /// /// NETSETUP_DEFER_SPN_SET = 0x00000100, /// /// Allow the domain join if existing account is a domain controller. This flag is supported on Windows Vista /// and later. /// NETSETUP_JOIN_DC_ACCOUNT = 0x00000200, /// /// Join the target machine specified in lpServer parameter with a new name queried from the registry on the machine specified in /// the lpServer parameter. /// /// This option is used if SetComputerNameEx has been called prior to rebooting the machine. The new computer name will not take /// effect until a reboot.With this option, the caller instructs the NetJoinDomain function to use the new name during the domain /// join operation.A reboot is required after calling NetJoinDomain successfully at which time both the computer name change and /// domain membership change will have taken affect. /// /// This flag is supported on Windows Vista and later. /// NETSETUP_JOIN_WITH_NEW_NAME = 0x00000400, /// /// Join the target machine specified in lpServer parameter using a pre-created account without requiring a writable domain controller. /// /// This option provides the ability to join a machine to domain if an account has already been provisioned and replicated to a /// read-only domain controller. The target read-only domain controller is specified as part of the lpDomain parameter, after the /// domain name delimited by a ‘\’ character. This provisioning must include the machine secret. The machine account must be /// added via group membership into the allowed list for password replication policy, and the account password must be replicated /// to the read-only domain controller prior to the join operation. For more information, see the information on Password /// Replication Policy Administration. /// /// /// Starting with Windows 7, an alternate mechanism is to use the offline domain join mechanism. For more information, see the /// NetProvisionComputerAccount and NetRequestOfflineDomainJoin functions. /// /// This flag is supported on Windows Vista and later. /// NETSETUP_JOIN_READONLY = 0x00000800, /// Limits any updates to DNS-based names only. NETSETUP_DNS_NAME_CHANGES_ONLY = 0x00001000, /// Indicates that the protocol method was invoked during installation. NETSETUP_INSTALL_INVOCATION = 0x00040000, /// /// When joining the domain don't try to set the preferred domain controller in the registry. This flag is /// supported on Windows 7, Windows Server 2008 R2, and later. /// NETSETUP_AMBIGUOUS_DC = 0x00001000, /// /// When joining the domain don't create the Netlogon cache. This flag is supported on Windows 7, Windows /// Server 2008 R2, and later. /// NETSETUP_NO_NETLOGON_CACHE = 0x00002000, /// /// When joining the domain don't force Netlogon service to start. This flag is supported on Windows 7, Windows /// Server 2008 R2, and later. /// NETSETUP_DONT_CONTROL_SERVICES = 0x00004000, /// /// When joining the domain for offline join only, set target machine hostname and NetBIOS name. This flag is /// supported on Windows 7, Windows Server 2008 R2, and later. /// NETSETUP_SET_MACHINE_NAME = 0x00008000, /// /// When joining the domain, override other settings during domain join and set the service principal name (SPN). /// This flag is supported on Windows 7, Windows Server 2008 R2, and later. /// NETSETUP_FORCE_SPN_SET = 0x00010000, /// /// When joining the domain, do not reuse an existing account. This flag is supported on Windows 7, Windows /// Server 2008 R2, and later. /// NETSETUP_NO_ACCT_REUSE = 0x00020000, /// Undocumented. NETSETUP_ALT_SAMACCOUNTNAME = 0x00020000, /// /// If this bit is set, unrecognized flags will be ignored by the NetJoinDomain function and NetJoinDomain will behave as if the /// flags were not set. /// NETSETUP_IGNORE_UNSUPPORTED_FLAGS = 0x10000000, /// Valid unjoin flags. NETSETUP_VALID_UNJOIN_FLAGS = NETSETUP_ACCT_DELETE | NETSETUP_IGNORE_UNSUPPORTED_FLAGS | NETSETUP_JOIN_DC_ACCOUNT, /// Undocumented. NETSETUP_PROCESS_OFFLINE_FLAGS = NETSETUP_JOIN_DOMAIN | NETSETUP_DOMAIN_JOIN_IF_JOINED | NETSETUP_JOIN_WITH_NEW_NAME | NETSETUP_DONT_CONTROL_SERVICES | NETSETUP_MACHINE_PWD_PASSED, } /// The join status of the specified computer. [PInvokeData("lmjoin.h", MSDNShortId = "c7cc1cf2-4530-4039-806b-fbee572f564d")] public enum NETSETUP_JOIN_STATUS { /// The status is unknown. NetSetupUnknownStatus = 0, /// The computer is not joined. NetSetupUnjoined, /// The computer is joined to a workgroup. NetSetupWorkgroupName, /// The computer is joined to a domain. NetSetupDomainName } /// The type of the name passed in the lpName parameter of to validate. [PInvokeData("lmjoin.h", MSDNShortId = "772603df-ec17-4a83-a715-2d9a14d5c2bb")] public enum NETSETUP_NAME_TYPE { /// The nametype is unknown. If this value is used, the NetValidateName function fails with ERROR_INVALID_PARAMETER. NetSetupUnknown = 0, /// Verify that the NetBIOS computer name is valid and that it is not in use. NetSetupMachine, /// Verify that the workgroup name is valid. NetSetupWorkgroup, /// Verify that the domain name exists and that it is a domain. NetSetupDomain, /// Verify that the domain name is not in use. NetSetupNonExistentDomain, /// /// Verify that the DNS computer name is valid. /// /// This value is supported on Windows 2000 and later. The application must be compiled with _WIN32_WINNT >= 0x0500 to use /// this value. /// /// NetSetupDnsMachine } /// Bit flags that define provisioning options. [PInvokeData("lmjoin.h", MSDNShortId = "4c854258-b84d-4ef3-a6da-ce0a9540ffd5")] [Flags] public enum NETSETUP_PROVISION : uint { /// /// If the caller requires account creation by privilege, this option will cause a retry on failure using account creation /// functions enabling interoperability with domain controllers running on earlier versions of Windows. /// The lpMachineAccountOU is not supported when using downlevel privilege support. /// NETSETUP_PROVISION_DOWNLEVEL_PRIV_SUPPORT = 0x00000001, /// /// If the named account already exists, an attempt will be made to reuse the existing account. /// This option requires sufficient credentials for this operation (Domain Administrator or the object owner). /// NETSETUP_PROVISION_REUSE_ACCOUNT = 0x00000002, /// /// Use the default machine account password which is the machine name in lowercase. This is largely to support the older /// unsecure join model where the pre-created account typically used this default password. Applications should /// avoid using this option if possible.This option as well as NetJoinDomain function with dwOptions set to /// NETSETUP_JOIN_UNSECURE for unsecure join should only be used on earlier versions of Windows. /// NETSETUP_PROVISION_USE_DEFAULT_PASSWORD = 0x00000004, /// /// Do not try to find the account on any domain controller in the domain. This option makes the operation faster, but should /// only be used when the caller is certain that an account by the same name hasn't recently been created. /// /// This option is only valid when the lpDcName parameter is specified. When the prerequisites are met, this option allows for /// must faster provisioning useful for scenarios such as batch processing. /// /// NETSETUP_PROVISION_SKIP_ACCOUNT_SEARCH = 0x00000008, /// /// This option retrieves all of the root Certificate Authority certificates on the local machine and adds them to the /// provisioning package when no certificate template names are provided as part of the provisioning package (the /// aCertTemplateNames member of the NETSETUP_PROVISIONING_PARAMS struct passed in the pProvisioningParams parameter to the /// NetCreateProvisioningPackage function is NULL). This flag is only supported by the /// NetCreateProvisioningPackage function on Windows 8, Windows Server 2012, and later. /// NETSETUP_PROVISION_ROOT_CA_CERTS = 0x00000010, /// Undocumented. NETSETUP_PROVISION_PERSISTENTSITE = 0x00000020, /// /// This flag is required if the lpWindowsPath parameter references the currently running Windows operating system directory /// rather than an offline Windows operating system image mounted on an accessible volume. If this flag is specified, the /// NetRequestProvisioningPackageInstall function must be invoked by a member of the local Administrators group. /// NETSETUP_PROVISION_ONLINE_CALLER = 0x40000000, /// Undocumented. NETSETUP_PROVISION_CHECK_PWD_ONLY = 0x80000000, } /// The NetAddAlternateComputerName function adds an alternate name for the specified computer. /// /// A pointer to a constant string that specifies the name of the computer on which to execute this function. If this parameter is /// NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the alternate name to add. This name must be in the form of a fully qualified DNS name. /// /// /// /// A pointer to a constant string that specifies the domain account to use for accessing the machine account object for the computer /// specified in the Server parameter in Active Directory. If this parameter is NULL, then the credentials of the user /// executing this routine are used. /// /// This parameter is not used if the server to execute this function is not joined to a domain. /// /// /// /// A pointer to a constant string that specifies the password matching the domain account passed in the DomainAccount parameter. If /// this parameter is NULL, then the credentials of the user executing this routine are used. /// /// /// This parameter is ignored if the DomainAccount parameter is NULL. This parameter is not used if the server to execute this /// function is not joined to a domain. /// /// /// Reserved for future use. This parameter should be NULL. /// /// 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_ACCESS_DENIED /// /// Access is denied. This error is returned if the caller was not a member of the Administrators local group on the target computer. /// /// /// /// ERROR_INVALID_NAME /// A name parameter is incorrect. This error is returned if the AlternateName parameter does not contain valid name. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the DomainAccount parameter does not contain a valid domain. This error is /// also returned if the DomainAccount parameter is not NULL and the DomainAccountPassword parameter is not NULL but does not contain /// a Unicode string. /// /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory is available to process this command. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the target computer specified in the Server parameter on which this /// function executes is running on Windows 2000 and earlier. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// The NetAddAlternateComputerName function is supported on Windows XP and later. /// /// The NetAddAlternateComputerName function is used to set secondary network names for computers. The primary name is the /// name used for authentication and maps to the machine account name. /// /// /// The NetAddAlternateComputerName function requires that the caller is a member of the Administrators local group on the /// target computer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netaddalternatecomputername NET_API_STATUS NET_API_FUNCTION // NetAddAlternateComputerName( LPCWSTR Server, LPCWSTR AlternateName, LPCWSTR DomainAccount, LPCWSTR DomainAccountPassword, ULONG // Reserved ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "710865c6-e327-439c-931d-de8674d69233")] public static extern Win32Error NetAddAlternateComputerName([Optional] string Server, string AlternateName, [Optional] string DomainAccount, [Optional] string DomainAccountPassword, uint Reserved = 0); /// /// The NetCreateProvisioningPackage function creates a provisioning package that provisions a computer account for later use in an /// offline domain join operation. The package may also contain information about certificates and policies to add to the machine /// during provisioning. /// /// /// A pointer to a NETSETUP_PROVISIONING_PARAMS structure that contains information about the provisioning package. /// The following values are defined for the members of this structure: /// /// /// Value /// Meaning /// /// /// dwVersion /// /// The version of Windows in the provisioning package. This member should use the following value defined in the Lmjoin.h header /// file: NETSETUP_PROVISIONING_PARAMS_CURRENT_VERSION (0x00000001) /// /// /// /// lpDomain /// /// A pointer to a constant null-terminated character string that specifies the name of the domain where the computer account is created. /// /// /// /// lpMachineName /// /// A pointer to a constant null-terminated character string that specifies the short name of the machine from which the computer /// account attribute sAMAccountName is derived by appending a '$'. This parameter must contain a valid DNS or NetBIOS machine name. /// /// /// /// lpMachineAccountOU /// /// An optional pointer to a constant null-terminated character string that contains the RFC 1779 format name of the organizational /// unit (OU) where the computer account will be created. If you specify this parameter, the string must contain a full path, for /// example, OU=testOU,DC=domain,DC=Domain,DC=com. Otherwise, this parameter must be NULL. If this parameter is NULL, the well known /// computer object container will be used as published in the domain. /// /// /// /// lpDcName /// /// An optional pointer to a constant null-terminated character string that contains the name of the domain controller to target. /// /// /// /// dwProvisionOptions /// /// A set of bit flags that define provisioning options. This parameter can be one or more of the values specified for the dwOptions /// parameter passed to the NetProvisionComputerAccount function. These possible values are defined in the Lmjoin.h header file. The /// NETSETUP_PROVISION_ROOT_CA_CERTS option is only supported on Windows 8 and Windows Server 2012. /// /// /// /// aCertTemplateNames /// A optional pointer to an array of NULL-terminated certificate template names. /// /// /// cCertTemplateNames /// When aCertTemplateNames is not NULL, this member provides an explicit count of the number of items in the array. /// /// /// aMachinePolicyNames /// An optional pointer to an array of NULL-terminated machine policy names. /// /// /// cMachinePolicyNames /// When aMachinePolicyNames is not NULL, this member provides an explicit count of the number of items in the array. /// /// /// aMachinePolicyPaths /// /// An optional pointer to an array of character strings. Each array element is a NULL-terminated character string which specifies /// the full or partial path to a file in the Registry Policy File format. For more information on the Registry Policy File Format , /// see Registry Policy File Format The path could be a UNC path on a remote server. /// /// /// /// cMachinePolicyPaths /// When aMachinePolicyPaths is not NULL, this member provides an explicit count of the number of items in the array. /// /// /// /// /// /// An optional pointer that will receive the package required by NetRequestOfflineDomainJoin function to complete an offline domain /// join, if the NetProvisionComputerAccount function completes successfully. The data is returned as an opaque binary buffer which /// may be passed to NetRequestOfflineDomainJoin function. /// /// /// If this parameter is NULL, then pPackageTextData parameter must not be NULL. If this parameter is not NULL, /// then the pPackageTextData parameter must be NULL. /// /// /// /// A pointer to a value that receives the size, in bytes, of the buffer returned in the pProvisionBinData parameter. /// /// This parameter must not be NULL if the pPackageBinData parameter is not NULL. This parameter must be NULL /// when the pPackageBinData parameter is NULL. /// /// /// /// /// An optional pointer that will receive the package required by NetRequestOfflineDomainJoin function to complete an offline domain /// join, if the NetProvisionComputerAccount function completes successfully. The data is returned in string form for embedding in an /// unattended setup answer file. /// /// /// If this parameter is NULL, then the pPackageBinData parameter must not be NULL. If this parameter is not /// NULL, then the the pPackageBinData parameter must be NULL. /// /// /// /// 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_ACCESS_DENIED /// Access is denied. This error is returned if the caller does not have sufficient privileges to complete the operation. /// /// /// ERROR_INVALID_DOMAIN_ROLE /// /// This operation is only allowed for the Primary Domain Controller of the domain. This error is returned if a domain controller /// name was specified in the lpDcName of the NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams parameter, /// but the computer specified could not be validated as a domain controller for the target domain specified in the lpDomain of the NETSETUP_PROVISIONING_PARAMS. /// /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is also returned if both the pProvisioningParams parameter is NULL. This error is also /// returned if the lpDomain or lpMachineName member of the NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams /// parameter is NULL. /// /// /// /// ERROR_NO_SUCH_DOMAIN /// The specified domain did not exist. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the lpMachineAccountOU member was specified in the /// NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams parameter and the domain controller is running on an /// earlier versions of Windows that does not support this parameter. /// /// /// /// NERR_DS8DCRequired /// The specified domain controller does not meet the version requirement for this operation. /// /// /// NERR_LDAPCapableDCRequired /// This operation requires a domain controller which supports LDAP. /// /// /// NERR_UserExists /// /// The account already exists in the domain and the NETSETUP_PROVISION_REUSE_ACCOUNT bit was not specified in the dwProvisionOptions /// member of the NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams parameter. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// /// The NetCreateProvisioningPackage function is supported on Windows 8 and Windows Server 2012 for offline join operations. /// For Windows 7, use the NetProvisionComputerAccount function. /// /// /// The NetCreateProvisioningPackage function is used to provision a computer account for later use in an offline domain join /// operation using the NetRequestProvisioningPackageInstall function. /// /// The offline domain join scenario uses two functions: /// /// /// /// NetCreateProvisioningPackage is a provisioning function that is first called to perform the network operations necessary /// to create and configure the computer object in Active Directory. The output from the NetCreateProvisioningPackage is a /// package used for the next step. /// /// /// /// /// NetRequestProvisioningPackageInstall, an image initialization function, is called to inject the output from the /// NetCreateProvisioningPackage provisioning function into a Windows operating system image for use during pre-installation /// and post-installation. /// /// /// /// Changes to Windows initialization code will detect this saved state and affect the local-only portion of domain join. /// /// When the pPackageBinData and pdwPackageBinDataSize out pointers are used, set the pPackageTextData out pointer to NULL. When /// pPackageTextData is used, set the pPackageBinData and pdwPackageBinDataSize out pointers to NULL. /// /// /// The pProvisioningParams parameter specifies data to include in the provisioning package. The package includes information /// relevant to the domain join, and it can also include information about policies and certificates to install on the machine. The /// provisioning package can be used in four ways: /// /// /// /// Domain join /// /// /// Domain join and installation of certificates /// /// /// Domain join and installation of policies /// /// /// Domain join and installation of certificates and policies /// /// /// /// The NetCreateProvisioningPackage function creates or reuses the machine account in the domain, collects all necessary /// metadata and returns it in a package. The package can be consumed by the offline domain join request operation supplying all the /// necessary input to complete the domain join during first boot without any network operations (local state updates only). /// /// /// Security Note: The package returned by the NetCreateProvisioningPackage function contains very sensitive data. It /// should be treated just as securely as a plaintext password. The package contains the machine account password and other /// information about the domain, including the domain name, the name of a domain controller, and the security ID (SID) of the /// domain. If the package is being transported physically or over the network, care must be taken to transport it securely. The /// design makes no provisions for securing this data. This problem exists today with unattended setup answer files which can carry a /// number of secrets including domain user passwords. The caller must secure the package. Solutions to this problem are varied. As /// an example, a pre-exchanged key could be used to encrypt a session between the consumer and provisioning entity enabling a secure /// transfer of the package. /// /// /// The package returned in the pPackageBinData parameter by the NetCreateProvisioningPackage function is versioned to allow /// interoperability and serviceability scenarios between different versions of Windows (such as joining a client, provisioning a /// machine, and using a domain controller). A package created on Windows 8 or Windows Server 2012 can be used Windows 7 or Windows /// Server 2008 R2, however only domain join information will take effect (certificates and policies are not supported). The offline /// join scenario currently does not limit the lifetime of the package returned by the NetCreateProvisioningPackage function. /// /// /// For offline domain joins, the access check performed depends on the configuration of the domain. Computer account creation is /// enabled using three methods: /// /// /// /// Domain administrators have rights to create computer accounts. /// /// /// The SD on a container can delegate the rights to create computer accounts. /// /// /// /// By default, authenticated users may create computer accounts by privilege. Authenticated users are limited to creating a limited /// number of accounts that is specified as a quota on the domain (the default value is 10). For more information, see the /// ms-DS-MachineAccountQuota attribute in the Active Directory schema. /// /// /// /// /// The NetCreateProvisioningPackage function works only with a writable domain controller and does not function against a /// read-only domain controller. Once provisioning is done against a writable domain controller and the account is replicated to a /// read-only domain controller, the other portions of the offline domain join operation do not require access to a domain controller. /// /// /// If the NetCreateProvisioningPackage function is successful, the pointer in the pPackageBinData or pPackageTextData /// parameter (depending on which parameter was not NULL) is returned with the serialized data for use in an offline join /// operation or as text in an unattended setup file. /// /// /// All phases of the provisioning process append to a NetSetup.log file on the local computer. The provisoning process can include /// up to three different computers: the computer where the provisioning package is created, the computer that requests the /// installation of the package, and the computer where the package is installed. There will be NetSetup.log file information stored /// on all three computers according to the operation performed. Reviewing the contents of these files is the most common means of /// troubleshooting online and offline provisioning errors. Provisioning operations undertaken by admins are logged to the /// NetSetup.log file in the %WINDIR%\Debug. Provisioning operations performed by non-admins are logged to the NetSetup.log file in /// the %USERPROFILE%\Debug folder. /// /// For more information on offline domain join operations, see the Offline Domain Join Step-by-Step Guide. /// /// Joining (and unjoining) a computer to a domain using NetJoinDomain and NetUnjoinDomain is performed only by a member of the /// Administrators local group on the target computer. Note that the domain administrator can set additional requirements for joining /// the domain using delegation and assignment of privileges. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netcreateprovisioningpackage NET_API_STATUS NET_API_FUNCTION // NetCreateProvisioningPackage( PNETSETUP_PROVISIONING_PARAMS pProvisioningParams, PBYTE *ppPackageBinData, DWORD // *pdwPackageBinDataSize, LPWSTR *ppPackageTextData ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "6E2A5578-8308-41E2-B5E9-5E34E9E76C0B")] public static extern Win32Error NetCreateProvisioningPackage(ref NETSETUP_PROVISIONING_PARAMS pProvisioningParams, out IntPtr ppPackageBinData, out uint pdwPackageBinDataSize, IntPtr ppPackageTextData = default); /// /// The NetCreateProvisioningPackage function creates a provisioning package that provisions a computer account for later use in an /// offline domain join operation. The package may also contain information about certificates and policies to add to the machine /// during provisioning. /// /// /// A pointer to a NETSETUP_PROVISIONING_PARAMS structure that contains information about the provisioning package. /// The following values are defined for the members of this structure: /// /// /// Value /// Meaning /// /// /// dwVersion /// /// The version of Windows in the provisioning package. This member should use the following value defined in the Lmjoin.h header /// file: NETSETUP_PROVISIONING_PARAMS_CURRENT_VERSION (0x00000001) /// /// /// /// lpDomain /// /// A pointer to a constant null-terminated character string that specifies the name of the domain where the computer account is created. /// /// /// /// lpMachineName /// /// A pointer to a constant null-terminated character string that specifies the short name of the machine from which the computer /// account attribute sAMAccountName is derived by appending a '$'. This parameter must contain a valid DNS or NetBIOS machine name. /// /// /// /// lpMachineAccountOU /// /// An optional pointer to a constant null-terminated character string that contains the RFC 1779 format name of the organizational /// unit (OU) where the computer account will be created. If you specify this parameter, the string must contain a full path, for /// example, OU=testOU,DC=domain,DC=Domain,DC=com. Otherwise, this parameter must be NULL. If this parameter is NULL, the well known /// computer object container will be used as published in the domain. /// /// /// /// lpDcName /// /// An optional pointer to a constant null-terminated character string that contains the name of the domain controller to target. /// /// /// /// dwProvisionOptions /// /// A set of bit flags that define provisioning options. This parameter can be one or more of the values specified for the dwOptions /// parameter passed to the NetProvisionComputerAccount function. These possible values are defined in the Lmjoin.h header file. The /// NETSETUP_PROVISION_ROOT_CA_CERTS option is only supported on Windows 8 and Windows Server 2012. /// /// /// /// aCertTemplateNames /// A optional pointer to an array of NULL-terminated certificate template names. /// /// /// cCertTemplateNames /// When aCertTemplateNames is not NULL, this member provides an explicit count of the number of items in the array. /// /// /// aMachinePolicyNames /// An optional pointer to an array of NULL-terminated machine policy names. /// /// /// cMachinePolicyNames /// When aMachinePolicyNames is not NULL, this member provides an explicit count of the number of items in the array. /// /// /// aMachinePolicyPaths /// /// An optional pointer to an array of character strings. Each array element is a NULL-terminated character string which specifies /// the full or partial path to a file in the Registry Policy File format. For more information on the Registry Policy File Format , /// see Registry Policy File Format The path could be a UNC path on a remote server. /// /// /// /// cMachinePolicyPaths /// When aMachinePolicyPaths is not NULL, this member provides an explicit count of the number of items in the array. /// /// /// /// /// /// An optional pointer that will receive the package required by NetRequestOfflineDomainJoin function to complete an offline domain /// join, if the NetProvisionComputerAccount function completes successfully. The data is returned as an opaque binary buffer which /// may be passed to NetRequestOfflineDomainJoin function. /// /// /// If this parameter is NULL, then pPackageTextData parameter must not be NULL. If this parameter is not NULL, /// then the pPackageTextData parameter must be NULL. /// /// /// /// A pointer to a value that receives the size, in bytes, of the buffer returned in the pProvisionBinData parameter. /// /// This parameter must not be NULL if the pPackageBinData parameter is not NULL. This parameter must be NULL /// when the pPackageBinData parameter is NULL. /// /// /// /// /// An optional pointer that will receive the package required by NetRequestOfflineDomainJoin function to complete an offline domain /// join, if the NetProvisionComputerAccount function completes successfully. The data is returned in string form for embedding in an /// unattended setup answer file. /// /// /// If this parameter is NULL, then the pPackageBinData parameter must not be NULL. If this parameter is not /// NULL, then the the pPackageBinData parameter must be NULL. /// /// /// /// 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_ACCESS_DENIED /// Access is denied. This error is returned if the caller does not have sufficient privileges to complete the operation. /// /// /// ERROR_INVALID_DOMAIN_ROLE /// /// This operation is only allowed for the Primary Domain Controller of the domain. This error is returned if a domain controller /// name was specified in the lpDcName of the NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams parameter, /// but the computer specified could not be validated as a domain controller for the target domain specified in the lpDomain of the NETSETUP_PROVISIONING_PARAMS. /// /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is also returned if both the pProvisioningParams parameter is NULL. This error is also /// returned if the lpDomain or lpMachineName member of the NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams /// parameter is NULL. /// /// /// /// ERROR_NO_SUCH_DOMAIN /// The specified domain did not exist. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the lpMachineAccountOU member was specified in the /// NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams parameter and the domain controller is running on an /// earlier versions of Windows that does not support this parameter. /// /// /// /// NERR_DS8DCRequired /// The specified domain controller does not meet the version requirement for this operation. /// /// /// NERR_LDAPCapableDCRequired /// This operation requires a domain controller which supports LDAP. /// /// /// NERR_UserExists /// /// The account already exists in the domain and the NETSETUP_PROVISION_REUSE_ACCOUNT bit was not specified in the dwProvisionOptions /// member of the NETSETUP_PROVISIONING_PARAMS struct pointed to by the pProvisioningParams parameter. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// /// The NetCreateProvisioningPackage function is supported on Windows 8 and Windows Server 2012 for offline join operations. /// For Windows 7, use the NetProvisionComputerAccount function. /// /// /// The NetCreateProvisioningPackage function is used to provision a computer account for later use in an offline domain join /// operation using the NetRequestProvisioningPackageInstall function. /// /// The offline domain join scenario uses two functions: /// /// /// /// NetCreateProvisioningPackage is a provisioning function that is first called to perform the network operations necessary /// to create and configure the computer object in Active Directory. The output from the NetCreateProvisioningPackage is a /// package used for the next step. /// /// /// /// /// NetRequestProvisioningPackageInstall, an image initialization function, is called to inject the output from the /// NetCreateProvisioningPackage provisioning function into a Windows operating system image for use during pre-installation /// and post-installation. /// /// /// /// Changes to Windows initialization code will detect this saved state and affect the local-only portion of domain join. /// /// When the pPackageBinData and pdwPackageBinDataSize out pointers are used, set the pPackageTextData out pointer to NULL. When /// pPackageTextData is used, set the pPackageBinData and pdwPackageBinDataSize out pointers to NULL. /// /// /// The pProvisioningParams parameter specifies data to include in the provisioning package. The package includes information /// relevant to the domain join, and it can also include information about policies and certificates to install on the machine. The /// provisioning package can be used in four ways: /// /// /// /// Domain join /// /// /// Domain join and installation of certificates /// /// /// Domain join and installation of policies /// /// /// Domain join and installation of certificates and policies /// /// /// /// The NetCreateProvisioningPackage function creates or reuses the machine account in the domain, collects all necessary /// metadata and returns it in a package. The package can be consumed by the offline domain join request operation supplying all the /// necessary input to complete the domain join during first boot without any network operations (local state updates only). /// /// /// Security Note: The package returned by the NetCreateProvisioningPackage function contains very sensitive data. It /// should be treated just as securely as a plaintext password. The package contains the machine account password and other /// information about the domain, including the domain name, the name of a domain controller, and the security ID (SID) of the /// domain. If the package is being transported physically or over the network, care must be taken to transport it securely. The /// design makes no provisions for securing this data. This problem exists today with unattended setup answer files which can carry a /// number of secrets including domain user passwords. The caller must secure the package. Solutions to this problem are varied. As /// an example, a pre-exchanged key could be used to encrypt a session between the consumer and provisioning entity enabling a secure /// transfer of the package. /// /// /// The package returned in the pPackageBinData parameter by the NetCreateProvisioningPackage function is versioned to allow /// interoperability and serviceability scenarios between different versions of Windows (such as joining a client, provisioning a /// machine, and using a domain controller). A package created on Windows 8 or Windows Server 2012 can be used Windows 7 or Windows /// Server 2008 R2, however only domain join information will take effect (certificates and policies are not supported). The offline /// join scenario currently does not limit the lifetime of the package returned by the NetCreateProvisioningPackage function. /// /// /// For offline domain joins, the access check performed depends on the configuration of the domain. Computer account creation is /// enabled using three methods: /// /// /// /// Domain administrators have rights to create computer accounts. /// /// /// The SD on a container can delegate the rights to create computer accounts. /// /// /// /// By default, authenticated users may create computer accounts by privilege. Authenticated users are limited to creating a limited /// number of accounts that is specified as a quota on the domain (the default value is 10). For more information, see the /// ms-DS-MachineAccountQuota attribute in the Active Directory schema. /// /// /// /// /// The NetCreateProvisioningPackage function works only with a writable domain controller and does not function against a /// read-only domain controller. Once provisioning is done against a writable domain controller and the account is replicated to a /// read-only domain controller, the other portions of the offline domain join operation do not require access to a domain controller. /// /// /// If the NetCreateProvisioningPackage function is successful, the pointer in the pPackageBinData or pPackageTextData /// parameter (depending on which parameter was not NULL) is returned with the serialized data for use in an offline join /// operation or as text in an unattended setup file. /// /// /// All phases of the provisioning process append to a NetSetup.log file on the local computer. The provisoning process can include /// up to three different computers: the computer where the provisioning package is created, the computer that requests the /// installation of the package, and the computer where the package is installed. There will be NetSetup.log file information stored /// on all three computers according to the operation performed. Reviewing the contents of these files is the most common means of /// troubleshooting online and offline provisioning errors. Provisioning operations undertaken by admins are logged to the /// NetSetup.log file in the %WINDIR%\Debug. Provisioning operations performed by non-admins are logged to the NetSetup.log file in /// the %USERPROFILE%\Debug folder. /// /// For more information on offline domain join operations, see the Offline Domain Join Step-by-Step Guide. /// /// Joining (and unjoining) a computer to a domain using NetJoinDomain and NetUnjoinDomain is performed only by a member of the /// Administrators local group on the target computer. Note that the domain administrator can set additional requirements for joining /// the domain using delegation and assignment of privileges. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netcreateprovisioningpackage NET_API_STATUS NET_API_FUNCTION // NetCreateProvisioningPackage( PNETSETUP_PROVISIONING_PARAMS pProvisioningParams, PBYTE *ppPackageBinData, DWORD // *pdwPackageBinDataSize, LPWSTR *ppPackageTextData ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "6E2A5578-8308-41E2-B5E9-5E34E9E76C0B")] public static extern Win32Error NetCreateProvisioningPackage(ref NETSETUP_PROVISIONING_PARAMS pProvisioningParams, [Optional] IntPtr ppPackageBinData, [Optional] IntPtr pdwPackageBinDataSize, ref StringBuilder ppPackageTextData); /// The NetEnumerateComputerNames function enumerates names for the specified computer. /// /// A pointer to a constant string that specifies the name of the computer on which to execute this function. If this parameter is /// NULL, the local computer is used. /// /// /// /// The type of the name queried. This member can be one of the following values defined in the NET_COMPUTER_NAME_TYPE /// enumeration defined in the Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NetPrimaryComputerName /// The primary computer name. /// /// /// NetAlternateComputerNames /// Alternate computer names. /// /// /// NetAllComputerNames /// All computer names. /// /// /// NetComputerNameTypeMax /// Indicates the end of the range that specifies the possible values for the type of name to be queried. /// /// /// /// Reserved for future use. This parameter should be NULL. /// /// A pointer to a DWORD value that returns the number of names returned in the buffer pointed to by the ComputerNames parameter if /// the function succeeds. /// /// /// /// A pointer to an array of pointers to names. If the function call is successful, this parameter will return the computer names /// that match the computer type name specified in the NameType parameter. /// /// When the application no longer needs this array, this buffer should be freed by calling NetApiBufferFree function. /// /// /// 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_ACCESS_DENIED /// /// Access is denied. This error is returned if the caller was not a member of the Administrators local group on the target computer. /// /// /// /// ERROR_INVALID_PARAMETER /// A parameter is incorrect. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory is available to process this command. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the target computer specified in the Server parameter on which this /// function executes is running on Windows 2000 and earlier. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// The NetEnumerateComputerNames function is supported on Windows Vista and later. /// The NetEnumerateComputerNames function is used to request the names a computer currently has configured. /// /// The NetEnumerateComputerNames function requires that the caller is a member of the Administrators local group on the /// target computer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netenumeratecomputernames NET_API_STATUS NET_API_FUNCTION // NetEnumerateComputerNames( LPCWSTR Server, NET_COMPUTER_NAME_TYPE NameType, ULONG Reserved, PDWORD EntryCount, LPWSTR // **ComputerNames ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "c657ae33-404e-4c36-a956-5fbcfa540be7")] public static extern Win32Error NetEnumerateComputerNames(string Server, NET_COMPUTER_NAME_TYPE NameType, [Optional] uint Reserved, out uint EntryCount, out SafeNetApiBuffer ComputerNames); /// /// Frees the memory allocated for the specified DSREG_JOIN_INFO structure, which contains join information for a tenant and which /// you retrieved by calling the NetGetAadJoinInformation function. /// /// Pointer to the DSREG_JOIN_INFO structure for which you want to free the memory. // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netfreeaadjoininformation VOID NET_API_FUNCTION // NetFreeAadJoinInformation( PDSREG_JOIN_INFO pJoinInfo ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true)] [PInvokeData("lmjoin.h", MSDNShortId = "BDFB6179-4B8C-43E3-8D34-A2B470EA0D0B")] public static extern void NetFreeAadJoinInformation(HANDLE pJoinInfo); /// /// Retrieves the join information for the specified tenant. This function examines the join information for Microsoft Azure Active /// Directory and the work account that the current user added. /// /// /// /// The tenant identifier for the joined account. If the device is not joined to Azure Active Directory (Azure AD), and the user /// currently logged into Windows added no Azure AD work accounts for the specified tenant, the buffer that the ppJoinInfo parameter /// points to is set to NULL. /// /// /// If the specified tenant ID is NULL or empty, ppJoinInfo is set to the default join account information, or NULL if the device is /// not joined to Azure AD and the current user added no Azure AD work accounts. /// /// /// /// The join information for the tenant that the pcszTenantId parameter specifies. If this parameter is NULL, the device is not /// joined to Azure AD and the current user added no Azure AD work accounts. You must call the NetFreeAadJoinInformation function to /// free the memory allocated for this structure. /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netgetaadjoininformation HRESULT NET_API_FUNCTION // NetGetAadJoinInformation( LPCWSTR pcszTenantId, PDSREG_JOIN_INFO *ppJoinInfo ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true)] [PInvokeData("lmjoin.h", MSDNShortId = "C63B3AA7-FC7E-4CB9-9318-BD25560591AB")] public static extern HRESULT NetGetAadJoinInformation([MarshalAs(UnmanagedType.LPWStr), Optional] string pcszTenantId, out DSREG_JOIN_INFO ppJoinInfo); /// /// The NetGetJoinableOUs function retrieves a list of organizational units (OUs) in which a computer account can be created. /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the computer on which to call the function. If this /// parameter is NULL, the local computer is used. /// Pointer to a constant string that specifies the name of the domain for which to retrieve the list of OUs that can be joined. /// Pointer to a constant string that specifies the account name to use when connecting to the domain controller. The string must /// specify either a domain NetBIOS name and user account (for example, "REDMOND\user") or the user principal name (UPN) of the user /// in the form of an Internet-style login name (for example, "someone@example.com"). If this parameter is NULL, the caller's /// context is used. /// If the lpAccount parameter specifies an account name, this parameter must point to the password to use when connecting to the /// domain controller. Otherwise, this parameter must be NULL. /// Receives the count of OUs returned in the list of joinable OUs. /// Pointer to an array that receives the list of joinable OUs. This array is allocated by the system and must be freed using a /// single call to the NetApiBufferFree function. For more information, see Network Management Function Buffers and Network /// Management Function Buffer Lengths. /// /// 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_NOT_ENOUGH_MEMORY /// Not enough storage is available to process this command. /// /// /// NERR_DefaultJoinRequired /// The destination domain controller does not support creating computer accounts in OUs. /// /// /// /// /// No special group membership is required to successfully execute the NetGetJoinableOUs function. /// For more information about organizational units, see Managing Users in the Active Directory documentation. /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netgetjoinableous NET_API_STATUS NET_API_FUNCTION // NetGetJoinableOUs( LPCWSTR lpServer, LPCWSTR lpDomain, LPCWSTR lpAccount, LPCWSTR lpPassword, DWORD *OUCount, LPWSTR **OUs ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "1faa912b-c56d-431c-95d5-d36790b0d467")] public static extern Win32Error NetGetJoinableOUs([Optional] string lpServer, string lpDomain, [Optional] string lpAccount, [Optional] string lpPassword, out uint OUCount, out SafeNetApiBuffer OUs); /// The NetGetJoinInformation function retrieves join status information for the specified computer. /// /// Pointer to a constant string that specifies the DNS or NetBIOS name of the computer on which to call the function. If this /// parameter is NULL, the local computer is used. /// /// /// Pointer to the buffer that receives the NetBIOS name of the domain or workgroup to which the computer is joined. This buffer is /// allocated by the system and must be freed using the NetApiBufferFree function. For more information, see Network Management /// Function Buffers and Network Management Function Buffer Lengths. /// /// Receives the join status of the specified computer. This parameter can have one of the following values. /// /// If the function succeeds, the return value is NERR_Success. /// If the function fails, the return value can be the following error code or one of the system error codes. /// /// /// Return code /// Description /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough storage is available to process this command. /// /// /// /// No special group membership is required to successfully execute the NetGetJoinInformation function. // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netgetjoininformation NET_API_STATUS NET_API_FUNCTION // NetGetJoinInformation( LPCWSTR lpServer, LPWSTR *lpNameBuffer, PNETSETUP_JOIN_STATUS BufferType ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "c7cc1cf2-4530-4039-806b-fbee572f564d")] public static extern Win32Error NetGetJoinInformation([Optional] string lpServer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NetApiBufferUnicodeStringMarshaler))] out string lpNameBuffer, out NETSETUP_JOIN_STATUS BufferType); /// The NetJoinDomain function joins a computer to a workgroup or domain. /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the computer on which to execute the domain join /// operation. If this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant null-terminated character string that specifies the name of the domain or workgroup to join. /// /// Optionally, you can specify the preferred domain controller to perform the join operation. In this instance, the string must be /// of the form DomainName\MachineName, where DomainName is the name of the domain to join, and MachineName is the name of the domain /// controller to perform the join. /// /// /// /// Optionally specifies the pointer to a constant null-terminated character string that contains the RFC 1779 format name of the /// organizational unit (OU) for the computer account. If you specify this parameter, the string must contain a full path, for /// example, OU=testOU,DC=domain,DC=Domain,DC=com. Otherwise, this parameter must be NULL. /// /// /// A pointer to a constant null-terminated character string that specifies the account name to use when connecting to the domain /// controller. The string must specify either a domain NetBIOS name and user account (for example, REDMOND\user) or the user /// principal name (UPN) of the user in the form of an Internet-style login name (for example, "someone@example.com"). If this /// parameter is NULL, the caller's context is used. /// /// /// /// If the lpAccount parameter specifies an account name, this parameter must point to the password to use when connecting to the /// domain controller. Otherwise, this parameter must be NULL. /// /// /// You can specify a local machine account password rather than a user password for unsecured joins. For more information, see the /// description of the NETSETUP_MACHINE_PWD_PASSED flag described in the fJoinOptions parameter. /// /// /// /// /// A set of bit flags defining the join options. This parameter can be one or more of the following values defined in the Lmjoin.h /// header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_JOIN_DOMAIN 0x00000001 /// Joins the computer to a domain. If this value is not specified, joins the computer to a workgroup. /// /// /// NETSETUP_ACCT_CREATE 0x00000002 /// Creates the account on the domain. /// /// /// NETSETUP_WIN9X_UPGRADE 0x00000010 /// The join operation is occurring as part of an upgrade. /// /// /// NETSETUP_DOMAIN_JOIN_IF_JOINED 0x00000020 /// Allows a join to a new domain even if the computer is already joined to a domain. /// /// /// NETSETUP_JOIN_UNSECURE 0x00000040 /// /// Performs an unsecured join. This option requests a domain join to a pre-created account without authenticating with domain user /// credentials. This option can be used in conjunction with NETSETUP_MACHINE_PWD_PASSED option. In this case, lpPassword is the /// password of the pre-created machine account. Prior to Windows Vista with SP1 and Windows Server 2008, an unsecure join did not /// authenticate to the domain controller. All communication was performed using a null (unauthenticated) session. Starting with /// Windows Vista with SP1 and Windows Server 2008, the machine account name and password are used to authenticate to the domain controller. /// /// /// /// NETSETUP_MACHINE_PWD_PASSED 0x00000080 /// /// Indicates that the lpPassword parameter specifies a local machine account password rather than a user password. This flag is /// valid only for unsecured joins, which you must indicate by also setting the NETSETUP_JOIN_UNSECURE flag. If you set this flag, /// then after the join operation succeeds, the machine password will be set to the value of lpPassword, if that value is a valid /// machine password. /// /// /// /// NETSETUP_DEFER_SPN_SET 0x00000100 /// /// Indicates that the service principal name (SPN) and the DnsHostName properties on the computer object should not be updated at /// this time. Typically, these properties are updated during the join operation. Instead, these properties should be updated during /// a subsequent call to the NetRenameMachineInDomain function. These properties are always updated during the rename operation. For /// more information, see the following Remarks section. /// /// /// /// NETSETUP_JOIN_DC_ACCOUNT 0x00000200 /// Allow the domain join if existing account is a domain controller. /// /// /// NETSETUP_JOIN_WITH_NEW_NAME 0x00000400 /// /// Join the target machine specified in lpServer parameter with a new name queried from the registry on the machine specified in the /// lpServer parameter. This option is used if SetComputerNameEx has been called prior to rebooting the machine. The new computer /// name will not take effect until a reboot. With this option, the caller instructs the NetJoinDomain function to use the new name /// during the domain join operation. A reboot is required after calling NetJoinDomain successfully at which time both the computer /// name change and domain membership change will have taken affect. /// /// /// /// NETSETUP_JOIN_READONLY 0x00000800 /// /// Join the target machine specified in lpServer parameter using a pre-created account without requiring a writable domain /// controller. This option provides the ability to join a machine to domain if an account has already been provisioned and /// replicated to a read-only domain controller. The target read-only domain controller is specified as part of the lpDomain /// parameter, after the domain name delimited by a ‘\’ character. This provisioning must include the machine secret. The machine /// account must be added via group membership into the allowed list for password replication policy, and the account password must /// be replicated to the read-only domain controller prior to the join operation. For more information, see the information on /// Password Replication Policy Administration. Starting with Windows 7, an alternate mechanism is to use the offline domain join /// mechanism. For more information, see the NetProvisionComputerAccount and NetRequestOfflineDomainJoin functions. /// /// /// /// NETSETUP_AMBIGUOUS_DC 0x00001000 /// When joining the domain don't try to set the preferred domain controller in the registry. /// /// /// NETSETUP_NO_NETLOGON_CACHE 0x00002000 /// When joining the domain don't create the Netlogon cache. /// /// /// NETSETUP_DONT_CONTROL_SERVICES 0x00004000 /// When joining the domain don't force Netlogon service to start. /// /// /// NETSETUP_SET_MACHINE_NAME 0x00008000 /// When joining the domain for offline join only, set target machine hostname and NetBIOS name. /// /// /// NETSETUP_FORCE_SPN_SET 0x00010000 /// When joining the domain, override other settings during domain join and set the service principal name (SPN). /// /// /// NETSETUP_NO_ACCT_REUSE 0x00020000 /// When joining the domain, do not reuse an existing account. /// /// /// NETSETUP_IGNORE_UNSUPPORTED_FLAGS 0x10000000 /// /// If this bit is set, unrecognized flags will be ignored by the NetJoinDomain function and NetJoinDomain will behave as if the /// flags were not set. /// /// /// /// /// /// 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_ACCESS_DENIED /// /// Access is denied. This error is returned if the caller was not a member of the Administrators local group on the target computer. /// /// /// /// ERROR_INVALID_PARAMETER /// A parameter is incorrect. This error is returned if the lpDomain parameter is NULL. /// /// /// ERROR_NO_SUCH_DOMAIN /// The specified domain did not exist. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the computer specified in the lpServer parameter does not support some of /// the options passed in the fJoinOptions parameter. /// /// /// /// NERR_InvalidWorkgroupName /// The specified workgroup name is not valid. /// /// /// NERR_SetupAlreadyJoined /// The computer is already joined to a domain. /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// /// Joining (and unjoining) a computer to a domain or workgroup can be performed only by a member of the Administrators local group /// on the target computer. Note that the domain administrator can set additional requirements for joining the domain using /// delegation and assignment of privileges. /// /// /// If you call the NetJoinDomain function remotely, you must supply credentials because you cannot delegate credentials under /// these circumstances. /// /// /// Different processes, or different threads of the same process, should not call the NetJoinDomain function at the same /// time. This situation can leave the computer in an inconsistent state. /// /// /// If you encounter a problem during a join operation, you should not delete a computer account and immediately follow the deletion /// with another join attempt. This can lead to replication-related problems that are difficult to investigate. When you delete a /// computer account, wait until the change has replicated to all domain controllers before attempting another join operation. /// /// A system reboot is required after calling the NetJoinDomain function for the operation to complete. /// /// Windows Server 2003 and Windows XP: When a call to the NetJoinDomain function precedes a call to the /// NetRenameMachineInDomain function, you should defer the update of the SPN and DnsHostName properties on the computer object until /// the rename operation. This is because the join operation can fail in certain situations. An example of such a situation is when /// the SPN that is derived from the current computer name is not valid in the new domain that the computer is joining, but the SPN /// derived from the new name that the computer will have after the rename operation is valid in the new domain. In this situation, /// the call to NetJoinDomain fails unless you defer the update of the two properties until the rename operation by specifying /// the NETSETUP_DEFER_SPN_SET flag in the fJoinOptions parameter when you call NetJoinDomain. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netjoindomain NET_API_STATUS NET_API_FUNCTION NetJoinDomain( // LPCWSTR lpServer, LPCWSTR lpDomain, LPCWSTR lpMachineAccountOU, LPCWSTR lpAccount, LPCWSTR lpPassword, DWORD fJoinOptions ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "4efcb399-03af-4312-9f1d-6bc38f356cac")] public static extern Win32Error NetJoinDomain([Optional] string lpServer, string lpDomain, [Optional] string lpMachineAccountOU, [Optional] string lpAccount, [Optional] string lpPassword, NETSETUP fJoinOptions); /// /// The NetProvisionComputerAccount function provisions a computer account for later use in an offline domain join operation. /// /// /// A pointer to a NULL-terminated character string that specifies the name of the domain where the computer account is created. /// /// /// A pointer to a NULL-terminated character string that specifies the short name of the machine from which the computer /// account attribute sAMAccountName is derived by appending a '$'. This parameter must contain a valid DNS or NetBIOS machine name. /// /// /// /// An optional pointer to a NULL-terminated character string that contains the RFC 1779 format name of the organizational /// unit (OU) where the computer account will be created. If you specify this parameter, the string must contain a full path, for /// example, OU=testOU,DC=domain,DC=Domain,DC=com. Otherwise, this parameter must be NULL. /// /// If this parameter is NULL, the well known computer object container will be used as published in the domain. /// /// /// An optional pointer to a NULL-terminated character string that contains the name of the domain controller to target. /// /// /// /// A set of bit flags that define provisioning options. This parameter can be one or more of the following values defined in the /// Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_PROVISION_DOWNLEVEL_PRIV_SUPPORT 0x00000001 /// /// If the caller requires account creation by privilege, this option will cause a retry on failure using account creation functions /// enabling interoperability with domain controllers running on earlier versions of Windows. The lpMachineAccountOU is not supported /// when using downlevel privilege support. /// /// /// /// NETSETUP_PROVISION_REUSE_ACCOUNT 0x00000002 /// /// If the named account already exists, an attempt will be made to reuse the existing account. This option requires sufficient /// credentials for this operation (Domain Administrator or the object owner). /// /// /// /// NETSETUP_PROVISION_USE_DEFAULT_PASSWORD 0x00000004 /// /// Use the default machine account password which is the machine name in lowercase. This is largely to support the older unsecure /// join model where the pre-created account typically used this default password. /// /// /// /// NETSETUP_PROVISION_SKIP_ACCOUNT_SEARCH 0x00000008 /// /// Do not try to find the account on any domain controller in the domain. This option makes the operation faster, but should only be /// used when the caller is certain that an account by the same name hasn't recently been created. This option is only valid when the /// lpDcName parameter is specified. When the prerequisites are met, this option allows for must faster provisioning useful for /// scenarios such as batch processing. /// /// /// /// NETSETUP_PROVISION_ROOT_CA_CERTS 0x00000010 /// /// This option retrieves all of the root Certificate Authority certificates on the local machine and adds them to the provisioning /// package when no certificate template names are provided as part of the provisioning package (the aCertTemplateNames member of the /// NETSETUP_PROVISIONING_PARAMS struct passed in the pProvisioningParams parameter to the NetCreateProvisioningPackage function is NULL). /// /// /// /// /// /// /// An optional pointer that will receive the opaque binary blob of serialized metadata required by NetRequestOfflineDomainJoin /// function to complete an offline domain join, if the NetProvisionComputerAccount function completes successfully. The data /// is returned as an opaque binary buffer which may be passed to NetRequestOfflineDomainJoin function. /// /// /// If this parameter is NULL, then pProvisionTextData parameter must not be NULL. If this parameter is not /// NULL, then the pProvisionTextData parameter must be NULL. /// /// /// /// A pointer to a value that receives the size, in bytes, of the buffer returned in the pProvisionBinData parameter. /// /// This parameter must not be NULL if the pProvisionBinData parameter is not NULL. This parameter must be NULL /// when the pProvisionBinData parameter is NULL. /// /// /// /// /// An optional pointer that will receive the opaque binary blob of serialized metadata required by NetRequestOfflineDomainJoin /// function to complete an offline domain join, if the NetProvisionComputerAccount function completes successfully. The data /// is returned in string form for embedding in an unattended setup answer file. /// /// /// If this parameter is NULL, then the pProvisionBinData parameter must not be NULL. If this parameter is not /// NULL, then the the pProvisionBinData parameter must be NULL. /// /// /// /// 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_ACCESS_DENIED /// Access is denied. This error is returned if the caller does not have sufficient privileges to complete the operation. /// /// /// ERROR_INVALID_DOMAIN_ROLE /// /// This operation is only allowed for the Primary Domain Controller of the domain. This error is returned if a domain controller /// name was specified in the lpDcName parameter, but the computer specified could not be validated as a domain controller for the /// target domain specified in the lpDomain parameter. /// /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the lpDomain or lpMachineName parameter is NULL. This error is also returned /// if both the pProvisionBinData and pProvisionTextData parameters are NULL. /// /// /// /// ERROR_NO_SUCH_DOMAIN /// The specified domain did not exist. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the lpMachineAccountOU parameter was specified and the domain controller /// is running on an earlier versions of Windows that does not support this parameter. /// /// /// /// NERR_DS8DCRequired /// The specified domain controller does not meet the version requirement for this operation. /// /// /// NERR_LDAPCapableDCRequired /// This operation requires a domain controller which supports LDAP. /// /// /// NERR_UserExists /// /// The account already exists in the domain and the NETSETUP_PROVISION_REUSE_ACCOUNT bit was not specified in the dwOptions parameter. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// /// The NetProvisionComputerAccount function is supported on Windows 7 and Windows Server 2008 R2 for offline join operations. /// On Windows 8 or Windows Server 2008 R2, it is recommended that the NetCreateProvisioningPackage function be used instead of the /// NetProvisionComputerAccount function. /// /// /// The NetProvisionComputerAccount function is used to provision a computer account for later use in an offline domain join /// operation using the NetRequestOfflineDomainJoin function. The offline domain join scenario uses these functions as follows: /// /// /// /// /// NetProvisionComputerAccount is a provisioning function that is first called to perform the network operations necessary to /// create and configure the computer object in Active Directory. The output from the NetProvisionComputerAccount is an opaque /// binary blob of serialized metadata used for the next step. /// /// /// /// /// NetRequestOfflineDomainJoin, an image initialization function, is then called to inject the output from the /// NetProvisionComputerAccount provisioning function into a Windows operating system image to be used during installation. /// /// /// /// Changes to Windows initialization code will detect this saved state and affect the local only portion of domain join. /// /// The NetProvisionComputerAccount function will create or reuse the machine account in the domain, collect all necessary /// metadata and return it in an opaque versioned binary blob or as text for embedding in an unattended setup answer file. The opaque /// binary blob can be consumed by the offline domain join request operation supplying all the necessary input to complete the domain /// join during first boot without any network operations (local state updates only). /// /// /// Security Note: The blob returned by the NetProvisionComputerAccount function contains very sensitive data. It /// should be treated just as securely as a plaintext password. The blob contains the machine account password and other information /// about the domain, including the domain name, the name of a domain controller, and the security ID (SID) of the domain. If the /// blob is being transported physically or over the network, care must be taken to transport it securely. The design makes no /// provisions for securing this data. This problem exists today with unattended setup answer files which can carry a number of /// secrets including domain user passwords. The caller must secure the blob and the unattended setup files. Solutions to this /// problem are varied. As an example, a pre-exchanged key could be used to encrypt a session between the consumer and provisioning /// entity enabling a secure transfer of the opaque blob. /// /// /// The opaque blob returned in the pProvisionBinData parameter by the NetProvisionComputerAccount function is versioned to /// allow interoperability and serviceability scenarios between different versions of Windows (joining client, provisioning machine, /// and domain controller). The offline join scenario currently does not limit the lifetime of the blob returned by the /// NetProvisionComputerAccount function. /// /// /// For offline domain joins, the access check performed depends on the configuration of the domain. Computer account creation is /// enabled using three methods: /// /// /// /// Domain administrators have rights to create computer accounts. /// /// /// The SD on a container can delegate the rights to create computer accounts. /// /// /// /// By default, authenticated users may create computer accounts by privilege. Authenticated users are limited to creating a limited /// number of accounts that is specified as a quota on the domain (the default value is 10). For more information, see the /// ms-DS-MachineAccountQuota attribute in the Active Directory schema. /// /// /// /// /// The NetProvisionComputerAccount function works only with a writable domain controller and does not function against a /// read-only domain controller. Once provisioning is done against a writable domain controller and the account is replicated to a /// read-only domain controller, then the other portions of offline domain join operation do not require access to a domain controller. /// /// /// If the NetProvisionComputerAccount function is successful, the pointer in the pProvisionBinData or pProvisionTextData /// parameter (depending on which was parameter was not NULL) is returned with the serialized data for use in an offline join /// operation or as text in an unattended setup file. /// /// For more information on offline domain join operations, see the Offline Domain Join Step-by-Step Guide. /// /// Joining (and unjoining) a computer to a domain using NetJoinDomain and NetUnjoinDomain can be performed only by a member of the /// Administrators local group on the target computer. Note that the domain administrator can set additional requirements for joining /// the domain using delegation and assignment of privileges. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netprovisioncomputeraccount NET_API_STATUS NET_API_FUNCTION // NetProvisionComputerAccount( LPCWSTR lpDomain, LPCWSTR lpMachineName, LPCWSTR lpMachineAccountOU, LPCWSTR lpDcName, DWORD // dwOptions, PBYTE *pProvisionBinData, DWORD *pdwProvisionBinDataSize, LPWSTR *pProvisionTextData ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "4c854258-b84d-4ef3-a6da-ce0a9540ffd5")] public static extern Win32Error NetProvisionComputerAccount(string lpDomain, string lpMachineName, [Optional] string lpMachineAccountOU, string lpDcName, NETSETUP_PROVISION dwOptions, out IntPtr pProvisionBinData, out uint pdwProvisionBinDataSize, [Optional] IntPtr pProvisionTextData); /// /// The NetProvisionComputerAccount function provisions a computer account for later use in an offline domain join operation. /// /// /// A pointer to a NULL-terminated character string that specifies the name of the domain where the computer account is created. /// /// /// A pointer to a NULL-terminated character string that specifies the short name of the machine from which the computer /// account attribute sAMAccountName is derived by appending a '$'. This parameter must contain a valid DNS or NetBIOS machine name. /// /// /// /// An optional pointer to a NULL-terminated character string that contains the RFC 1779 format name of the organizational /// unit (OU) where the computer account will be created. If you specify this parameter, the string must contain a full path, for /// example, OU=testOU,DC=domain,DC=Domain,DC=com. Otherwise, this parameter must be NULL. /// /// If this parameter is NULL, the well known computer object container will be used as published in the domain. /// /// /// An optional pointer to a NULL-terminated character string that contains the name of the domain controller to target. /// /// /// /// A set of bit flags that define provisioning options. This parameter can be one or more of the following values defined in the /// Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_PROVISION_DOWNLEVEL_PRIV_SUPPORT 0x00000001 /// /// If the caller requires account creation by privilege, this option will cause a retry on failure using account creation functions /// enabling interoperability with domain controllers running on earlier versions of Windows. The lpMachineAccountOU is not supported /// when using downlevel privilege support. /// /// /// /// NETSETUP_PROVISION_REUSE_ACCOUNT 0x00000002 /// /// If the named account already exists, an attempt will be made to reuse the existing account. This option requires sufficient /// credentials for this operation (Domain Administrator or the object owner). /// /// /// /// NETSETUP_PROVISION_USE_DEFAULT_PASSWORD 0x00000004 /// /// Use the default machine account password which is the machine name in lowercase. This is largely to support the older unsecure /// join model where the pre-created account typically used this default password. /// /// /// /// NETSETUP_PROVISION_SKIP_ACCOUNT_SEARCH 0x00000008 /// /// Do not try to find the account on any domain controller in the domain. This option makes the operation faster, but should only be /// used when the caller is certain that an account by the same name hasn't recently been created. This option is only valid when the /// lpDcName parameter is specified. When the prerequisites are met, this option allows for must faster provisioning useful for /// scenarios such as batch processing. /// /// /// /// NETSETUP_PROVISION_ROOT_CA_CERTS 0x00000010 /// /// This option retrieves all of the root Certificate Authority certificates on the local machine and adds them to the provisioning /// package when no certificate template names are provided as part of the provisioning package (the aCertTemplateNames member of the /// NETSETUP_PROVISIONING_PARAMS struct passed in the pProvisioningParams parameter to the NetCreateProvisioningPackage function is NULL). /// /// /// /// /// /// /// An optional pointer that will receive the opaque binary blob of serialized metadata required by NetRequestOfflineDomainJoin /// function to complete an offline domain join, if the NetProvisionComputerAccount function completes successfully. The data /// is returned as an opaque binary buffer which may be passed to NetRequestOfflineDomainJoin function. /// /// /// If this parameter is NULL, then pProvisionTextData parameter must not be NULL. If this parameter is not /// NULL, then the pProvisionTextData parameter must be NULL. /// /// /// /// A pointer to a value that receives the size, in bytes, of the buffer returned in the pProvisionBinData parameter. /// /// This parameter must not be NULL if the pProvisionBinData parameter is not NULL. This parameter must be NULL /// when the pProvisionBinData parameter is NULL. /// /// /// /// /// An optional pointer that will receive the opaque binary blob of serialized metadata required by NetRequestOfflineDomainJoin /// function to complete an offline domain join, if the NetProvisionComputerAccount function completes successfully. The data /// is returned in string form for embedding in an unattended setup answer file. /// /// /// If this parameter is NULL, then the pProvisionBinData parameter must not be NULL. If this parameter is not /// NULL, then the the pProvisionBinData parameter must be NULL. /// /// /// /// 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_ACCESS_DENIED /// Access is denied. This error is returned if the caller does not have sufficient privileges to complete the operation. /// /// /// ERROR_INVALID_DOMAIN_ROLE /// /// This operation is only allowed for the Primary Domain Controller of the domain. This error is returned if a domain controller /// name was specified in the lpDcName parameter, but the computer specified could not be validated as a domain controller for the /// target domain specified in the lpDomain parameter. /// /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the lpDomain or lpMachineName parameter is NULL. This error is also returned /// if both the pProvisionBinData and pProvisionTextData parameters are NULL. /// /// /// /// ERROR_NO_SUCH_DOMAIN /// The specified domain did not exist. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the lpMachineAccountOU parameter was specified and the domain controller /// is running on an earlier versions of Windows that does not support this parameter. /// /// /// /// NERR_DS8DCRequired /// The specified domain controller does not meet the version requirement for this operation. /// /// /// NERR_LDAPCapableDCRequired /// This operation requires a domain controller which supports LDAP. /// /// /// NERR_UserExists /// /// The account already exists in the domain and the NETSETUP_PROVISION_REUSE_ACCOUNT bit was not specified in the dwOptions parameter. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// /// The NetProvisionComputerAccount function is supported on Windows 7 and Windows Server 2008 R2 for offline join operations. /// On Windows 8 or Windows Server 2008 R2, it is recommended that the NetCreateProvisioningPackage function be used instead of the /// NetProvisionComputerAccount function. /// /// /// The NetProvisionComputerAccount function is used to provision a computer account for later use in an offline domain join /// operation using the NetRequestOfflineDomainJoin function. The offline domain join scenario uses these functions as follows: /// /// /// /// /// NetProvisionComputerAccount is a provisioning function that is first called to perform the network operations necessary to /// create and configure the computer object in Active Directory. The output from the NetProvisionComputerAccount is an opaque /// binary blob of serialized metadata used for the next step. /// /// /// /// /// NetRequestOfflineDomainJoin, an image initialization function, is then called to inject the output from the /// NetProvisionComputerAccount provisioning function into a Windows operating system image to be used during installation. /// /// /// /// Changes to Windows initialization code will detect this saved state and affect the local only portion of domain join. /// /// The NetProvisionComputerAccount function will create or reuse the machine account in the domain, collect all necessary /// metadata and return it in an opaque versioned binary blob or as text for embedding in an unattended setup answer file. The opaque /// binary blob can be consumed by the offline domain join request operation supplying all the necessary input to complete the domain /// join during first boot without any network operations (local state updates only). /// /// /// Security Note: The blob returned by the NetProvisionComputerAccount function contains very sensitive data. It /// should be treated just as securely as a plaintext password. The blob contains the machine account password and other information /// about the domain, including the domain name, the name of a domain controller, and the security ID (SID) of the domain. If the /// blob is being transported physically or over the network, care must be taken to transport it securely. The design makes no /// provisions for securing this data. This problem exists today with unattended setup answer files which can carry a number of /// secrets including domain user passwords. The caller must secure the blob and the unattended setup files. Solutions to this /// problem are varied. As an example, a pre-exchanged key could be used to encrypt a session between the consumer and provisioning /// entity enabling a secure transfer of the opaque blob. /// /// /// The opaque blob returned in the pProvisionBinData parameter by the NetProvisionComputerAccount function is versioned to /// allow interoperability and serviceability scenarios between different versions of Windows (joining client, provisioning machine, /// and domain controller). The offline join scenario currently does not limit the lifetime of the blob returned by the /// NetProvisionComputerAccount function. /// /// /// For offline domain joins, the access check performed depends on the configuration of the domain. Computer account creation is /// enabled using three methods: /// /// /// /// Domain administrators have rights to create computer accounts. /// /// /// The SD on a container can delegate the rights to create computer accounts. /// /// /// /// By default, authenticated users may create computer accounts by privilege. Authenticated users are limited to creating a limited /// number of accounts that is specified as a quota on the domain (the default value is 10). For more information, see the /// ms-DS-MachineAccountQuota attribute in the Active Directory schema. /// /// /// /// /// The NetProvisionComputerAccount function works only with a writable domain controller and does not function against a /// read-only domain controller. Once provisioning is done against a writable domain controller and the account is replicated to a /// read-only domain controller, then the other portions of offline domain join operation do not require access to a domain controller. /// /// /// If the NetProvisionComputerAccount function is successful, the pointer in the pProvisionBinData or pProvisionTextData /// parameter (depending on which was parameter was not NULL) is returned with the serialized data for use in an offline join /// operation or as text in an unattended setup file. /// /// For more information on offline domain join operations, see the Offline Domain Join Step-by-Step Guide. /// /// Joining (and unjoining) a computer to a domain using NetJoinDomain and NetUnjoinDomain can be performed only by a member of the /// Administrators local group on the target computer. Note that the domain administrator can set additional requirements for joining /// the domain using delegation and assignment of privileges. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netprovisioncomputeraccount NET_API_STATUS NET_API_FUNCTION // NetProvisionComputerAccount( LPCWSTR lpDomain, LPCWSTR lpMachineName, LPCWSTR lpMachineAccountOU, LPCWSTR lpDcName, DWORD // dwOptions, PBYTE *pProvisionBinData, DWORD *pdwProvisionBinDataSize, LPWSTR *pProvisionTextData ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "4c854258-b84d-4ef3-a6da-ce0a9540ffd5")] public static extern Win32Error NetProvisionComputerAccount(string lpDomain, string lpMachineName, [Optional] string lpMachineAccountOU, string lpDcName, NETSETUP_PROVISION dwOptions, [Optional] IntPtr pProvisionBinData, [Optional] IntPtr pdwProvisionBinDataSize, ref StringBuilder pProvisionTextData); /// The NetRemoveAlternateComputerName function removes an alternate name for the specified computer. /// /// A pointer to a constant string that specifies the name of the computer on which to execute this function. If this parameter is /// NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the alternate name to remove. This name must be in the form of a fully qualified /// DNS name. /// /// /// /// A pointer to a constant string that specifies the domain account to use for accessing the machine account object for the computer /// specified in the Server parameter in Active Directory. If this parameter is NULL, then the credentials of the user /// executing this routine are used. /// /// This parameter is not used if the server to execute this function is not joined to a domain. /// /// /// /// A pointer to a constant string that specifies the password matching the domain account passed in the DomainAccount parameter. If /// this parameter is NULL, then the credentials of the user executing this routine are used. /// /// /// This parameter is ignored if the DomainAccount parameter is NULL. This parameter is not used if the server to execute this /// function is not joined to a domain. /// /// /// Reserved for future use. This parameter should be NULL. /// /// 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_ACCESS_DENIED /// /// Access is denied. This error is returned if the caller was not a member of the Administrators local group on the target computer. /// /// /// /// ERROR_INVALID_NAME /// A name parameter is incorrect. This error is returned if the AlternateName parameter does not contain valid name. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the DomainAccount parameter does not contain a valid domain. This error is /// also returned if the DomainAccount parameter is not NULL and the DomainAccountPassword parameter is not NULL but does not contain /// a Unicode string. /// /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory is available to process this command. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the target computer specified in the Server parameter on which this /// function executes is running on Windows 2000 and earlier. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// The NetRemoveAlternateComputerName function is supported on Windows XP and later. /// /// The NetRemoveAlternateComputerName function is used to remove secondary computer names configured for the target computer. /// /// /// The NetRemoveAlternateComputerName function requires that the caller is a member of the Administrators local group on the /// target computer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netremovealternatecomputername NET_API_STATUS // NET_API_FUNCTION NetRemoveAlternateComputerName( LPCWSTR Server, LPCWSTR AlternateName, LPCWSTR DomainAccount, LPCWSTR // DomainAccountPassword, ULONG Reserved ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "3c7ab44e-d5fa-40da-83fe-a44bf85b2ba5")] public static extern Win32Error NetRemoveAlternateComputerName([Optional] string Server, string AlternateName, [Optional] string DomainAccount, [Optional] string DomainAccountPassword, uint Reserved = 0); /// The NetRenameMachineInDomain function changes the name of a computer in a domain. /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the computer on which to call the function. If this /// parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the new name of the computer. If specified, the local computer name is changed as /// well. If this parameter is NULL, the function assumes you have already called the SetComputerNameEx function. /// /// /// A pointer to a constant string that specifies an account name to use when connecting to the domain controller. If this parameter /// is NULL, the caller's context is used. /// /// /// If the lpAccount parameter specifies an account name, this parameter must point to the password to use when connecting to the /// domain controller. Otherwise, this parameter must be NULL. /// /// /// The rename options. If this parameter is NETSETUP_ACCT_CREATE, the function renames the account in the domain. /// /// /// 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_ACCESS_DENIED /// /// Access is denied. This error is returned if the account name passed in the lpAccount parameter did not have sufficient access /// rights for the operation. /// /// /// /// ERROR_INVALID_PARAMETER /// A parameter is incorrect. /// /// /// NERR_SetupNotJoined /// The computer is not currently joined to a domain. /// /// /// NERR_SetupDomainController /// This computer is a domain controller and cannot be unjoined from a domain. /// /// /// /// /// /// Renaming a domain computer can be performed only by a user that is a member of the Administrators local group on the target /// computer and that also is a member of the Administrators group on the domain or has the Account Operator privilege on the domain. /// If you call the NetRenameMachineInDomain function remotely, you must supply credentials because you cannot delegate /// credentials under these circumstances. /// /// /// Different processes, or different threads of the same process, should not call the NetRenameMachineInDomain function at /// the same time. This situation can leave the computer in an inconsistent state. /// /// /// The NERR_SetupNotJoined and NERR_SetupDomainController return values are defined in the Lmerr.h header file. This /// header file is automatically included by the Lm.h header file and should not be included directly. /// /// A system reboot is required after calling the NetRenameMachineInDomain function for the operation to complete. /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netrenamemachineindomain NET_API_STATUS NET_API_FUNCTION // NetRenameMachineInDomain( LPCWSTR lpServer, LPCWSTR lpNewMachineName, LPCWSTR lpAccount, LPCWSTR lpPassword, DWORD fRenameOptions ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "1f7ddaa1-a349-49a6-856d-a2fde2f1dc3b")] public static extern Win32Error NetRenameMachineInDomain([Optional] string lpServer, [Optional] string lpNewMachineName, [Optional] string lpAccount, [Optional] string lpPassword, NETSETUP fRenameOptions); /// /// The NetRequestOfflineDomainJoin function executes locally on a machine to modify a Windows operating system image mounted /// on a volume. The registry is loaded from the image and provisioning blob data is written where it can be retrieved during the /// completion phase of an offline domain join operation. /// /// /// /// A pointer to a buffer required to initialize the registry of a Windows operating system image to process the final local state /// change during the completion phase of the offline domain join operation. /// /// /// The opaque binary blob of serialized metadata passed in the pProvisionBinData parameter is returned by the /// NetProvisionComputerAccount function. /// /// /// /// The size, in bytes, of the buffer pointed to by the pProvisionBinData parameter. /// This parameter must not be NULL. /// /// /// /// A set of bit flags that define options for this function. This parameter can be one or more of the following values defined in /// the Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_PROVISION_ONLINE_CALLER 0x40000000 /// /// This flag is required if the lpWindowsPath parameter references the currently running Windows operating system directory rather /// than an offline Windows operating system image mounted on an accessible volume. If this flag is specified, the /// NetRequestOfflineDomainJoin function must be invoked by a member of the local Administrators group. /// /// /// /// /// /// /// A pointer to a constant null-terminated character string that specifies the path to a Windows operating system image under which /// the registry hives are located. This image must be offline and not currently booted unless the dwOptions parameter contains /// NETSETUP_PROVISION_ONLINE_CALLER in which case the locally running operating system directory is allowed. /// /// This path could be a UNC path on a remote server. /// /// /// 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_ACCESS_DENIED /// Access is denied. This error is returned if the caller does not have sufficient privileges to complete the operation. /// /// /// ERROR_ELEVATION_REQUIRED /// The requested operation requires elevation. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the pProvisionBinData, cbProvisionBinDataSize, or lpWindowsPath parameters /// are NULL. This error is also returned if the buffer pointed to by the pProvisionBinData parameter does not contain valid data in /// the blob for the domain, machine account name, or machine account password. This error is also returned if the string pointed to /// lpWindowsPath parameter does not specific the path to a Windows operating system image. /// /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the specified server does not support this operation. For example, if the /// lpWindowsPath parameter references a Windows installation configured as a domain controller. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// /// /// The NetRequestOfflineDomainJoin function is supported on Windows 7 for offline domain join operations. /// /// The NetRequestOfflineDomainJoin function is used locally on a machine to modify a Windows operating system image mounted /// on a volume. The registry is loaded for the image and provisioning blob data is written where it can be retrieved during the /// completion phase of an offline domain join operation. The offline domain join scenario uses these functions as follows: /// /// /// /// /// NetProvisionComputerAccount is a provisioning function that is first called to perform the network operations necessary to create /// and configure the computer object in Active Directory. The output from the NetProvisionComputerAccount is an opaque binary /// blob of serialized metadata used for the next step. /// /// /// /// /// NetRequestOfflineDomainJoin , an image initialization function, is then called to inject the output from the /// NetProvisionComputerAccount provisioning function into a Windows operating system image to be used during installation. Changes /// to Windows initialization code will detect this saved state and affect the local only portion of domain join. /// /// /// /// /// The NetProvisionComputerAccount function will create or reuse the machine account in the domain, collect all necessary metadata /// and return it in an opaque versioned binary blob or as text for embedding in an unattended setup answer file. The opaque binary /// blob can be consumed by the offline domain join request operation supplying all the necessary input to complete the domain join /// during first boot without any network operations (local state updates only). Note that the blob contains machine account password /// material essentially in the clear. The design makes no provisions for securing this data. This problem exists today with /// unattended setup answer files which can carry a number of secrets including domain user passwords. The caller must secure the /// blob and the unattended setup files. Solutions to this problem are varied. As an example, a pre-exchanged key could be used to /// encrypt a session between the consumer and provisioning entity enabling a secure transfer of the opaque blob . /// /// /// The opaque blob returned in the pProvisionBinData parameter by the NetProvisionComputerAccount function is versioned to allow /// interoperability and serviceability scenarios between different versions of Windows (joining client, provisioning machine, and /// domain controller). The offline join scenario currently does not limit the lifetime of the blob returned by the /// NetProvisionComputerAccount function. /// /// For more information on offline domain join operations, see the Offline Domain Join Step-by-Step Guide. /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netrequestofflinedomainjoin NET_API_STATUS NET_API_FUNCTION // NetRequestOfflineDomainJoin( BYTE *pProvisionBinData, DWORD cbProvisionBinDataSize, DWORD dwOptions, LPCWSTR lpWindowsPath ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "f3f8fe00-d6f7-4d59-a4e7-6aef7f507e1a")] public static extern Win32Error NetRequestOfflineDomainJoin([In] IntPtr pProvisionBinData, uint cbProvisionBinDataSize, NETSETUP_PROVISION dwOptions, string lpWindowsPath); /// /// The NetRequestProvisioningPackageInstall function executes locally on a machine to modify a Windows operating system image /// mounted on a volume. The registry is loaded from the image and provisioning package data is written where it can be retrieved /// during the completion phase of an offline domain join operation. /// /// /// /// A pointer to a buffer required to initialize the registry of a Windows operating system image to process the final local state /// change during the completion phase of the offline domain join operation. /// /// /// The opaque binary blob of serialized metadata passed in the pPackageBinData parameter is returned by the /// NetCreateProvisioningPackage function. /// /// /// /// The size, in bytes, of the buffer pointed to by the pPackageBinData parameter. /// This parameter must not be NULL. /// /// /// /// A set of bit flags that define options for this function. This parameter uses one or more of the following values defined in the /// Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_PROVISION_ONLINE_CALLER 0x40000000 /// /// This flag is required if the lpWindowsPath parameter references the currently running Windows operating system directory rather /// than an offline Windows operating system image mounted on an accessible volume. If this flag is specified, the /// NetRequestProvisioningPackageInstall function must be invoked by a member of the local Administrators group. /// /// /// /// /// /// /// A pointer to a NULL-terminated character string that specifies the path to a Windows operating system image under which /// the registry hives are located. This image must be offline and not currently booted unless the dwProvisionOptions parameter /// contains NETSETUP_PROVISION_ONLINE_CALLER, in which case, the locally running operating system directory is allowed. /// /// This path could be a UNC path on a remote server. /// /// Reserved for future use. /// /// If the function succeeds, the return value is NERR_Success. /// If the function fails, the return value can be one of the following Network Management error codes. /// /// /// Return code /// Description /// /// /// NERR_NoOfflineJoinInfo /// The offline join completion information was not found. /// /// /// NERR_BadOfflineJoinInfo /// The offline join completion information was bad. /// /// /// NERR_CantCreateJoinInfo /// /// Unable to create offline join information. Please ensure you have access to the specified path location and permissions to modify /// its contents. Running as an elevated administrator may be required. /// /// /// /// NERR_BadDomainJoinInfo /// The domain join info being saved was incomplete or bad. /// /// /// NERR_JoinPerformedMustRestart /// Offline join operation successfully completed but a restart is needed. /// /// /// NERR_NoJoinPending /// There was no offline join operation pending. /// /// /// NERR_ValuesNotSet /// Unable to set one or more requested machine or domain name values on the local computer. /// /// /// NERR_CantVerifyHostname /// Could not verify the current machine's hostname against the saved value in the join completion information. /// /// /// NERR_CantLoadOfflineHive /// /// Unable to load the specified offline registry hive. Please ensure you have access to the specified path location and permissions /// to modify its contents. Running as an elevated administrator may be required. /// /// /// /// NERR_ConnectionInsecure /// The minimum session security requirements for this operation were not met. /// /// /// NERR_ProvisioningBlobUnsupported /// Computer account provisioning blob version is not supported. /// /// /// /// /// /// The NetRequestProvisioningPackageInstall function is supported on Windows 8 for offline domain join operations. For Windows 7, /// use NetRequestOfflineDomainJoin. /// /// The offline domain join scenario uses two functions: /// /// /// /// NetCreateProvisioningPackage is a provisioning function that is first called to perform the network operations necessary to /// create and configure the computer object in Active Directory. The output from the NetCreateProvisioningPackage is a /// package used for the next step. /// /// /// /// /// NetRequestProvisioningPackageInstall, an image initialization function, is called to inject the output from the /// NetCreateProvisioningPackage provisioning function into a Windows operating system image for use during installation. /// /// /// /// /// Changes to Windows initialization code will detect this saved state and affect the local-only portion of domain join and install /// any certificate and policy information that may have been present in the package. /// /// /// The NetCreateProvisioningPackage function will create or reuse the machine account in the domain, collect all necessary metadata /// and return it in a package. The package can be consumed by the offline domain join request operation supplying all the necessary /// input to complete the domain join during first boot without any network operations (local state updates only). /// /// /// Security Note: The package created by the NetCreateProvisioningPackage function contains very sensitive data. It should be /// treated just as securely as a plaintext password. The package contains the machine account password and other information about /// the domain, including the domain name, the name of a domain controller, and the security ID (SID) of the domain. If the package /// is being transported physically or over the network, care must be taken to transport it securely. The design makes no provisions /// for securing this data. This problem exists today with unattended setup answer files which can carry a number of secrets /// including domain user passwords. The caller must secure the package. Solutions to this problem are varied. As an example, a /// pre-exchanged key could be used to encrypt a session between the consumer and provisioning entity enabling a secure transfer of /// the package. /// /// /// The package returned in the pPackageBinData parameter by the NetCreateProvisioningPackage function is versioned to allow /// interoperability and serviceability scenarios between different versions of Windows (such as joining a client, provisioning a /// machine, and using a domain controller). The offline join scenario currently does not limit the lifetime of the package returned /// by the NetCreateProvisioningPackage function. /// /// /// All phases of the provisioning process append to a NetSetup.log file on the local computer. The provisoning process can include /// up to three different computers: the computer where the provisioning package is created, the computer that requests the /// installation of the package, and the computer where the package is installed. There will be NetSetup.log file information stored /// on all three computers according to the operation performed. Reviewing the contents of these files is the most common means of /// troubleshooting online and offline provisioning errors. Provisioning operations undertaken by admins are logged to the /// NetSetup.log file in the %WINDIR%\Debug. Provisioning operations performed by non-admins are logged to the NetSetup.log file in /// the %USERPROFILE%\Debug folder. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netrequestprovisioningpackageinstall NET_API_STATUS // NET_API_FUNCTION NetRequestProvisioningPackageInstall( BYTE *pPackageBinData, DWORD dwPackageBinDataSize, DWORD // dwProvisionOptions, LPCWSTR lpWindowsPath, PVOID pvReserved ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "107ED0F7-8DDD-4C18-8C34-3A67F771FA62")] public static extern Win32Error NetRequestProvisioningPackageInstall([In] IntPtr pPackageBinData, uint dwPackageBinDataSize, NETSETUP_PROVISION dwProvisionOptions, string lpWindowsPath, IntPtr pvReserved = default); /// The NetSetPrimaryComputerName function sets the primary computer name for the specified computer. /// /// A pointer to a constant string that specifies the name of the computer on which to execute this function. If this parameter is /// NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the primary name to set. This name must be in the form of a fully qualified DNS name. /// /// /// /// A pointer to a constant string that specifies the domain account to use for accessing the machine account object for the computer /// specified in the Server parameter in Active Directory. If this parameter is NULL, then the credentials of the user /// executing this routine are used. /// /// This parameter is not used if the server to execute this function is not joined to a domain. /// /// /// /// A pointer to a constant string that specifies the password matching the domain account passed in the DomainAccount parameter. If /// this parameter is NULL, then the credentials of the user executing this routine are used. /// /// /// This parameter is ignored if the DomainAccount parameter is NULL. This parameter is not used if the server to execute this /// function is not joined to a domain. /// /// /// Reserved for future use. This parameter should be NULL. /// /// 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_ACCESS_DENIED /// /// Access is denied. This error is returned if the caller was not a member of the Administrators local group on the target computer. /// /// /// /// ERROR_INVALID_NAME /// A name parameter is incorrect. This error is returned if the PrimaryName parameter does not contain valid name. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the DomainAccount parameter does not contain a valid domain. This error is /// also returned if the DomainAccount parameter is not NULL and the DomainAccountPassword parameter is not NULL but does not contain /// a Unicode string. /// /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory is available to process this command. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if the target computer specified in the Server parameter on which this /// function executes is running on Windows 2000 and earlier. /// /// /// /// NERR_WkstaNotStarted /// The Workstation service has not been started. /// /// /// RPC_S_CALL_IN_PROGRESS /// A remote procedure call is already in progress for this thread. /// /// /// RPC_S_PROTSEQ_NOT_SUPPORTED /// The remote procedure call protocol sequence is not supported. /// /// /// /// /// The NetSetPrimaryComputerName function is supported on Windows XP and later. /// /// The NetSetPrimaryComputerName function is used as part of computer rename operations. The specified name will be removed /// from the alternate name list configured for the target computer and configured as the primary name. The computer account name /// will be changed to match the primary name. The previous primary computer name is moved to the alternate computer name list /// configured for the computer. /// /// /// The NetSetPrimaryComputerName function requires that the caller is a member of the Administrators local group on the /// target computer. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netsetprimarycomputername NET_API_STATUS NET_API_FUNCTION // NetSetPrimaryComputerName( LPCWSTR Server, LPCWSTR PrimaryName, LPCWSTR DomainAccount, LPCWSTR DomainAccountPassword, ULONG // Reserved ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "524c8219-a303-45ab-95e2-91319b477568")] public static extern Win32Error NetSetPrimaryComputerName([Optional] string Server, string PrimaryName, [Optional] string DomainAccount, [Optional] string DomainAccountPassword, uint Reserved = 0); /// The NetUnjoinDomain function unjoins a computer from a workgroup or a domain. /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the computer on which the function is to execute. If /// this parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the account name to use when connecting to the domain controller. The string must /// specify either a domain NetBIOS name and user account (for example, REDMOND\user) or the user principal name (UPN) of the user in /// the form of an Internet-style login name (for example, "someone@example.com"). If this parameter is NULL, the caller's /// context is used. /// /// /// If the lpAccount parameter specifies an account name, this parameter must point to the password to use when connecting to the /// domain controller. Otherwise, this parameter must be NULL. /// /// /// Specifies the unjoin options. If this parameter is NETSETUP_ACCT_DELETE, the account is disabled when the unjoin occurs. Note /// that this option does not delete the account. Currently, there are no other unjoin options defined. /// /// /// 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. /// /// /// NERR_SetupNotJoined /// The computer is not currently joined to a domain. /// /// /// NERR_SetupDomainController /// This computer is a domain controller and cannot be unjoined from a domain. /// /// /// /// /// /// Unjoining (and joining) a computer to a domain or workgroup can be performed only by a member of the Administrators local group /// on the target computer. If you call the NetUnjoinDomain function remotely, you must supply credentials because you cannot /// delegate credentials under these circumstances. /// /// /// Different processes, or different threads of the same process, should not call the NetUnjoinDomain function at the same /// time. This situation can leave the computer in an inconsistent state. /// /// A system reboot is required after calling the NetRenameMachineInDomain function for the operation to complete. /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netunjoindomain NET_API_STATUS NET_API_FUNCTION // NetUnjoinDomain( LPCWSTR lpServer, LPCWSTR lpAccount, LPCWSTR lpPassword, DWORD fUnjoinOptions ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "cc755c22-1fd6-4787-999e-a43258287a05")] public static extern Win32Error NetUnjoinDomain([Optional] string lpServer, [Optional] string lpAccount, [Optional] string lpPassword, NETSETUP fUnjoinOptions); /// /// The NetValidateName function verifies that a name is valid for name type specified(computer name, workgroup name, domain /// name, or DNS computer name). /// /// /// A pointer to a constant string that specifies the DNS or NetBIOS name of the computer on which to call the function. If this /// parameter is NULL, the local computer is used. /// /// /// A pointer to a constant string that specifies the name to validate. Depending on the value specified in the NameType parameter, /// the lpName parameter can point to a computer name, workgroup name, domain name, or DNS computer name. /// /// /// If the lpName parameter is a domain name, this parameter points to an account name to use when connecting to the domain /// controller. The string must specify either a domain NetBIOS name and user account (for example, "REDMOND\user") or the user /// principal name (UPN) of the user in the form of an Internet-style login name (for example, "someone@example.com"). If this /// parameter is NULL, the caller's context is used. /// /// /// If the lpAccount parameter specifies an account name, this parameter must point to the password to use when connecting to the /// domain controller. Otherwise, this parameter must be NULL. /// /// /// /// The type of the name passed in the lpName parameter to validate. This parameter can be one of the values from the /// NETSETUP_NAME_TYPE enumeration type defined in the Lmjoin.h header file. /// /// /// Note that the Lmjoin.h header is automatically included by the Lm.h header file. The Lmjoin.h header files should not be used directly. /// /// The following list shows the possible values for this parameter. /// /// /// Value /// Meaning /// /// /// NetSetupUnknown 0 /// The nametype is unknown. If this value is used, the NetValidateName function fails with ERROR_INVALID_PARAMETER. /// /// /// NetSetupMachine 1 /// Verify that the NetBIOS computer name is valid and that it is not in use. /// /// /// NetSetupWorkgroup 2 /// Verify that the workgroup name is valid. /// /// /// NetSetupDomain 3 /// Verify that the domain name exists and that it is a domain. /// /// /// NetSetupNonExistentDomain 4 /// Verify that the domain name is not in use. /// /// /// NetSetupDnsMachine 5 /// /// Verify that the DNS computer name is valid. This value is supported on Windows 2000 and later. The application must be compiled /// with _WIN32_WINNT >= 0x0500 to use this value. /// /// /// /// /// /// 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. /// /// /// Return code /// Description /// /// /// DNS_ERROR_INVALID_NAME_CHAR /// /// The DNS name contains an invalid character. This error is returned if the NameType parameter specified is NetSetupDnsMachine and /// the DNS name in the lpName parameter contains an invalid character. /// /// /// /// DNS_ERROR_NON_RFC_NAME /// /// The DNS name does not comply with RFC specifications. This error is returned if the NameType parameter specified is /// NetSetupDnsMachine and the DNS name in the lpName parameter does not comply with RFC specifications. /// /// /// /// ERROR_DUP_NAME /// A duplicate name already exists on the network. /// /// /// ERROR_INVALID_COMPUTERNAME /// The format of the specified computer name is not valid. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is incorrect. This error is returned if the lpName parameter is NULL or the NameType parameter is specified as /// NetSetupUnknown or an unknown nametype. /// /// /// /// ERROR_NO_SUCH_DOMAIN /// The specified domain does not exist. /// /// /// ERROR_NOT_SUPPORTED /// /// The request is not supported. This error is returned if a remote computer was specified in the lpServer parameter and this call /// is not supported on the remote computer. /// /// /// /// NERR_InvalidComputer /// /// The specified computer name is not valid. This error is returned if the NameType parameter specified is NetSetupDnsMachine or /// NetSetupMachine and the specified computer name is not valid. /// /// /// /// NERR_InvalidWorkgroupName /// /// The specified workgroup name is not valid. This error is returned if the NameType parameter specified is NetSetupWorkgroup and /// the specified workgroup name is not valid. /// /// /// /// RPC_S_SERVER_UNAVAILABLE /// /// The RPC server is not available. This error is returned if a remote computer was specified in the lpServer parameter and the RPC /// server is not available. /// /// /// /// RPC_E_REMOTE_DISABLED /// /// Remote calls are not allowed for this process. This error is returned if a remote computer was specified in the lpServer /// parameter and remote calls are not allowed for this process. /// /// /// /// /// /// The NetValidateName function validates a name based on the nametype specified. /// /// If the NameType parameter is NetSetupMachine, the name passed in the lpName parameter must be syntactically correct as a /// NetBIOS name and the name must not currently be in use on the network. /// /// /// If the NameType parameter is NetSetupWorkgroup, the name passed in the lpName parameter must be syntactically correct as a /// NetBIOS name, the name must not currently be in use on the network as a unique name, and the name must be different from the /// computer name. /// /// /// If the NameType parameter is NetSetupDomain, the name passed in the lpName parameter must be syntactically correct as a /// NetBIOS or DNS name and the name must currently be registered as a domain name. /// /// /// If the NameType parameter is NetSetupNonExistentDomain, the name passed in the lpName parameter must be syntactically /// correct as a NetBIOS or DNS name and the name must currently not be registered as a domain name. /// /// /// If the NameType parameter is NetSetupDnsMachine, the name passed in the lpName parameter must be syntactically correct as /// a DNS name. /// /// NetBIOS names are limited to maximum length of 16 characters. /// No special group membership is required to successfully execute the NetValidateName function. /// Examples /// The following example validates a name for a specific type. /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/nf-lmjoin-netvalidatename NET_API_STATUS NET_API_FUNCTION // NetValidateName( LPCWSTR lpServer, LPCWSTR lpName, LPCWSTR lpAccount, LPCWSTR lpPassword, NETSETUP_NAME_TYPE NameType ); [DllImport(Lib.NetApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("lmjoin.h", MSDNShortId = "772603df-ec17-4a83-a715-2d9a14d5c2bb")] public static extern Win32Error NetValidateName([Optional] string lpServer, string lpName, [Optional] string lpAccount, [Optional] string lpPassword, NETSETUP_NAME_TYPE NameType); /// Contains information about a user account that is used to join a device to Microsoft Azure Active Directory. // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/ns-lmjoin-_dsreg_user_info typedef struct _DSREG_USER_INFO { LPWSTR // pszUserEmail; LPWSTR pszUserKeyId; LPWSTR pszUserKeyName; } DSREG_USER_INFO, *PDSREG_USER_INFO; [PInvokeData("lmjoin.h", MSDNShortId = "5E639988-0F53-40D7-BBEC-F78B3D124CC0")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct DSREG_USER_INFO { /// The email address of the user. public string pszUserEmail; /// The identifier of the Microsoft Passport key that is provisioned for the user. public string pszUserKeyId; /// The name of the Microsoft Passport key that is provisioned for the user. public string pszUserKeyName; } /// /// The NETSETUP_PROVISIONING_PARAMS structure contains information that is used when creating a provisioning package using /// the NetCreateProvisionPackage function. /// /// /// /// The NETSETUP_PROVISIONING_PARAMS structure provides flags for the NetCreateProvisioningPackage function which is supported /// on Windows 8 and Windows Server 2012 for offline join operations. /// /// /// In addition to domain joins, the provisioning package can provide certificates and policies to the machine. The provisioning /// package can be used in four ways: /// /// /// /// Domain join /// /// /// Domain join and installation of certificates /// /// /// Domain join and installation of policies /// /// /// Domain join and installation of certificates and policies /// /// /// /// When certificates need to be added to the package, this structure provides the aCertTemplateNames member as an array of /// NULL-terminated certificate template names. The aCertTemplateNames member requires the cCertTemplateNames /// member to provide an explicit count of the number of items in the array. /// /// There are two different ways to add policies. You can use one or both methods: /// /// /// /// Policy name—An array of NULL-terminated policy names is provided in the aMachinePolicyNames member. During runtime, /// the policy name is mapped to the policy name in AD and the GUID that represents the policy in the enterprise space is retrieved. /// The aMachinePolicyNames member requires the cMachinePolicyNames member to provide an explicit count of the number /// of items in the array. /// /// /// /// /// Policy path—A pointer to an array of NULL-terminated character strings provided in the aMachinePolicyPaths member /// which specify the path to a file in the Registry Policy File format. For more information on the Registry Policy File Format , /// see Registry Policy File Format. The policy path is a full or relative path to the policy file. /// /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/ns-lmjoin-_netsetup_provisioning_params typedef struct // _NETSETUP_PROVISIONING_PARAMS { DWORD dwVersion; LPCWSTR lpDomain; LPCWSTR lpHostName; LPCWSTR lpMachineAccountOU; LPCWSTR // lpDcName; DWORD dwProvisionOptions; LPCWSTR *aCertTemplateNames; DWORD cCertTemplateNames; LPCWSTR *aMachinePolicyNames; DWORD // cMachinePolicyNames; LPCWSTR *aMachinePolicyPaths; DWORD cMachinePolicyPaths; LPWSTR lpNetbiosName; LPWSTR lpSiteName; LPWSTR // lpPrimaryDNSDomain; } NETSETUP_PROVISIONING_PARAMS, *PNETSETUP_PROVISIONING_PARAMS; [PInvokeData("lmjoin.h", MSDNShortId = "E965804F-145A-4D8F-BB8E-466580AC65DA")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct NETSETUP_PROVISIONING_PARAMS { /// /// /// The version of Windows in the provisioning package. This parameter should use the following value defined in the Lmjoin.h /// header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_PROVISIONING_PARAMS_CURRENT_VERSION 0x00000001 /// The version for this package is Windows Server 2012. /// /// /// public uint dwVersion; /// /// A pointer to a NULL-terminated character string that specifies the name of the domain where the computer account is created. /// public string lpDomain; /// The lp host name public string lpHostName; /// /// /// A optional pointer to a NULL-terminated character string that contains the RFC 1779 format name of the organizational /// unit (OU) where the computer account will be created. If you specify this parameter, the string must contain a full path, for /// example, OU=testOU,DC=domain,DC=Domain,DC=com. Otherwise, this parameter must be NULL. /// /// If this parameter is NULL, the well known computer object container will be used as published in the domain. /// public string lpMachineAccountOU; /// /// An optional pointer to a NULL-terminated character string that contains the name of the domain controller to target. /// public string lpDcName; /// /// /// A set of bit flags that define provisioning options. This parameter can be one or more of the following values defined in the /// Lmjoin.h header file. /// /// /// /// Value /// Meaning /// /// /// NETSETUP_PROVISION_DOWNLEVEL_PRIV_SUPPORT 0x00000001 /// /// If the caller requires account creation by privilege, this option will cause a retry on failure using account creation /// functions enabling interoperability with domain controllers running on earlier versions of Windows. The lpMachineAccountOU is /// not supported when using downlevel privilege support. /// /// /// /// NETSETUP_PROVISION_REUSE_ACCOUNT 0x00000002 /// /// If the named account already exists, an attempt will be made to reuse the existing account. This option requires sufficient /// credentials for this operation (Domain Administrator or the object owner). /// /// /// /// NETSETUP_PROVISION_USE_DEFAULT_PASSWORD 0x00000004 /// /// Use the default machine account password which is the machine name in lowercase. This is largely to support the older /// unsecure join model where the pre-created account typically used this default password. /// /// /// /// NETSETUP_PROVISION_SKIP_ACCOUNT_SEARCH 0x00000008 /// /// Do not try to find the account on any domain controller in the domain. This option makes the operation faster, but should /// only be used when the caller is certain that an account by the same name hasn't recently been created. This option is only /// valid when the lpDcName parameter is specified. When the prerequisites are met, this option allows for must faster /// provisioning useful for scenarios such as batch processing. /// /// /// /// NETSETUP_PROVISION_ROOT_CA_CERTS 0x00000010 /// /// This option retrieves all of the root Certificate Authority certificates on the local machine and adds them to the /// provisioning package. /// /// /// /// public uint dwProvisionOptions; /// A pointer to an array of NULL-terminated certificate template names. public IntPtr aCertTemplateNames; /// /// When aCertTemplateNames is not NULL, this member provides an explicit count of the number of items in the array. /// public uint cCertTemplateNames; /// A pointer to an array of NULL-terminated machine policy names. public IntPtr aMachinePolicyNames; /// /// When aMachinePolicyNames is not NULL, this member provides an explicit count of the number of items in the array. /// public uint cMachinePolicyNames; /// /// /// A pointer to an array of character strings. Each array element is a NULL-terminated character string which specifies the full /// or partial path to a file in the Registry Policy File format. For more information on the Registry Policy File Format , see /// Registry Policy File Format /// /// This path could be a UNC path on a remote server. /// public IntPtr aMachinePolicyPaths; /// /// When aMachinePolicyPaths is not NULL, this member provides an explicit count of the number of items in the array. /// public uint cMachinePolicyPaths; /// The lp netbios name public string lpNetbiosName; /// The lp site name public string lpSiteName; /// The lp primary DNS domain public string lpPrimaryDNSDomain; } /// Contains information about how a device is joined to Microsoft Azure Active Directory. // https://docs.microsoft.com/en-us/windows/desktop/api/lmjoin/ns-lmjoin-_dsreg_join_info typedef struct _DSREG_JOIN_INFO { // DSREG_JOIN_TYPE joinType; PCCERT_CONTEXT pJoinCertificate; LPWSTR pszDeviceId; LPWSTR pszIdpDomain; LPWSTR pszTenantId; LPWSTR // pszJoinUserEmail; LPWSTR pszTenantDisplayName; LPWSTR pszMdmEnrollmentUrl; LPWSTR pszMdmTermsOfUseUrl; LPWSTR pszMdmComplianceUrl; // LPWSTR pszUserSettingSyncUrl; DSREG_USER_INFO *pUserInfo; } DSREG_JOIN_INFO, *PDSREG_JOIN_INFO; [PInvokeData("lmjoin.h", MSDNShortId = "9B0F7BE3-BDCD-437E-9157-9A646A2A20E2")] public class DSREG_JOIN_INFO : SafeHANDLE { /// An enumeration value that specifies the type of the join. public DSREG_JOIN_TYPE joinType => Value.joinType; /// /// Representations of the certification for the join. This is a pointer to CERT_CONTEXT structure which can be found in Vanara.PInvoke.Cryptography. /// public Crypt32.CERT_CONTEXT? pJoinCertificate => Value.pJoinCertificate.ToNullableStructure(); /// The PSZ device identifier public string pszDeviceId => Value.pszDeviceId; /// A string that represents Azure Active Directory (Azure AD). public string pszIdpDomain => Value.pszIdpDomain; /// The identifier of the joined Azure AD tenant. public string pszTenantId => Value.pszTenantId; /// The email address for the joined account. public string pszJoinUserEmail => Value.pszJoinUserEmail; /// The display name for the joined account. public string pszTenantDisplayName => Value.pszTenantDisplayName; /// The URL to use to enroll in the Mobile Device Management (MDM) service. public string pszMdmEnrollmentUrl => Value.pszMdmEnrollmentUrl; /// The URL that provides information about the terms of use for the MDM service. public string pszMdmTermsOfUseUrl => Value.pszMdmTermsOfUseUrl; /// The URL that provides information about compliance for the MDM service. public string pszMdmComplianceUrl => Value.pszMdmComplianceUrl; /// The URL for synchronizing user settings. public string pszUserSettingSyncUrl => Value.pszUserSettingSyncUrl; /// Information about the user account that was used to join a device to Azure AD. public DSREG_USER_INFO? pUserInfo => Value.pUserInfo.ToNullableStructure(); /// /// Internal method that actually releases the handle. This is called by /// for valid handles and afterwards zeros the handle. /// /// true to indicate successful release of the handle; false otherwise. protected override bool InternalReleaseHandle() { NetFreeAadJoinInformation(handle); return true; } private _DSREG_JOIN_INFO Value => handle.ToStructure<_DSREG_JOIN_INFO>(); [StructLayout(LayoutKind.Sequential)] struct _DSREG_JOIN_INFO { public DSREG_JOIN_TYPE joinType; public IntPtr pJoinCertificate; public StrPtrUni pszDeviceId; public StrPtrUni pszIdpDomain; public StrPtrUni pszTenantId; public StrPtrUni pszJoinUserEmail; public StrPtrUni pszTenantDisplayName; public StrPtrUni pszMdmEnrollmentUrl; public StrPtrUni pszMdmTermsOfUseUrl; public StrPtrUni pszMdmComplianceUrl; public StrPtrUni pszUserSettingSyncUrl; public IntPtr pUserInfo; } } } }