Jump to content

Script to rename a computer and join a domain after renamed


Recommended Posts

Posted

Hi,

 

I'm looking for a vbs script or a batch file that will rename a computer (with user input for 2 fields) in both the description and the actual computer name. The format will always be the same:

 

NAME(Input1)-(Input2)

 

Once the computer is renamed, then need it joined to a domain. Joining should require little to no input from the user (the script can hold the credentials).

 

Ideally, the script would rename, restart, join, restart. If it's only possible to rename/restart and then run a second script for joining/restarting, that's fine too but it would be preferential if this did everything automatically. If at all possible, maybe a message box after each step would be great as well (renaming finishes, message box says "computer renamed to 'comp name'") and the same for the domain.

 

Also, if the script could delete itself when all is done, that would be even better! :)

 

I've been searching for the past few days and have been unsuccessful in finding a script that I can modify with my needs and get the results I'm looking for.

 

Any help would be greatly appreciated.

 

Thanks!

Posted

Here is what I have so far - I'm able to rename the computer with the prompt boxes I want and force a restart.

 

''Rename computer
dim LocID, TermID, objFSO, objTextFile, oShell
Const ForReading = 1, ForWriting = 2, ForAppending = 8


LocID=InputBox("Location ID:")
TermID=InputBox("Terminal Number:")


Set WshNetwork = WScript.CreateObject("WScript.Network")


strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")


Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")


For Each objComputer in colComputers
err = objComputer.Rename("IITGS" & LocID & "-" & TermID)
Next


''Set Computer Description


Set Obj = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery("Select * FROM Win32_OperatingSystem")
   For Each object In Obj
       object.Description = ("IITGS" & LocID & "-" & TermID)
       object.Put_
   Next


'messagebox
msgbox "Computername and description changed to " & "IITGS" & LocID & "-" & TermID
Set oShell=CreateObject("Wscript.Shell")
oShell.Run "%comspec% /c shutdown /r /t 5 /f", , TRUE

 

I'm working on a seperate script now to join the domain. If anyone has any input as to how I can make this script act the way I want above (rename/restart/join/restart) all in one script, that would be awesome.

 

And yes, I know my coding is EXTREMELY crude. I'm working on a tight timeline here and am just trying to get it to work. Cleanup can come later. :)

Posted (edited)

I have put a solution in place for this here but it forms part of a broader system of scripts and utilities linked in with WDS to centrally automate computer naming, including other desired activities like on-the-fly encryption during auto-build. I'm going to make a very long post now that details all the components of this, some of which can probably help you. I use Windows batch scripting rather than VBScript. "DOMAINNAME"/"domainname.local", "DomainUser", "DomainPassword" and "ServerName" should be altered to suit your environment. I've turned OFF the WDS option to have workstations automatically joining the domain otherwise it would conflict with this.

 

Firstly, we need to get the desired computer name when WDS loads, before image selection. To that end, we include a section in the WdsClientUnattend.xml file on the imaging server:

 


   
       
           domainname.local
           DomainPassword
           DomainUser
       
       Get computer name and store it
       1
       \\ServerName\ComputerNames\GNWrapper.bat
   

 

DomainUser is a member of solely the Domain Guests group, but is delegated access to manage our workstations OU tree from the top down. We must create a folder called ComputerNames on the WDS server and share it with the same name, granting DomainUser certain privileges to it (share with "Authenticated Users">"Full Control" only and grant NTFS permissions). DomainUser is denied interactive logon or Remote Desktop logon rights through domain-level Group Policies, and cannot change its own password.

 

This section in the config file calls a "wrapper" batch file (this is needed to stop users from clicking away the password prompt). The file is found in the root of the ComputerNames share and is as follows:

 

 @echo off
start /b /w \\ServerName\computernames\getname.exe
if not exist x:\getname.run exit 1

 

This ties in with some code from the main program, GetName.exe, which was a batch file compiled into an encrypted executable that asks for a password when run (this is to prevent users from randomly re-imaging workstations at will). The tool to compile the batch file in this way is here:

 

F2KO Software | Bat To Exe Converter

 

GetName.bat's source code is as follows:

 

 @echo off
echo. > x:\getname.run
for /f "tokens=3 delims== " %%i in ('nbtstat -a %computername% ^| find "MAC"') do set mac=%%i
if exist \\ServerName\computernames\names\%mac%.txt goto :cipher
:name
set /p compname=Please enter the workstation name: 
if not %compname%. == . echo %compname%> \\ServerName\computernames\names\%mac%.txt & goto :cipher
echo You must enter a workstation name. & goto :name
:cipher
if exist \\ServerName\computernames\names\%mac%_cipher.txt goto :eof
set /p cipher=Please enter a boot password (or press Enter to skip): 
if not %cipher%. == . echo %cipher%> \\ServerName\computernames\names\%mac%_cipher.txt

 

