• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 760
  • Last Modified:

windows 7 rename computer to existing AD computer object

In xp, sysprep was a great tool for deploying new images to machines in an AD environment. Unlike Windows 7 sysprep, it could be configured to prompt for a computer name before joining it to the domain. If if the name was identical to an existing computer account, it would automatically reset the account and assign it to that machine.

I need the same functionality for deploying Windows 7. I currently have a .vbs script that is part of my builds that utilizes netdom to prompt for a computer name, and then rename the machine from the random one that the unattend creates.

In addition to renaming, I'm looking for help getting my script to also be able to reuse any existing computer accounts in the OU they exist in, to save me the trouble of having to deal with it manually.
deployment.vbs
0
alanz-sthelens
Asked:
alanz-sthelens
1 Solution
 
Manpreet SIngh KhatraSolutions Architect, Project LeadCommented:
How Sysprep Works
Applies To: Windows 7
http://technet.microsoft.com/en-us/library/dd744512(v=WS.10).aspx

- Rancy
0
 
Davis McCarnOwnerCommented:
You do know that reusing the computername causes AD to carry forward all of the detritus about the old PC, don't you?  In general, it's not a good idea.
0
 
alanz-sthelensAuthor Commented:
My goal is to have the machine prompt for the name, then the script detects if that computer name is in use. If not, it simply renames. Otherwise, it captures the location of the existing object within the OU hierarchy, deletes the object, renames the machine to the desired name, and then moves it to the OU it needs to be in.

I should be clear that this process would occur after the machine has had a scripted install of Windows 7. I'm not using sysprep prior to taking a system image.

I'm looking for examples of this kind of code, or other suggestions on how I can accomplish what I'm trying to do.
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

 
David Johnson, CD, MVPOwnerCommented:
I'm not using sysprep prior to taking a system image

That is in violation of the Microsoft End User Agreement and will result in a lot of unexplained errors later on.
0
 
RobSampsonCommented:
To rename a computer, and join it to the domain, give the HTA here a try:
http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_27680828.html

It doesn't verify the computer accounts existence though.

Regards,

Rob.
0
 
alanz-sthelensAuthor Commented:
That is in violation of the Microsoft End User Agreement and will result in a lot of unexplained errors later on.

This does not apply. I'm not using sysprep, because I'm not cloning a singular system image for deploying on multiple machines. Consider each  machine as if the OS had been installed from the original media. There are reasons why I want the machine to use a random name during setup, and hence, why I want to develop the script I outlined earlier.

Let's not worry about that, and instead focus on how to script to check AD for an existing computer account and retrieve its OU path?


To rename a computer, and join it to the domain, give the HTA here a try:

Thank you, but since I only need to enter one piece of information (the name),  InputBox seems to work fine for my purposes.
0
 
RobSampsonCommented:
OK, so stripping out the script parts of the HTA isn't difficult, so this is a pure VBS version, again, at the moment, it doesn't check for the existence of a computer account.

Regards,

Rob.

strAdminUser = "administrator"
strAdminPassword = "password"
strDomainName = "your.domain"

Set objNetwork = CreateObject("WScript.Network")
strNewName = InputBox("Enter new computer name:", "New Computer Name", objNetwork.ComputerName)
If strNewName <> "" Then
	If UCase(strNewName) <> UCase(objNetwork.ComputerName) Then
		Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
		For Each oCmp in oWMI.InstancesOf("Win32_ComputerSystem")
			sReturn = oCmp.Rename(strNewName)
		Next
		intReturn = MsgBox("Computer has been renamed. Do you want to restart now?", vbYesNo, "Reboot?")
		If intReturn = 6 Then
			Set objOSSet = GetObject("winmgmts:{(RemoteShutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")
			For Each objOS In objOSSet
				objOS.Reboot()
			Next
		End If
	End If
	intReturn = MsgBox("Do you want to join the domain now?", vbYesNo, "Join Domain?")
	If intReturn = 6 Then
		JoinDomain strAdminUser, strAdminPassword, strDomainName
	End If
Else
	MsgBox "Please enter a computer name."
End If

Sub JoinDomain(sUser, sPassword, sDomain)
	If sUser <> "" Then
		If sPassword <> "" Then
			If sDomain <> "" then
				' Join Domain
				Const JOIN_DOMAIN = 1
				Const ACCT_CREATE = 2
				
				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
				MsgBox "Computer has been joined to the domain."
			Else
				MsgBox "Please pass a username."
			End If
		Else
			MsgBox "Please pass a password."
		End If
	Else
		MsgBox "Please pass a domain name."
	End If
End Sub

Open in new window

0
 
