WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Samples from Users

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

JoinDomain

 Keywords: active directory join domain  

This has been a struggle. I've previously used NT Winbatch routines to add machines to an NT domain. In the switch to AD I wanted to be able to not only add a machine to a specific OU but set attributes on the account. Netdom JOIN was the only way I could get it to work in AD but Netdom isn't perfect and doing it with an external application is just weak IMHO.

First for the references:
-------------------------------------------
Microsoft's basic create computer account to Domain script.
http://www.microsoft.com/technet/treeview/default.asp?url=/technet/scriptcenter/compmgmt/scrcm06.asp
-------------------------------------------

A conversion of the more exended one that set's permissions as well is already available but *doesn't work* unless you are already on a trusted machine / account on the domain... http://www.microsoft.com/technet/treeview/default.asp?url=/technet/scriptcenter/compmgmt/scrcm07.asp

WB Translation + explanation:
(Thanks to the original author who I borrowed code segments from)
-------------------------------------------

There are some pre-requisites to the script as well as some modifications needed.

  1. Run a change machine name routine and reboot prior to running joinDomain.
  2. Get the LSA variables. You can use the LSAGet.wbt attached and run it on a machine that's already on the domain. I just statically set all of them as the Domain name, SID...etc aren't going to change here any time soon. See Script comments . . .
  3. I am stamping the username, asset tag and serial number in the description field of the machine. You will need to get / assign these ahead of time. (See GetWMIInfo Attached for Serial#)
  4. Get a list of cached domains from the registry of a machine that is already on the domain. (HKLM -> SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache) and put those in. See Script comments . . .
I'd be interested in knowing how well this works for other people as well as a more generic version / adaptation of this UDF. :)


LSAPolicyQuery.wbt

AddExtender("WWWNT34i.DLL")

a=wntLsaPolGet('','PrimaryDomain',1)
b=wntLsaPolGet('','PrimaryDomain',2)
c=wntLsaPolGet('','DNSDomain',1)
d=wntLsaPolGet('','DNSDomain',2)
e=wntLsaPolGet('','DNSDomain',3)
f=wntLsaPolGet('','DNSDomain',4)
g=wntLsaPolGet('','DNSDomain',5)
x=wntLsaPolGet('','AccountDomain',1)
z=wntLsaPolGet('','AccountDomain',2)

; Reset the stored & hashed password that the computer will use when signing on using
; its own workstation trust account in the domain...

OutPut=FileOpen("C:\LSAOutput.txt","WRITE")

FileWrite(OutPut,"PrimaryDomain=%a%")
FileWrite(OutPut,"PrimaryDomainSID=%b%")
FileWrite(OutPut,"DNS Name=%c%")
FileWrite(OutPut,"DNS Domain=%d%")
FileWrite(OutPut,"DNS Forest=%e%")
FileWrite(OutPut,"DNS GUID=%f%")
FileWrite(OutPut,"DNS SID=%g%")
FileWrite(OutPut,"AccountDomain=%x%")
FileWrite(OutPut,"AccountDomainSID=%z%")
FileClose(OutPut)


Run("Notepad","C:\LSAOutput.txt")


STAGING_JoinDomain.wbt

;-------------------------------------------------------------------------------
; -= AddComp2Domain =-
; -= KK (crypt) 2003 =-
; Adds the specified machine to the domain
; Context: AddCompToDomain(domain,compname,OU,Username,AssetTag,ServiceTag)
;
; Domain = Short Domain Name
; compname = Computer name of the existing machine
; OU = Full LDAP path to the target OU
; Username = Stamped into computer description as user: 
; AssetTag = Stamped into computer description as Asset: 
; AssetTag = Stamped into computer description as Serial:  (See WMI Routines on WB board)
;
; Returns: Always 0 (add code for Exitcode if you want)
;
;-------------------------------------------------------------------------------
#DefineFunction AddCompToDomain(domain,compname,OU,Username,AssetTag,ServiceTag)

		Admin="Domain\Admin Account"
		Pass="Password"
		LongDomain="%domain%.yourdomain.com"

		;Add a computer to the domain
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		dsSetCredent(Admin, pass)
		UF_WORKSTATION_TRUST_ACCOUNT = 4096 ; This is a computer account that is a member of this domain. 
		UF_PASSWD_NOTREQD = 32 ; No password is required. 
		
		lFlag = UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD
		compname=StrUpper(compname)
		sComputerName = "%compname%"
		
		;*********************************************************************
		;* Establish a path to the container in the Active Directory where
		;* the machine account will be created. 
		;* For simplisities sake we are hard coding the path. Normally this
		;* is not the best way to do it.
		;*********************************************************************
		
		sComputerContainer = OU
	
		;*********************************************************************
		;* Here, the computer account is created. Certain attributes must
		;* have a value beforecommitting the object to the Active
		;* Directory with dsSetObj
		;*********************************************************************
		
		sComputerPath = dsCreateobj(sComputerContainer, "computer", "CN=%sComputerName%")
		dsSetProperty(sComputerPath, "samAccountName", "%sComputerName%$")
		dsSetProperty(sComputerPath, "userAccountControl", lFlag)
		dsSetProperty(sComputerPath, "dNSHostName", "%sComputerName%@%LongDomain%")
		dsSetProperty(sComputerPath, "servicePrincipalName", "HOST/%sComputerName%	HOST/%sComputerName%.%LongDomain%")
		dsSetProperty(sComputerPath, "Description", "User:%Username% Asset:%AssetTag% ServiceTag:%ServiceTag%")
			srchPath = "LDAP://%domain%" 
			username=StrLower(username)
			sSearch = "sAMAccountName=%username%"   
			UserPath= dsFindPath(srchPath,  sSearch)
			If UserPath=="" ;;;Account was not created.... do some error handling !!! 
				ExitCode=0
			Else
				ExitCode=1
			EndIf
			
			UserPath=StrReplace(Userpath,"LDAP://%DOMAIN%/","")
		dsSetObj(sComputerPath)
		
		;*********************************************************************
		;* Establish a default password for the machine account
		;*********************************************************************
		
		sPwd = "%sComputerName%$"
		sPwd = StrLower(sPwd)
		dsSetPassword(sComputerPath, "", sPwd) 
					
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		 


		; Set the local computer to think that it belongs to the domain...
		; AD seems to be a lot pickier about this information, hence we are setting additional
		; fields over and above the old NT Join Domain Scripts

		;;;;;;;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;;;;;;;;;;;;;;;;;;;
		;FILL IN FIELDS BELOW WITH THE LSA INFORMATION YOU GATHERED
		;;;;;;;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;;;;;;;;;;;;;;;;;;;
			wntLsaPolSet('','PrimaryDomain',1,Domain)
			wntLsaPolSet('','PrimaryDomain',2,"S-1-5-21-XXXXXXXX-xxxxxxxx-XXXXXXXXX")
			wntLsaPolSet('','DNSDomain',2,"your.domain.com") ;FILL IN DNS Domain		
			wntLsaPolSet('','DNSDomain',3,"domain.com") ;FILL IN DNS Forest
			wntLsaPolSet('','DNSDomain',5,"S-1-5-xx-XXXXXXXX-xxxxxxx-XXXXXXXX") ;FILL IN DNS SID
		   RegSetValue(@REGMACHINE,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters[DOMAIN]",LongDomain)
			RegSetValue(@REGMACHINE,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters[NV DOMAIN]",LongDomain)

		
		
		; Reset the stored & hashed password that the computer will use when signing on using
	   ; its own workstation trust account in the domain...
		wntLsaPolSet('','PrivateData','$MACHINE.ACC',sPwd)

		;Set Netlogon and W32Time services to Automatic
		RegSetDword(@REGMACHINE,"SYSTEM\CurrentControlSet\Services\Netlogon[Start]","2")
		RegSetDword(@REGMACHINE,"SYSTEM\CurrentControlSet\Services\W32Time[Start]","2")
			
			
		;;;;;;;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;;;;;;;;;;;;;;;;;;;
		;FILL IN FIELDS BELOW WITH THE CACHED DOMAIN INFORMATION
		;;;;;;;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;;;;;;;;;;;;;;;;;;;	
			;Create Domain Cache List
			RegSetValue(@REGMACHINE,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache[]","")
			RegSetValue(@REGMACHINE,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache[]","")
			RegSetValue(@REGMACHINE,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache[]","")
		Return ;May want to return the Exitcode ! :)
#EndFunction


WMI_Get_Manufacturer_Info.wbt

	;-------------------------------------------------------------------------------
	; -= Get Manufacturer =-
	; Grabs the Vendor name from the BIOS
	; Context: GetWMIInfo()
	; Returns: The Machine's Manufacturer, Model Name and Serial Number
	;-------------------------------------------------------------------------------
	#DefineFunction GetWMIInfo()
		IntControl(73, 2,0,0,0)
		Locator = ObjectOpen("WbemScripting.SWbemLocator")
		Service = Locator.ConnectServer()
		Security = Service.Security_
		Security.ImpersonationLevel = 3
		Class = "Win32_ComputerSystemProduct"
		Instance = Service.InstancesOf(Class)
		Enum = ObjectCollectionOpen(Instance)
			While 1
			  Obj = ObjectCollectionNext(Enum)
			  If Obj == 0 Then Break
			  man=Obj.Vendor
			  model=Obj.Name
			  serial=Obj.IdentifyingNumber
			EndWhile
			If man=="0" then man=""
			if model=="0" then model=""
			if serial=="0" then serial=""
		ObjectCollectionClose(Enum)
		ObjectClose(Instance)
		ObjectClose(Security)
		ObjectClose(Service)
		ObjectClose(Locator)
		data=StrCat(man,@TAB,model,@TAB,serial)
		Return(data)

		:WBERRORHANDLER
		IntControl(73, 2,0,0,0)
		Return
	#EndFunction

Article ID:   W16333
File Created: 2005:02:18:12:19:48
Last Updated: 2005:02:18:12:19:48