Moving servers between domains with Powershell v3 add-computer commandlet

Migrating computers as part of an Active Directory migration has 2 aspects. There is an Active Directory object migration as it is with user and group objects. And in addition you have to disjoin the Windows computer from the old domain and join it to the new domain which requires to modify the workstation or server OS.
The most simple way to move a computer between domains is of course to use the GUI and change the domain or workgroup association of the computer in the system property settings manually.
However, this is not a solution for migration projects where you want to move many computers at the same time remotely logging on to the machines interactively.

In our actual large scale migration project we have to deal with multiple thousands servers that have to be migrated to the new domain. While the client computers run through an SCCM controlled imaging process, the server domain move is the task of the server admins. Some of the server admins are responsible for large scale test and development environments with hundreds of servers.
To ease the one time task of domain migration for those administrators, our idea was to implement a remote service utility which can migrate servers to the new domain in bulk mode.
While we would operate and maintain the service centrally, the server admins should decide which servers to migrate and when to migrate them. Another requirement was to leave the servers as is without installing QMM agents that could interfere with running applications.

server move automat


To be as most flexible as can be, we chose the add-computer Powershell commandlet for our scripting solution. (We ended up with a 320 line script to combine multiple modifications during server move). Server owners would place a config file on a share. The script server periodically scans the share for new config files and processes the server names.
While the final script contains multiple functions, the core function with the add-computer commandlet to disjoin/join the Computer can be found here:

function domain_move($compacc,$fqdn) {
$cred_JoinTarget=new-object -typename System.Management.Automation.PSCredential –argumentlist $username_joinTarget,$password_joinTarget
$cred_UnjoinSource=new-object -typename System.Management.Automation.PSCredential -argumentlist $username_unjoinSource,$password_unjoinSource
Try {Add-Computer -ComputerName $compacc -DomainName $TARGETDOMAIN -Credential $cred_JoinTarget -UnjoinDomainCredential $cred_UnJoinSource -Server $TargetDC -PassThru -Verbose}
Catch {return $false}
Start-Sleep -Seconds 10
Restart-Computer -ComputerName $fqdn
return $true}

The variables $compacc and $fqdn come from the main part of the script as parameters when calling the function.
$compacc=”samaccountname of computer to migrate”
$fqdn=”full qualified domain name of computer to migrate”
The text files with the encrypted passwords are located in the same directory as the executable or ps1 script.

The add-computer commandlet was introduced with Powershell 2, but had the restriction that you could only migrate the local computer and needed to run Powershell Remoting to make it useful for other computers.
With Powershell version 3 the parameter –computer was added which allows you to address remote computers for domain move.
Note: This parameter does not rely on Powershell Remoting
Another important parameter for us is –server which defines the target DC that will control the domain join operation. Since we are creating the computer object in the target domain in a specific OU in advance in the same script, it is important not to run into replication delays (trying to join while the computer object was not replicated). The –server parameter which never worked properly in Powershell version 2, did its job for us as long as we used the FQDN of the Domain Controller as syntax.
Note: If you cannot succeed with the domain\DC value for the –server parameter as listed in the Tech Net article, try out the FQDN instead.
A remarkable caveat of the add-computer commandlet for server domain move is the explicit input of domain credentials for disjoin and join actions. Even when the account that is running the script or scheduled task keeps all necessary permissions, you still have to pass account and credentials to make the domain join working. We suppose that this is a WMI restriction and that WMI is underlying code here. Check out the WMI commands below. To overcome this limitation we captured the encrypted passwords in 2 separate text files and only listed the service account in the script code. In the final version the script code was transformed into an exe file by using Powershell Admin Studio by Sapien Technlogies.
The add-computer commandlet also provides a parameter –restart. We cannot recommend to use this parameter, because it might trigger the reboot too fast, which can lead to RPC connection errors after reboot. We recommend to set a sleep time of multiple seconds and trigger a separate restart-computer commandlet which provides you with multiple options and restart dependencies.
We do not use the –path parameter but create the computer account in a separate function.
For a full amount of Parameters please check Tech Net.

Alternatives to the Add-Computer commandlet

Quest Resource Updating Manager
If you have deployed Migration Manager for Active Directory in your migration project, you can create collections for computers that should undergo a domain move. The collections can be filled by import scripts, so that you can achieve a semi-automatic solution.
QMM Resource Updating Manager
While the main purpose of QMM Resource Updating Manager is to prepare the resources (file shares, local groups, registry etc) for the domain move (which either requires to install agents or to deploy vmover scripts), it also has an option to move computers remotely without installing agents.
QMM Resource Updating Manager


Another option is the NETDOM JOIN legacy command which is around since Windows NT 4.
(To use netdom, you must run the netdom command from an elevated command prompt.)

Another way is to go WMI native and use the commands that might be underlying of the add-computer commandlet. However, we find WMI a bit “clumsy” for this purpose (we like it easy).
$currentserver= (gwmi -computername $Computer -class “Win32_ComputerSystem” -Authentication 6)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s