Domain join using a Read-Only Domain Controller

2 minute read

Joining computers to a domain using only a read-only domain controller (without access to any writeable domain controllers) is a bit of a complicated process. If you just follow the instructions that exist in Microsoft documentation you are probably going to run into weird issues down the road. After many failed attempts over the years I have finally found a process that seems to work reliably. Here it is!

Pre-populating

The first step is pretty obvious. We’re going to have to create a computer account in our domain with a known password that we can provide to the computer to join with.

$ComputerPassword = 'Password!'

New-ADComputer -Name 'NewComputer' -AccountPassword ($ComputerPassword | ConvertTo-SecureString -AsPlainText -Force)

Once that’s done we’ll want to add it to the security group that allows its account to be replicated to our Read-Only Domain Controllers. Best practice is to create a security group for each physical site or RODC and add those, but for this example I’m just going to use the default group.

$ComputerName = 'NewComputer'

Get-ADGroup "Allowed RODC Password Replication Group" | Add-ADGroupMember -Members (Get-ADComputer $ComputerName)

This next part is fairly critical and not super obvious. If your computer only has access to a Read-Only Domain Controller it won’t be able to update its Service Principal Names after joining. Without these in place Kerberos is going to fail and you’re going to run into a lot of weird issues. To fix these problems you can prepopulate the required SPN entries manually.

$ComputerName = 'NewComputer'
$Domain = 'example.net'

$SPN = @{
    Replace = @(
        "TERMSRV/$ComputerName.$Domain",
        "WSMAN/$ComputerName.$Domain",
        "RestrictedKrbHost/$ComputerName.$Domain",
        "HOST/$ComputerName.$Domain",
        "TERMSRV/$ComputerName",
        "WSMAN/$ComputerName",
        "RestrictedKrbHost/$ComputerName",
        "HOST/$ComputerName"
    )
}

Get-ADComputer $ComputerName | Set-ADComputer -ServicePrincipalNames $SPN

Likewise your computer is probably not going to be able to register its own DNS records without access to a writeable Domain Controller so we’ll create that record manually.

$ComputerName = 'NewComputer'
$Domain = 'example.net'
$ComputerIP = '192.168.100.200'

Add-DnsServerResourceRecord -ZoneName $Domain -A -CreatePtr -IPv4Address $ComputerIP -Name $ComputerName

Joining the domain

The final step is to actually run the join on the computer. In my experience trying to join to a RODC only works if the computer already has the appropriate name before starting the join. Before we do anything we’ll need to rename the computer and restart.

Rename-Computer -NewName 'NewComputer' -Restart

Once that’s done run the PowerShell commands to join to the specific RODC using a pre-populated password.

$Rodc = 'rodc01.example.net'

$ComputerPassword = 'Password!'
$ComputerCredentials = New-Object powershellcredential -ArgumentList @(
    UserName = $null
    Password = $ComputerPassword | ConvertTo-SecureString -AsPlainText -Force
)

$Options = 'UnsecuredJoin,PasswordPass,JoinReadOnly'

Add-Computer -Domain $Domain -Options $Options -Credential $ComputerCredentials -Server $Rodc -Restart

Voila! If everything went well you should now be able to log in to this computer using domain credentials and access domain resources. In my experience it may take one or two reboots before Group Policies start applying properly.

Future Concerns

  • You’ll probably want some way of automating computer password rotation since the computer can no longer do it automatically.