So the wrapper checks for the .run file that indicates the password was successfully entered and the batch code has begun execution (so users can't click the password prompt away). X:\ is the RAM disk mapped by the WDS deployment image. On the back of that, you need to edit the .wim file for your WDS deployment image and add an empty file called DisableCMDRequest.tag to \Windows\Setup\Scripts (if that folder structure doesn't exist, create it). If you don't do that, a malicious user could press Shift+F10 to access a command prompt during this stage of deployment.

 

We then identify the workstation's MAC address and check whether it has already been "registered". If it hasn't, we prompt for a name and write that back to the server by creating a .txt file named after the computer's MAC address. This file contains a single line, which is the name we prompted for earlier. These files all live in the Names folder, which is inside the ComputerNames share, to which DomainUser has normal read-and-execute permissions plus "Create files/write data", "Create folders/append data", "Write attributes" and "Write extended attributes". Administrators and SYSTEM have Full Control. No other access is granted. We know from WdsClientUnattend.xml that we are running this command as DomainUser, so the check for existing files and the subsequent write-back will be successful.

 

So, our structure under ComputerNames is:

 

Names (folder with special permissions for DomainUser)

GetName.exe (control program)

GNWrapper.bat (wrapper for security)

 

We also check whether this workstation should auto-encrypt (we only do this for staff laptops but naturally it's the same imaging system). We apply the same principles and check whether a file containing the encryption password exists (which will be MACAddress_cipher.txt). If it doesn't, we prompt again and add this file, unless the input is null in which case we skip that step. Note that only the DomainUser account can access the storage folder so this is reasonably secure although they're stored in plain text. If we ever want to change a pre-registered computer name or encryption password, we search the storage folder with the "file contents" option on, find the right file(s) and either edit or delete them (which only happens very occasionally).

 

We then proceed with image selection normally and the workstation receives the image and reboots. When it does so, we need to include a script to fetch our information again and apply it, so in the ImageUnattend.xml file for the image, we include this section:

 


   
       psexec -accepteula -is cmd /c c:\windows\system32\renamecomputer.bat
       Set computer name and join domain
       1
       true
   

 

So this will run a script called RenameComputer.bat that we include on the image before we SysPrep it. We must also have installed the drivers and executables for DiskCryptor, which can be found here:

 

Main Page/en - DiskCryptor wiki

 

We need PSExec from SysInternals too, which I always include on my images due to its immense usefulness for running programs in the SYSTEM context. Frankly, I can't remember why there's a need to run this script as SYSTEM, but I'm sure there was a reason.

 

On the first startup after imaging, RenameComputer.bat will then run. It looks like this:

 

 @echo off
del c:\windows\panther\unattend.xml
for /f "tokens=3 delims== " %%i in ('nbtstat -a %computername% ^| find "MAC"') do set mac=%%i
net use \\ServerName\computernames /u:DOMAINNAME\DomainUser DomainPassword
for /f %%i in (\\ServerName\computernames\names\%mac%.txt) do set newname=%%i
if not exist \\ServerName\computernames\names\%mac%_cipher.txt goto :rename
for /f %%i in (\\ServerName\computernames\names\%mac%_cipher.txt) do set cipher=%%i
cls
:rename
echo Renaming computer...
net use \\ServerName\computernames /d
reg add HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce /v DeleteRename /d "cmd /c del c:\windows\system32\renamecomputer.bat" > nul
reg add HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce /v JoinDomain /d "netdom join %newname% /domain:domainname.local /userd:DomainUser /passwordd:DomainPassword /reboot:0" > nul
if defined cipher dccon -boot -setmbr hd0 > nul
if defined cipher dccon -encrypt pt1 -p %cipher% > nul
netdom renamecomputer %computername% /newname:%newname% /force /reboot:0 > nul

 

First we delete the locally-cached copy of the Unattend.xml file to make sure no serial numbers, usernames/passwords etc are exposed. We then find our MAC address, connect to the imaging server and look for the .txt file with a matching name, and read that file to determine what our name should be. We carry out the same process with the cipher .txt file, if it exists, to determine whether or not we should encrypt and what the startup password should be if so. We then set the new name, which will not apply until we restart, and carry out full-disk encryption if we need to (this will take considerable time on systems with larger disks so factor that in, while also remembering that we will now need the startup password for each subsequent boot throughout the imaging process, so only use this auto-encryption when you need to). Our final action is to set RunOnce Registry commands for the next reboot to firstly delete the RenameComputer.bat script (as it includes domain credentials), then join the domain with the new name. These Registry entries are removed automatically by Windows once they have been executed, so our DomainUser credentials are not present on the finished build.

 

That's pretty much it. Naturally you can remove all encryption-related components of this entirely and it will still work. I've incorporated scripted encryption because it means I don't have to manually install and go through TrueCrypt full-disk encryption on all staff laptops (and I only ever have one or two of those at a time in my office so I can step in with startup passwords as necessary). We never encrypt our desktops around the school, so these are truly automated.

 

New machine: boot, enter password, provide name, walk away.

Edited by Ephelyon
Posted

Try this, I wrote it a while back and its a bit messy really, but it works for XP.

 

I hope it helps you on your path, ;-)

 

