Solved

VBscript need help with joining workstation to domain

Posted on 2011-02-16
3
910 Views
Last Modified: 2012-05-11
Hi my company has finally upgraded from RIS to WDS and I've found that the %MACHINENAME% variable doesn't work to name a XP machine during the sysprep's mini setup phase.  I've put together a script below which automates the machine name phase during sysprep in the cmdlines section.  
Because of company policy all workstations must be prestaged so this script below in a nut shell does the following:

- Finds the DCs using the DNS address assigned by DHCP
- Pulls the GUID from BIOS
- Queries AD using GUID retrieving D/Name associated with GUID
- Chanes computer with name pulled from AD
- Joins computer to domain

The problem i'm having is when I run the script on a workstaton, it changes the computer name and joins it to the domain but when i goto log on to the workstation is says the the 'computer account is not in AD or couldnt find a DC'.  The computer account is in AD with the associated GUID.
The funny thing is, if I run the script on a workstation that's already configured with the computer name it has associated with is GUID in AD, it joins the workstation to the domain and I can log on.

I'm not sure what to do from here.  Below is my script and if someone has any pointers or an easier way, im all ears.
Option Explicit


Dim colAdapters, nic, objPing, objstatus, strDNS
Dim objWMIService, strComputer, objSystems, objItem, colComputer, objCompItem
Dim strHexID, strGUID, k, strTMP
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strDN
Dim objNS, strName, strUser, strPassword, strServer
Dim arrbytGUID, strHexGUID, arrbytSID, strHexSID, strDecSID

Const ADS_SECURE_AUTHENTICATION = &H1
Const ADS_SERVER_BIND = &H200

' Specify the local computer.
strComputer = "."

' Specify credentials.
strUser = "Domain\User"
strPassword = "password"

' Specify Domain Controller.

Set objWMIService = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colAdapters = objWMIService.ExecQuery _
      ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
For Each nic In colAdapters
              if Not IsNull(nic.DNSServerSearchOrder) Then
                  Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
                    ExecQuery("select * from Win32_PingStatus where address = '"_
                       & nic.DNSServerSearchOrder(0) & "'")
                  For Each objStatus in objPing
                        If IsNull(objStatus.StatusCode) Or objStatus.StatusCode = 0 Then
                        strServer = nic.DNSServerSearchOrder(0)
                        Else
                              strServer = nic.DNSServerSearchOrder(1)
                        End If
                  Next
            End If
Next

'get the local netbootGUID in format: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colComputer = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
For Each objCompItem In colComputer
  strGUID = "{" & objCompItem.UUID & "}"
Next

' Convert hex string to escaped hex format.
strHexGUID = DisplayGUIDToEscapedHex(strGUID)
strGUID = strHexGUID

' Determine DNS domain name. Use server binding and alternate
' credentials. The value of strDNSDomain can also be hard coded.
Set objNS = GetObject("LDAP:")
Set objRootDSE = objNS.OpenDSObject("LDAP://" & strServer & "/RootDSE", _
     strUser, strPassword, _
     ADS_SERVER_BIND Or ADS_SECURE_AUTHENTICATION)
strDNSDomain = "DC=Domain,DC=com,DC=au"

'objRootDSE.Get("defaultNamingContext")

' Create the ADO Connection object.
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Properties("User ID") = strUser
adoConnection.Properties("Password") = strPassword
adoConnection.Properties("Encrypt Password") = True
adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND _
     Or ADS_SECURE_AUTHENTICATION
adoConnection.Open "Active Directory Provider"
Set adoCommand = CreateObject("ADODB.Command")
adoCommand.ActiveConnection = adoConnection

strBase = "<LDAP://" & strServer & "/" & strDNSDomain & ">"

' Filter on computer object with netbootGUID equal to local GUID.
strFilter = "(&(objectCategory=computer)" _
    & "(netbootGUID=" & strGUID & "))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName,sAMAccountName"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

' Run the query.
Set adoRecordset = adoCommand.Execute

' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
    ' Retrieve values.
    strDN = adoRecordset.Fields("distinguishedName").Value
    strName = adoRecordset.Fields("sAMAccountName").Value
    ' Remove trailing "$" character.
    strName = Left(strName, Len(strName) - 1)
    adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close

' Rename Computer and Join Domain
Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
 
Dim sCmpName
Dim sUser, sPassword, sDomain, sOU

sUser = "User"
sPassword = "password"
sDomain = "Domain"
 
