{"id":409,"date":"2009-11-28T23:23:30","date_gmt":"2009-11-28T15:23:30","guid":{"rendered":"http:\/\/www.jhouseconsulting.com\/?p=409"},"modified":"2010-03-05T03:56:18","modified_gmt":"2010-03-05T03:56:18","slug":"script-to-join-a-computer-to-the-domain","status":"publish","type":"post","link":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2009\/11\/28\/script-to-join-a-computer-to-the-domain-409","title":{"rendered":"Script to Join a Computer to the Domain"},"content":{"rendered":"<p>This script will join a computer to a domain. You can either specify the parameters as command line arguments, or look them up in an ini file.<\/p>\n<p>If an OU is not specified, the value is set to NULL, which means that the computer object will be placed in the OU\/Container that is set as the Domain default within Active Directory, which is typically the Computers container.<\/p>\n<p>It also checks to see if the computer object already exists in AD. If it does, it will join to the object in its existing location.<\/p>\n<p>IMPORTANT: Refer to the %SystemRoot%\\Debug\\NetSetup.LOG file to help fault find any issues with the domain joining process.<!--more--><\/p>\n<p>Syntax of command line, if specifying arguments:<\/p>\n<p style=\"padding-left: 30px;\">cscript JoinDomain.vbs &#8220;[domain]&#8221; &#8220;[username]&#8221; &#8220;[password]&#8221; &#8220;[MachineAccountOU]&#8221;<\/p>\n<p>Example of command line, if specifying arguments:<\/p>\n<p style=\"padding-left: 30px;\">cscript JoinDomain.vbs &#8220;mydomain.com&#8221; &#8220;build&#8221; &#8220;password&#8221; &#8220;OU=Citrix,OU=Servers,DC=myDomain,DC=com&#8221;<\/p>\n<p>Example of the contents of the JoinDomain.ini file:<\/p>\n<p style=\"padding-left: 30px;\">[Identification]<br \/>\nJoinDomain = mydomain.com<br \/>\nDomainAdmin = build<br \/>\nDomainAdminPassword = &#8220;password&#8221;<br \/>\nMachineObjectOU = &#8220;OU=New,OU=Servers,DC=myDomain,DC=com&#8221;<\/p>\n<p><dirtycode:Join Domain Script><br \/>\n&#8216; This script will join a computer to a domain. You can either specify the parameters as<br \/>\n&#8216; command line arguments, or look them up in an ini file.<br \/>\n&#8216; If an OU is not specified, the value is set to NULL, which means that the computer<br \/>\n&#8216; object will be placed in the OU\/Container that is set as the Domain default within<br \/>\n&#8216; Active Directory.<br \/>\n&#8216; It also checks to see if the computer object already exists in AD. If it does, it will<br \/>\n&#8216; join to the object in its existing location.<br \/>\n&#8216;<br \/>\n&#8216; IMPORTANT: Refer to the %SystemRoot%\\Debug\\NetSetup.LOG file to help fault find any<br \/>\n&#8216;            issues with the domain joining process.<br \/>\n&#8216;<br \/>\n&#8216; Release 1.2 by Jeremy@jhouseconsulting.com on 5th March 2010.<br \/>\n&#8216; Written by Jeremy@jhouseconsulting.com on 13th November 2009.<br \/>\n&#8216;<br \/>\n&#8216; Syntax of command line, if specifying arguments:<br \/>\n&#8216; cscript JoinDomain.vbs &#8220;<domain>&#8221; &#8220;<username>&#8221; &#8220;<password>&#8221; &#8220;<MachineAccountOU>&#8221;<br \/>\n&#8216;<br \/>\n&#8216; Example of command line, if specifying arguments:<br \/>\n&#8216; cscript JoinDomain.vbs &#8220;mydomain.com&#8221; &#8220;build&#8221; &#8220;password&#8221; &#8220;OU=Citrix,OU=Servers,DC=myDomain,DC=com&#8221;<br \/>\n&#8216;<br \/>\n&#8216; Example of the contents of the JoinDomain.ini file:<br \/>\n&#8216;<br \/>\n&#8216; [Identification]<br \/>\n&#8216; JoinDomain = mydomain.com<br \/>\n&#8216; DomainAdmin = build<br \/>\n&#8216; DomainAdminPassword = &#8220;password&#8221;<br \/>\n&#8216; MachineObjectOU = &#8220;OU=New,OU=Servers,DC=myDomain,DC=com&#8221;<br \/>\n&#8216;<br \/>\nOption Explicit<\/p>\n<p>Const JOIN_DOMAIN = 1<br \/>\nConst ACCT_CREATE = 2<br \/>\nConst ACCT_DELETE = 4<br \/>\nConst WIN9X_UPGRADE = 16<br \/>\nConst DOMAIN_JOIN_IF_JOINED = 32<br \/>\nConst JOIN_UNSECURE = 64<br \/>\nConst MACHINE_PASSWORD_PASSED = 128<br \/>\nConst DEFERRED_SPN_SET = 256<br \/>\nConst INSTALL_INVOCATION = 262144<\/p>\n<p>Dim wshShell, objFSO, sScriptFullName, sScriptPath, blnUseArgs, strDomain, strUser<br \/>\nDim strPassword, strOU, objNetwork, strComputer, strExistingLocation, objComputer<br \/>\nDim intReturn, strSystemDrive, striniFileLocation, striniFile, strErrorDescription<br \/>\nDim blnDebug<\/p>\n<p>blnDebug = False<\/p>\n<p>Set wshShell = CreateObject(&#8220;wscript.shell&#8221;)<br \/>\nSet objFSO = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)<br \/>\nsScriptFullName = WScript.ScriptFullName<br \/>\nsScriptPath = Left(sScriptFullName, InStrRev(sScriptFullName, &#8220;\\&#8221;))<br \/>\nstrSystemDrive = WshShell.ExpandEnvironmentStrings(&#8220;%SystemDrive%&#8221;)<br \/>\nstriniFileLocation =strSystemDrive &#038; &#8220;\\wininst\\&#8221;<br \/>\nstriniFile = striniFileLocation &#038; &#8220;JoinDomain.ini&#8221;<br \/>\nIf NOT objFSO.FileExists(striniFile) Then<br \/>\n  striniFile = sScriptPath &#038; &#8220;JoinDomain.ini&#8221;<br \/>\nEnd If<\/p>\n<p>If WScript.Arguments.Count < 3 Then\n  blnUseArgs = False\nElse\n  blnUseArgs = True\n  strDomain = WScript.Arguments(0)\n  strUser = WScript.Arguments(1)\n  strPassword = WScript.Arguments(2)\n  If WScript.Arguments.Count = 4 Then\n    strOU = WScript.Arguments(3)\n  End If\nEnd If\n\nIf NOT blnUseArgs Then\n  If objFSO.FileExists(striniFile) Then\n    strDomain = GetINIString(\"Identification\", \"JoinDomain\", \"\", striniFile)\n    strDomain = Replace(strDomain,\"\"\"\",\"\")\n    strUser = GetINIString(\"Identification\", \"DomainAdmin\", \"\", striniFile)\n    strUser = Replace(strUser,\"\"\"\",\"\")\n    strPassword = GetINIString(\"Identification\", \"DomainAdminPassword\", \"\", striniFile)\n    strPassword = Replace(strPassword,\"\"\"\",\"\")\n    strOU = GetINIString(\"Identification\", \"MachineObjectOU\", \"\", striniFile)\n    strOU = Replace(strOU,\"\"\"\",\"\")\n    If blnDebug Then\n      wscript.echo \"Domain: \" &#038; strDomain &#038; vbcrlf &#038; _\n                   \"User: \" &#038; strUser &#038; vbcrlf &#038; _\n                   \"Password: \" &#038; strPassword &#038; vbcrlf &#038; _\n                   \"OU: \" &#038; strOU\n    End If\n  End If\nEnd If\n\nIf strDomain <> &#8220;&#8221; AND strUser <> &#8220;&#8221; AND strPassword <> &#8220;&#8221; Then<\/p>\n<p>  If strOU = &#8220;&#8221; Then<br \/>\n    strOU = NULL<br \/>\n  End If<\/p>\n<p>  Set objNetwork = CreateObject(&#8220;WScript.Network&#8221;)<br \/>\n  strComputer = objNetwork.ComputerName<\/p>\n<p>  strExistingLocation = getHostOU(strComputer,strDomain,strUser,strPassword)<br \/>\n  If strExistingLocation <> &#8220;&#8221; Then<br \/>\n    strOU = strExistingLocation<br \/>\n  End If<\/p>\n<p>  Set objComputer = GetObject(&#8220;winmgmts:{impersonationLevel=Impersonate}!\\\\&#8221; &#038; _<br \/>\n    strComputer &#038; &#8220;\\root\\cimv2:Win32_ComputerSystem.Name='&#8221; &#038; strComputer &#038; &#8220;&#8216;&#8221;)<\/p>\n<p>  wscript.echo &#8220;Attempting to join the &#8221; &#038; chr(34) &#038; strDomain &#038; chr(34) &#038; &#8221; Domain.&#8221;<br \/>\n  If NOT IsNULL(strOU) Then<br \/>\n    wscript.echo &#8220;The Computer Object will be placed in the following OU:&#8221; &#038; vbcrlf &#038; _<br \/>\n                 chr(34) &#038; strOU &#038; chr(34)<br \/>\n  End If<\/p>\n<p>  intReturn = objComputer.JoinDomainOrWorkGroup(strDomain, strPassword, strDomain &#038; &#8220;\\&#8221; &#038; strUser, _<br \/>\n              strOU, JOIN_DOMAIN + ACCT_CREATE)<\/p>\n<p>  Select Case intReturn<br \/>\n    Case 0<br \/>\n      strErrorDescription = &#8220;Successfully added the computer to the &#8221; &#038; chr(34) &#038; strDomain &#038; chr(34) &#038; &#8221; Domain.&#8221;<br \/>\n    Case 5<br \/>\n      strErrorDescription = &#8220;Access is denied&#8221;<br \/>\n    Case 87<br \/>\n      strErrorDescription = &#8220;The parameter is incorrect&#8221;<br \/>\n    Case 110<br \/>\n      strErrorDescription = &#8220;The system cannot open the specified object&#8221;<br \/>\n    Case 1323<br \/>\n      strErrorDescription = &#8220;Unable to update the password&#8221;<br \/>\n    Case 1326<br \/>\n      strErrorDescription = &#8220;Logon failure: unknown username or bad password&#8221;<br \/>\n    Case 1355<br \/>\n      strErrorDescription = &#8220;The specified domain either does not exist or could not be contacted&#8221;<br \/>\n    Case 2224<br \/>\n      strErrorDescription = &#8220;The account already exists&#8221;<br \/>\n    Case 2691<br \/>\n      strErrorDescription = &#8220;The machine is already joined to the domain&#8221;<br \/>\n    Case 2692<br \/>\n      strErrorDescription = &#8220;The machine is not currently joined to a domain&#8221;<br \/>\n  End Select<br \/>\n  wscript.echo strErrorDescription<\/p>\n<p>End If<\/p>\n<p>Set wshShell = Nothing<br \/>\nSet objFSO = Nothing<br \/>\nSet objNetwork = Nothing<br \/>\nSet objComputer = Nothing<\/p>\n<p>wscript.quit(0)<\/p>\n<p>Function GetINIString(Section, KeyName, Default, FileName)<br \/>\n  Dim INIContents, PosSection, PosEndSection, sContents, Value, Found<\/p>\n<p>  &#8216;Get contents of the INI file As a string<br \/>\n  INIContents = GetFile(FileName)<\/p>\n<p>  &#8216;Find section<br \/>\n  PosSection = InStr(1, INIContents, &#8220;[&#8221; &#038; Section &#038; &#8220;]&#8221;, vbTextCompare)<br \/>\n  If PosSection>0 Then<\/p>\n<p>    &#8216;Section exists. Find end of section<br \/>\n    PosEndSection = InStr(PosSection, INIContents, vbCrLf &#038; &#8220;[&#8220;)<br \/>\n    &#8216;?Is this last section?<br \/>\n    If PosEndSection = 0 Then PosEndSection = Len(INIContents)+1<\/p>\n<p>    &#8216;Separate section contents<br \/>\n    sContents = Mid(INIContents, PosSection, PosEndSection &#8211; PosSection)<\/p>\n<p>    If InStr(1, sContents, vbCrLf &#038; KeyName &#038; &#8220;=&#8221;, vbTextCompare)>0 Then<br \/>\n      Found = True<br \/>\n      &#8216;Separate value of a key.<br \/>\n      Value = SeparateField(sContents, vbCrLf &#038; KeyName &#038; &#8220;=&#8221;, vbCrLf)<br \/>\n    ElseIf InStr(1, sContents, vbCrLf &#038; KeyName &#038; &#8221; =&#8221;, vbTextCompare)>0 Then<br \/>\n      Found = True<br \/>\n      &#8216;Separate value of a key.<br \/>\n      Value = SeparateField(sContents, vbCrLf &#038; KeyName &#038; &#8221; =&#8221;, vbCrLf)<br \/>\n    End If<br \/>\n  End If<\/p>\n<p>  If isempty(Found) Then Value = Default<br \/>\n  GetINIString = Trim(Value)<br \/>\nEnd Function<\/p>\n<p>&#8216;Separates one field between sStart And sEnd<br \/>\nFunction SeparateField(ByVal sFrom, ByVal sStart, ByVal sEnd)<br \/>\n  Dim PosB: PosB = InStr(1, sFrom, sStart, 1)<br \/>\n  If PosB > 0 Then<br \/>\n    PosB = PosB + Len(sStart)<br \/>\n    Dim PosE: PosE = InStr(PosB, sFrom, sEnd, 1)<br \/>\n    If PosE = 0 Then PosE = InStr(PosB, sFrom, vbCrLf, 1)<br \/>\n    If PosE = 0 Then PosE = Len(sFrom) + 1<br \/>\n    SeparateField = Mid(sFrom, PosB, PosE &#8211; PosB)<br \/>\n  End If<br \/>\nEnd Function<\/p>\n<p>Function GetFile(ByVal FileName)<br \/>\n  Dim FS: Set FS = CreateObject(&#8220;Scripting.FileSystemObject&#8221;)<br \/>\n  &#8216;Go To windows folder If full path Not specified.<br \/>\n  If InStr(FileName, &#8220;:\\&#8221;) = 0 And Left (FileName,2)<>&#8220;\\\\&#8221; Then<br \/>\n    FileName = FS.GetSpecialFolder(0) &#038; &#8220;\\&#8221; &#038; FileName<br \/>\n  End If<br \/>\n  On Error Resume Next<\/p>\n<p>  GetFile = FS.OpenTextFile(FileName).ReadAll<br \/>\n  Set FS = Nothing<br \/>\nEnd Function<\/p>\n<p>Function getHostOU(hostname,strDomain,strUser,strPassword)<\/p>\n<p>  Dim arrDefaultNamingContext<br \/>\n  Dim item<br \/>\n  Dim strDefaultNamingContext<br \/>\n  Dim strADsPath<br \/>\n  Dim strBase<br \/>\n  Dim strFilter<br \/>\n  Dim strAttributes<br \/>\n  Dim strScope<br \/>\n  Dim strCommandText<br \/>\n  Dim objADOConnection<br \/>\n  Dim objADOCommand<br \/>\n  Dim objADORecordset<br \/>\n  Dim hostDN, hostOU<\/p>\n<p>&#8216; ADS Authentication constants that can be used.<br \/>\n  Const ADS_SECURE_AUTHENTICATION = &#038;H1<br \/>\n  Const ADS_USE_ENCRYPTION = &#038;H2<br \/>\n  Const ADS_USE_SSL = &#038;H2<br \/>\n  Const ADS_USE_SIGNING = &#038;H40<br \/>\n  Const ADS_USE_SEALING = &#038;H80<br \/>\n  Const ADS_USE_DELEGATION = &#038;H100<br \/>\n  Const ADS_SERVER_BIND = &#038;H200<\/p>\n<p>&#8216; First, need to set the correct Default Naming Context<br \/>\n&#8216;  arrDefaultNamingContext = Split(strDomain,&#8221;.&#8221;)<br \/>\n&#8216;  For Each item in arrDefaultNamingContext<br \/>\n&#8216;    If  strDefaultNamingContext = &#8220;&#8221; Then<br \/>\n&#8216;      strDefaultNamingContext =  &#8220;DC=&#8221; &#038; item<br \/>\n&#8216;    Else<br \/>\n&#8216;      strDefaultNamingContext =  strDefaultNamingContext &#038; &#8220;,DC=&#8221; &#038; item<br \/>\n&#8216;    End If<br \/>\n&#8216;  Next<br \/>\n  strDefaultNamingContext = strDomain<br \/>\n  strADsPath = &#8220;LDAP:\/\/&#8221; &#038; strDefaultNamingContext<br \/>\n  strBase = &#8220;<\" &#038; strADsPath &#038; \">&#8221;<\/p>\n<p>&#8216; Specify the LDAP filter<br \/>\n  strFilter = &#8220;(&#038;(objectClass=computer)(cn=&#8221; &#038; UCase(hostname) &#038; &#8220;))&#8221;<br \/>\n  strAttributes = &#8220;cn,distinguishedName,ADsPath&#8221;<br \/>\n&#8216; Specify the scope (base, onelevel, subtree)<br \/>\n  strScope = &#8220;subtree&#8221;<\/p>\n<p>  strCommandText = strBase &#038; &#8220;;&#8221; &#038; strFilter &#038; &#8220;;&#8221; &#038; strAttributes &#038; &#8220;;&#8221; &#038; strScope<\/p>\n<p>&#8216; Create ADO connection using the ADSI OLE DB provider<br \/>\n  Set objADOConnection = CreateObject(&#8220;ADODB.Connection&#8221;)<br \/>\n  Set objADOCommand = CreateObject(&#8220;ADODB.Command&#8221;)<br \/>\n  objADOConnection.Provider = &#8220;ADsDSOObject&#8221;<br \/>\n  objADOConnection.Properties(&#8220;User ID&#8221;) = strDomain &#038; &#8220;\\&#8221; &#038; strUser<br \/>\n  objADOConnection.Properties(&#8220;Password&#8221;) = strPassword<br \/>\n  objADOConnection.Properties(&#8220;Encrypt Password&#8221;) = True<br \/>\n  objADOConnection.Properties(&#8220;ADSI Flag&#8221;) = ADS_SERVER_BIND Or ADS_SECURE_AUTHENTICATION<br \/>\n  objADOConnection.open &#8220;Active Directory Provider&#8221;<br \/>\n  objADOCommand.activeconnection = objADOConnection<br \/>\n  objADOCommand.CommandText = strCommandText<br \/>\n  objADOCommand.Properties(&#8220;Page Size&#8221;) = 2000<br \/>\n  objADOCommand.Properties(&#8220;Sort On&#8221;) = &#8220;cn&#8221;<\/p>\n<p>  On Error Resume Next<br \/>\n  Set objADORecordset = objADOCommand.Execute<br \/>\n  If Err.Number = 0 Then<br \/>\n    While Not objADORecordset.EOF<br \/>\n      hostDN = objADORecordset.Fields(&#8220;distinguishedName&#8221;)<br \/>\n      objADORecordset.MoveNext<br \/>\n    Wend<br \/>\n    objADOConnection.Close<\/p>\n<p>    If Len(hostDN) > 0 Then<br \/>\n      hostOU = Right(hostDN, (Len(hostDN) &#8211; InStr(hostDN, &#8220;,&#8221;)))<br \/>\n    Else<br \/>\n      hostOU =&#8221;&#8221;<br \/>\n    End If<\/p>\n<p>    If Len(hostOU) > 0 Then<br \/>\n      getHostOU = hostOU<br \/>\n    Else<br \/>\n      getHostOU = &#8220;&#8221;<br \/>\n    End If<br \/>\n  Else<br \/>\n    wscript.echo &#8220;Cannot connect to the Active Directory Provider to check for the existence of the Computer Object.&#8221;<br \/>\n    getHostOU = &#8220;&#8221;<br \/>\n  End If<br \/>\n  On Error Goto 0<br \/>\n  Err.Clear<\/p>\n<p>  Set objADOConnection = Nothing<br \/>\n  Set objADOCommand = Nothing<br \/>\n  Set objADORecordset = Nothing<br \/>\nEnd Function<br \/>\n<\/dirtycode><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This script will join a computer to a domain. You can either specify the parameters as command line arguments, or look them up in an ini file. If an OU is not specified, the value is set to NULL, which means that the computer object will be placed in the OU\/Container that is set as &#8230; <a title=\"Script to Join a Computer to the Domain\" class=\"read-more\" href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2009\/11\/28\/script-to-join-a-computer-to-the-domain-409\" aria-label=\"Read more about Script to Join a Computer to the Domain\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[5],"tags":[155],"class_list":["post-409","post","type-post","status-publish","format-standard","hentry","category-scripting","tag-join-domain"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/409","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/comments?post=409"}],"version-history":[{"count":20,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/409\/revisions"}],"predecessor-version":[{"id":508,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/409\/revisions\/508"}],"wp:attachment":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/media?parent=409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/categories?post=409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/tags?post=409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}