BoX

 

Dim FSO
Dim strComputer, objNetwork, objWMIService
Dim colItems, objItem
Dim objFileSystem, objOutputFile
Dim strOutputFile
Dim strDirectory
Dim objFSO

Const NETSETUP_ACCT_DELETE = 2 
Const OverwriteExisting = True
Const LocalDocumentsFolder = "C:\Documents and Settings\"

'local administrator user/pass to leave Domain and for auto logon.
' Edit these to suit your domain
strUser = "LocalAdministrator"
strPassword = "*********"

strAdmin = "DomainAdministrator"
strAdminPass = "*********"

Set objShell = CreateObject("Wscript.Shell")
'Set objFSO = CreateObject("Scripting.FileSystemObject")
'set objFolder = objFSO.GetFolder(localdocumentsfolder)

' generate JoinDomain script
strOutputFile = "c:\joindomain.vbs"
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set objOutputFile = objFileSystem.CreateTextFile(strOutputFile, TRUE)


' Get Domain name 
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
For Each objItem in colItems

strDomain = objItem.domain

'write contents to the file
'this file is run by runonce at logon and the self deletes
objOutputFile.WriteLine("DIM objFSO")
objOutputFile.WriteLine("Const JOIN_DOMAIN             = 1")
objOutputFile.WriteLine("Const ACCT_CREATE             = 2")
objOutputFile.WriteLine("Const ACCT_DELETE             = 4")
objOutputFile.WriteLine("Const WIN9X_UPGRADE           = 16")
objOutputFile.WriteLine("Const DOMAIN_JOIN_IF_JOINED   = 32")
objOutputFile.WriteLine("Const JOIN_UNSECURE           = 64")
objOutputFile.WriteLine("Const MACHINE_PASSWORD_PASSED = 128")
objOutputFile.WriteLine("Const DEFERRED_SPN_SET        = 256")
objOutputFile.WriteLine("Const INSTALL_INVOCATION      = 262144")
objOutputFile.WriteLine("strDomain   = " & Chr(34) & strDomain & Chr(34) & "")
'objOutputFile.WriteLine("Set objShell = CreateObject("Wscript.Shell")")
objOutputFile.WriteLine("Set objShell = CreateObject(" & Chr(34) & "Wscript.Shell" & Chr(34) & ")")
'add jondomain.vbs to runonce in the registry
' set auto logon
'objOutputFile.WriteLine("path2 = " & Chr(34) & "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon" & Chr(34) & )
'objOutputFile.WriteLine("objShell.RegWrite path2 & " & Chr(34) & "\DefaultDomainName" & Chr(34) & ","  & Chr(34) & strDomain & Chr(34) &  ","  & Chr(34) &  "REG_SZ" & Chr(34) & )
'account with joindomian permissions
objOutputFile.WriteLine("strPassword = " & Chr(34) & strAdminPass & Chr(34) & "")
objOutputFile.WriteLine("strUser     = " & Chr(34) & strAdmin & Chr(34) & "")
objOutputFile.WriteLine("Set objFSO = CreateObject(" & Chr(34) & "Scripting.FileSystemObject" & Chr(34) & ")")
objOutputFile.WriteLine("Set objNetwork = CreateObject(" & Chr(34) & "WScript.Network" & Chr(34) & ")")
objOutputFile.WriteLine("strComputer = objNetwork.ComputerName")
objOutputFile.WriteLine("Set objComputer = _")
objOutputFile.WriteLine("    GetObject(" & Chr(34) & "winmgmts:{impersonationLevel=Impersonate}!\\" & Chr(34) & " & _")
objOutputFile.WriteLine("    strComputer & " & Chr(34) & "\root\cimv2:Win32_ComputerSystem.Name='" & Chr(34) & " _")
objOutputFile.WriteLine("    & strComputer & " & Chr(34) & "'" & Chr(34) & ")")
objOutputFile.WriteLine("ReturnValue = objComputer.JoinDomainOrWorkGroup(strDomain, _")
objOutputFile.WriteLine("    strPassword, _")
objOutputFile.WriteLine("    strDomain & " & Chr(34) & "\" & Chr(34) & " & strUser, _")
objOutputFile.WriteLine("    NULL, _")
objOutputFile.WriteLine("    JOIN_DOMAIN + ACCT_CREATE ,True)")
objOutputFile.WriteLine("")
objOutputFile.WriteLine("strComputer = " & Chr(34) & "." & Chr(34) & "")
objOutputFile.WriteLine("Set objWMIService = GetObject(" & Chr(34) & "winmgmts:" & Chr(34) & " _")
objOutputFile.WriteLine("    & " & Chr(34) & "{impersonationLevel=impersonate,(Shutdown)}!\\" & Chr(34) & " & _")
objOutputFile.WriteLine("        strComputer & " & Chr(34) & "\root\cimv2" & Chr(34) & ")")
objOutputFile.WriteLine("")
objOutputFile.WriteLine("Set colOperatingSystems = objWMIService.ExecQuery _")
objOutputFile.WriteLine("    (" & Chr(34) & "Select * from Win32_OperatingSystem" & Chr(34) & ")")
objOutputFile.WriteLine("")
objOutputFile.WriteLine("For Each objOperatingSystem in colOperatingSystems")
objOutputFile.WriteLine("    objOperatingSystem.Reboot()")
objOutputFile.WriteLine("'Delete Self")
objOutputFile.WriteLine("objFSO.DeleteFile WScript.ScriptFullName")
objOutputFile.WriteLine("Set objFSO = Nothing")
objOutputFile.WriteLine("Next")

'close file
objOutputFile.Close

'add jondomain.vbs to runonce in the registry
path = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce\joinDomain"
objShell.RegWrite path, "c:\joindomain.vbs", "REG_SZ"

' set auto logon
path2 = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\winlogon"
objShell.RegWrite path2 & "\AutoAdminLogon", "1", "REG_DWORD"
objShell.RegWrite path2 & "\DefaultUserName", strUser, "REG_SZ"
objShell.RegWrite path2 & "\DefaultPassword", strPassword, "REG_SZ"
'objShell.RegWrite path2 & "\DefaultDomainName, local, "REG_SZ"

WScript.Sleep(12000)

'call delete profiles function
delprof

'Wait for profiles to be deleted
WScript.Sleep(300000)

'Leave Domain
Set objNetwork = CreateObject("WScript.Network")
strComputer = objNetwork.ComputerName

Set objComputer = GetObject("winmgmts:{impersonationLevel=Impersonate}!\\" & _
strComputer & "\root\cimv2:Win32_ComputerSystem.Name='" & strComputer & "'")
strDomain = objComputer.Domain
intReturn = objComputer.UnjoinDomainOrWorkgroup _
(strPassword, strDomain & "\" & strUser, NETSETUP_ACCT_DELETE ,True)

'reboot
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
   & "{impersonationLevel=impersonate,(Shutdown)}!\\" & _
       strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _
   ("Select * from Win32_OperatingSystem")

For Each objOperatingSystem in colOperatingSystems
   objOperatingSystem.Reboot()
Next

Next

'function to delete profiles
Function Delprof()
On Error Resume Next
Dim obtainfolder
Dim Pathfinder
Dim strPath

Set fso = CreateObject("Scripting.FileSystemObject")

strPath = "C:\Documents and Settings\"

userexcludelist = "Administrator,All Users,Default User,localservice,networkservice"

Set f = fso.GetFolder(strPath)

' Loop through all subfolders
For Each fldrItem in f.SubFolders
  fldrName = fldrItem.name
  If Right(strPath,1) <> "\" Then
    Pathfinder = strPath & "\" & fldrName
  Else
    Pathfinder = strPath & fldrName
  End If

  If InStr(1, userexcludelist, fldrName, 1) Then
    
  Else
    
    set obtainfolder = fso.GetFolder(Pathfinder)
    obtainfolder.Delete true
  End If



Next

' Clean up objects
Set fso = Nothing
Set fc = Nothing

End Function

Posted (edited)

Sorry, I've just noticed that you asked for the computer description as well. The Registry entry for this is here:

 

HKLM\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters\srvcomment

 

So you could adapt my code above to account for this as well. Personally I use the computer description to identify the image version, so I set this before I SysPrep the golden image. The command to change the computer description would be:

 

reg add HKLM\SYSTEM\CurrentControlSet\services\LanmanServer\Parameters /v srvcomment /d "WhateverYouWantItToBe" /f

 

The /f switch is to force the change to an existing Registry entry without prompting for confirmation.

 

That really is supposed to read "LanmanServer". When I save the post it does something funky with the formatting for some reason.

Edited by Ephelyon
  • 7 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...