Dim oWMI, oCmp, oOS, sReturn
 
Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
For Each oCmp in oWMI.InstancesOf("Win32_ComputerSystem")
  sReturn = oCmp.Rename(strName)
  sReturn = oCmp.JoinDomainOrWorkgroup(sDomain, sPassword, _
    sDomain & "\" & sUser,, JOIN_DOMAIN+ACCT_CREATE)
Next

 Function DisplayGUIDToEscapedHex(ByVal strGUID)
    ' Function to convert GUID value from display string to
    ' escaped hex format (every byte escaped with a backslash).

    Dim TempGUID

    TempGUID = Replace(strGUID, "{", "")
    TempGUID = Replace(TempGUID, "}", "")
    TempGUID = Replace(TempGUID, "-", "")
    DisplayGUIDToEscapedHex = "\" & Mid(TempGUID, 7, 2) _
          & "\" & Mid(TempGUID, 5, 2) _
       & "\" & Mid(TempGUID, 3, 2) _
       & "\" & Mid(TempGUID, 1, 2) _
       & "\" & Mid(TempGUID, 11, 2) _
       & "\" & Mid(TempGUID, 9, 2) _
       & "\" & Mid(TempGUID, 15, 2) _
       & "\" & Mid(TempGUID, 13, 2) _
       & "\" & Mid(TempGUID, 17, 2) _
       & "\" & Mid(TempGUID, 19, 2) _
       & "\" & Mid(TempGUID, 21, 2) _
       & "\" & Mid(TempGUID, 23, 2) _
       & "\" & Mid(TempGUID, 25, 2) _
       & "\" & Mid(TempGUID, 27, 2) _
       & "\" & Mid(TempGUID, 29, 2) _
       & "\" & Mid(TempGUID, 31, 2)

End Function

0
Comment
Question by:Thunder-Cat
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 65

Accepted Solution

by:
RobSampson earned 500 total points
ID: 34912849
I would say you're going to need a reboot between these two lines:
  sReturn = oCmp.Rename(strName)
  sReturn = oCmp.JoinDomainOrWorkgroup(sDomain, sPassword, _
    sDomain & "\" & sUser,, JOIN_DOMAIN+ACCT_CREATE)


After renaming a computer, you would need to reboot before joining the domain.  I have added a reboot command, and a text file flag to let the script know if it's running after or before a reboot.  You will need to run the same script a second time after a reboot.

Regards,

Rob.
Option Explicit

Dim colAdapters, nic, objPing, objstatus, strDNS
Dim objWMIService, strComputer, objSystems, objItem, colComputer, objCompItem
Dim strHexID, strGUID, k, strTMP
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strDN
Dim objNS, strName, strUser, strPassword, strServer
Dim arrbytGUID, strHexGUID, arrbytSID, strHexSID, strDecSID
Dim objFSO, strTempFile, objFile

Const ADS_SECURE_AUTHENTICATION = &H1
Const ADS_SERVER_BIND = &H200

' Specify the local computer.
strComputer = "."

' Specify credentials.
strUser = "Domain\User"
strPassword = "password"

strTempFile = "C:\REBOOTED.TXT"

' Specify Domain Controller.

Set objWMIService = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colAdapters = objWMIService.ExecQuery _
      ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
For Each nic In colAdapters
              if Not IsNull(nic.DNSServerSearchOrder) Then
                  Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
                    ExecQuery("select * from Win32_PingStatus where address = '"_
                       & nic.DNSServerSearchOrder(0) & "'")
                  For Each objStatus in objPing
                        If IsNull(objStatus.StatusCode) Or objStatus.StatusCode = 0 Then 
                        strServer = nic.DNSServerSearchOrder(0)
                        Else
                              strServer = nic.DNSServerSearchOrder(1)
                        End If
                  Next
            End If
Next

'get the local netbootGUID in format: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colComputer = objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct")
For Each objCompItem In colComputer
  strGUID = "{" & objCompItem.UUID & "}"
Next

' Convert hex string to escaped hex format.
strHexGUID = DisplayGUIDToEscapedHex(strGUID)
strGUID = strHexGUID

' Determine DNS domain name. Use server binding and alternate
' credentials. The value of strDNSDomain can also be hard coded.
Set objNS = GetObject("LDAP:")
Set objRootDSE = objNS.OpenDSObject("LDAP://" & strServer & "/RootDSE", _
     strUser, strPassword, _
     ADS_SERVER_BIND Or ADS_SECURE_AUTHENTICATION)
strDNSDomain = "DC=Domain,DC=com,DC=au"

'objRootDSE.Get("defaultNamingContext")

' Create the ADO Connection object.
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Properties("User ID") = strUser
adoConnection.Properties("Password") = strPassword
adoConnection.Properties("Encrypt Password") = True
adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND _
     Or ADS_SECURE_AUTHENTICATION
adoConnection.Open "Active Directory Provider" 
Set adoCommand = CreateObject("ADODB.Command")
adoCommand.ActiveConnection = adoConnection

strBase = "<LDAP://" & strServer & "/" & strDNSDomain & ">"

' Filter on computer object with netbootGUID equal to local GUID.
strFilter = "(&(objectCategory=computer)" _
    & "(netbootGUID=" & strGUID & "))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName,sAMAccountName"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

' Run the query.
Set adoRecordset = adoCommand.Execute

' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
    ' Retrieve values.
    strDN = adoRecordset.Fields("distinguishedName").Value
    strName = adoRecordset.Fields("sAMAccountName").Value
    ' Remove trailing "$" character.
    strName = Left(strName, Len(strName) - 1)
    adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close

' Rename Computer and Join Domain
Const JOIN_DOMAIN = 1
Const ACCT_CREATE = 2
 
Dim sCmpName
Dim sUser, sPassword, sDomain, sOU

sUser = "User"
sPassword = "password"
sDomain = "Domain"
 
Dim oWMI, oCmp, oOS, sReturn, objOSSet, objOS
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strTempFile) = False Then
	Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
	For Each oCmp in oWMI.InstancesOf("Win32_ComputerSystem")
		sReturn = oCmp.Rename(strName)
	Next
	Set objFile = objFSO.CreateTextFile(strTempFile, True)
	objFile.Close
    Set objOSSet = GetObject("winmgmts:{(RemoteShutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")
    For Each objOS In objOSSet
		objOS.Reboot()
    Next
Else
	Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
	For Each oCmp in oWMI.InstancesOf("Win32_ComputerSystem")
		sReturn = oCmp.JoinDomainOrWorkgroup(sDomain, sPassword, _
			sDomain & "\" & sUser,, JOIN_DOMAIN+ACCT_CREATE)
	Next
	objFSO.DeleteFile strTempFile, True
	MsgBox "Computer has been joined to the domain."
End If

 Function DisplayGUIDToEscapedHex(ByVal strGUID)
    ' Function to convert GUID value from display string to
    ' escaped hex format (every byte escaped with a backslash).

    Dim TempGUID

    TempGUID = Replace(strGUID, "{", "")
    TempGUID = Replace(TempGUID, "}", "")
    TempGUID = Replace(TempGUID, "-", "")
    DisplayGUIDToEscapedHex = "\" & Mid(TempGUID, 7, 2) _
          & "\" & Mid(TempGUID, 5, 2) _
       & "\" & Mid(TempGUID, 3, 2) _
       & "\" & Mid(TempGUID, 1, 2) _
       & "\" & Mid(TempGUID, 11, 2) _
       & "\" & Mid(TempGUID, 9, 2) _
       & "\" & Mid(TempGUID, 15, 2) _
       & "\" & Mid(TempGUID, 13, 2) _
       & "\" & Mid(TempGUID, 17, 2) _
       & "\" & Mid(TempGUID, 19, 2) _
       & "\" & Mid(TempGUID, 21, 2) _
       & "\" & Mid(TempGUID, 23, 2) _
       & "\" & Mid(TempGUID, 25, 2) _
       & "\" & Mid(TempGUID, 27, 2) _
       & "\" & Mid(TempGUID, 29, 2) _
       & "\" & Mid(TempGUID, 31, 2)

End Function

Open in new window

0
 

Author Comment

by:Thunder-Cat
ID: 34938864
Cheers that worked.  Now Ive got to try and get the script to run in the cmdlines file.  

When I add any of the lines in the cmdlines.txt file the script still doesn't run.

"C:\Wscript.exe VBScript.vbs"
"C:\Sysprep\i386\$OEM$\wscript.exe VBscipt.vbs"
"C:\Sysprep\i386\$OEM$\VBscipt.vbs"  

U have any pointers?
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 34938906
Try using
wscript C:\VBScript.vbs

or
C:\Windows\System32\wscript.exe C:\VBScript.vbs

wscript is it's own executable, and the full path to the VBS needs to be specified after it.

Regards,

Rob.
0

Featured Post

What Is Transaction Monitoring and who needs it?

Synthetic Transaction Monitoring that you need for the day to day, which ensures your business website keeps running optimally, and that there is no downtime to impact your customer experience.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It is only natural that we all want our PCs to be in good working order, improved system performance, so that is exactly how programs are advertised to entice. They say things like:            •      PC crashes? Get registry cleaner to repair it!    …
This article is the result of a quest to better understand Task Scheduler 2.0 and all the newer objects available in vbscript in this version over  the limited options we had scripting in Task Scheduler 1.0.  As I started my journey of knowledge I f…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question