alanz-sthelensAuthor Commented:
Thanks Rob, but I continue to research how to develop code to check existence of existing AD objects and to retrieve their OU path.
0
 
RobSampsonCommented:
Hi, I have included a function to check for the existence of the computer.  Try this.

You need to change the top four values.

Regards,

Rob.
' Enter your primary domain controller here for domain searches
strServer = "YOURPDC"
strAdminUser = "administrator"
strAdminPassword = "password"
strDomainName = "your.domain"

Set objNetwork = CreateObject("WScript.Network")
strNewName = InputBox("Enter new computer name:", "New Computer Name", objNetwork.ComputerName)
If strNewName <> "" Then
	strDN = CheckForComputer(strNewName)
	intReturn = 6
	If Left(UCase(strDN), 3) = "CN=" Then intReturn = MsgBox(strNewName & " already exists at " & strDN & vbCrLf & "Do you want to continue to rename this computer to " & strNewName & "?", vbYesNo, "Continue?")
	If intReturn = 6 Then
		If UCase(strNewName) <> UCase(objNetwork.ComputerName) Then
			Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
			For Each oCmp in oWMI.InstancesOf("Win32_ComputerSystem")
				sReturn = oCmp.Rename(strNewName)
			Next
			intReturn = MsgBox("Computer has been renamed. Do you want to restart now?", vbYesNo, "Reboot?")
			If intReturn = 6 Then
				Set objOSSet = GetObject("winmgmts:{(RemoteShutdown)}//./root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")
				For Each objOS In objOSSet
					objOS.Reboot()
				Next
			End If
		End If
		intReturn = MsgBox("Do you want to join the domain now?", vbYesNo, "Join Domain?")
		If intReturn = 6 Then
			JoinDomain strAdminUser, strAdminPassword, strDomainName
		End If
	Else
		MsgBox "Rename and joining of domain cancelled."
	End If
Else
	MsgBox "Please enter a computer name."
End If

Sub JoinDomain(sUser, sPassword, sDomain)
	If sUser <> "" Then
		If sPassword <> "" Then
			If sDomain <> "" then
				' Join Domain
				Const JOIN_DOMAIN = 1
				Const ACCT_CREATE = 2
				
				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
				MsgBox "Computer has been joined to the domain."
			Else
				MsgBox "Please pass a username."
			End If
		Else
			MsgBox "Please pass a password."
		End If
	Else
		MsgBox "Please pass a domain name."
	End If
End Sub

Function CheckForComputer(strNameToFind)
	Const ADS_SECURE_AUTHENTICATION = &H1
	Const ADS_SERVER_BIND = &H200
	
	' Specify or prompt for credentials.
	strUser = strAdminUser
	strPassword = strAdminPassword
	
	' Determine DNS domain name. Use server binding and alternate
	' credentials. The value of strDNSDomain can also be hard coded.
	Set objNS = GetObject("LDAP:")
	On Error Resume Next
	Set objRootDSE = objNS.OpenDSObject("LDAP://" & strServer & "/RootDSE", strUser, strPassword, ADS_SERVER_BIND Or ADS_SECURE_AUTHENTICATION)
	If Err.Number = 0 Then
		strDNSDomain = objRootDSE.Get("defaultNamingContext")
		
		' Use ADO to search Active Directory.
		' Use alternate credentials.
		Set adoCommand = CreateObject("ADODB.Command")
		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.ActiveConnection = adoConnection
		
		' Search entire domain. Use server binding.
		strBase = "<LDAP://" & strServer & "/" & strDNSDomain & ">"
		
		' Search for all users.
		strFilter = "(&(objectClass=computer)(name=" & strNameToFind & "))"
		
		' Comma delimited list of attribute values to retrieve.
		strAttributes = "distinguishedName"
		
		' Construct the LDAP query.
		strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
		
		' Run the query.
		adoCommand.CommandText = strQuery
		adoCommand.Properties("Page Size") = 100
		adoCommand.Properties("Timeout") = 30
		adoCommand.Properties("Cache Results") = False
		Set adoRecordset = adoCommand.Execute
		
		' Enumerate the resulting recordset.
		strDN = ""
		Do Until adoRecordset.EOF
		     ' Retrieve values.
		     strDN = adoRecordset.Fields("distinguishedName").Value
		     adoRecordset.MoveNext
		Loop
		
	Else
		strDN = "Connection failure.  Wrong password?"
	End If
	Err.Clear
	On Error GoTo 0
	CheckForComputer = strDN
End Function

Open in new window

0
 
alanz-sthelensAuthor Commented:
Rob, thank you for your excellent help. I will need time to study this.
0

Featured Post

Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now