mccabr
asked on
Rename a Computer then Join to a Domain
Hi, I have been struggling with WMI, renaming a computer then joining a domain.
I have two scenarios, run the script on a machine which has never participated in the domain and I can rename and join in one go - no problems.
If the machine account already exists on the domain (machine was rebuilt with a temp name after sysprep) and I try and rename and join, it fails. If I simply rename using WMI and try and 'Add to the Domain' it fails since the computer object I have just renamed is still referred to in WMI as the old name (confused? I am).
Essentially, I want to Rename and Join in one move for both sets of circumstances and would be able to do so if WMI reported the newly named machine after a rename instead of the old one.
Here are the functions (VB) I have at the moment:
Public Function RenameComputerAndAccount(B yVal strComputerName As String) As Boolean
Dim strComputer As String
Dim objWMIService As Object
Dim colComputers As Object
Dim objComputer As Object
'Set default return value
RenameComputerAndAccount = False
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=imper sonate}!\\ " & strComputer & "\root\cimv2")
Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer In colComputers
RenameComputerAndAccount = objComputer.Rename(strComp uterName)
Next
End Function
Public Function AddComputerToDomain(ByVal strComputer As String, ByVal strDomain As String, ByVal strUser As String, ByVal strPassword As String, ByVal strOU As String) As Boolean
Dim objNetwork As Object
Dim objComputer As Object
Dim lresult As Long
'Set objNetwork = CreateObject("WScript.Netw ork")
'strComputer = objNetwork.ComputerName
Set objComputer = GetObject("winmgmts:{imper sonationLe vel=Impers onate}!\\" & _
strComputer & "\root\cimv2:Win32_Compute rSystem.Na me='" & _
strComputer & "'")
lresult = objComputer.JoinDomainOrWo rkGroup(st rDomain, _
strPassword, strDomain & "\" & strUser, strOU, _
JOIN_DOMAIN + ACCT_CREATE)
If lresult = 2224 Then
'The account already exists, not a problem!
lresult = 0
Exit Function
End If
If lresult <> ERROR_SUCCESS Then MsgBox "Failed to Join the domain '" & strDomain & "'" & vbCrLf & "Error: " & lresult
End Function
Public Function RenameComputer(ByVal strComputerName As String) As Boolean
Dim objWMIService As Object
Dim objComputer As Object
Dim strComputer As String
Dim lReturn As Long
'Set default return value
RenameComputer = False
strComputer = "."
Set objWMIService = GetObject("Winmgmts:root\c imv2")
' Call always gets only one Win32_ComputerSystem object.
For Each objComputer In _
objWMIService.InstancesOf( "Win32_Com puterSyste m")
lReturn = objComputer.Rename(strComp uterName, vbNull, strUser)
If lReturn <> 0 Then MsgBox "Rename Failed: Error Number: " & Err.Number & " " & Err.Description
RenameComputer = lReturn
Next
End Function
I have two scenarios, run the script on a machine which has never participated in the domain and I can rename and join in one go - no problems.
If the machine account already exists on the domain (machine was rebuilt with a temp name after sysprep) and I try and rename and join, it fails. If I simply rename using WMI and try and 'Add to the Domain' it fails since the computer object I have just renamed is still referred to in WMI as the old name (confused? I am).
Essentially, I want to Rename and Join in one move for both sets of circumstances and would be able to do so if WMI reported the newly named machine after a rename instead of the old one.
Here are the functions (VB) I have at the moment:
Public Function RenameComputerAndAccount(B
Dim strComputer As String
Dim objWMIService As Object
Dim colComputers As Object
Dim objComputer As Object
'Set default return value
RenameComputerAndAccount = False
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=imper
Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer In colComputers
RenameComputerAndAccount = objComputer.Rename(strComp
Next
End Function
Public Function AddComputerToDomain(ByVal strComputer As String, ByVal strDomain As String, ByVal strUser As String, ByVal strPassword As String, ByVal strOU As String) As Boolean
Dim objNetwork As Object
Dim objComputer As Object
Dim lresult As Long
'Set objNetwork = CreateObject("WScript.Netw
'strComputer = objNetwork.ComputerName
Set objComputer = GetObject("winmgmts:{imper
strComputer & "\root\cimv2:Win32_Compute
strComputer & "'")
lresult = objComputer.JoinDomainOrWo
strPassword, strDomain & "\" & strUser, strOU, _
JOIN_DOMAIN + ACCT_CREATE)
If lresult = 2224 Then
'The account already exists, not a problem!
lresult = 0
Exit Function
End If
If lresult <> ERROR_SUCCESS Then MsgBox "Failed to Join the domain '" & strDomain & "'" & vbCrLf & "Error: " & lresult
End Function
Public Function RenameComputer(ByVal strComputerName As String) As Boolean
Dim objWMIService As Object
Dim objComputer As Object
Dim strComputer As String
Dim lReturn As Long
'Set default return value
RenameComputer = False
strComputer = "."
Set objWMIService = GetObject("Winmgmts:root\c
' Call always gets only one Win32_ComputerSystem object.
For Each objComputer In _
objWMIService.InstancesOf(
lReturn = objComputer.Rename(strComp
If lReturn <> 0 Then MsgBox "Rename Failed: Error Number: " & Err.Number & " " & Err.Description
RenameComputer = lReturn
Next
End Function
You're the man.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
The way to do this is to first, use ADSI to delete the account you want to create (if it exists) there is a method of binding which allows you to pass a username/password instead of the current context.
Next, join the machine to the domain and finally rename the workstation using the .rename which works for local account and domain account - problem solved.