Once the most common problems that plagues Windows system administrators is trusted, Active Directory computers seemingly fall off the domain. In this guide, you're going to learn every trick I've come across in my 20+ years managing Active Directory and how to automate it with PowerShell.

The trust relationship between this workstation and the primary domain failed

Chances are an Active Directory-joined computer that's no longer be trusted on a domain is because the password the local computer has does not match the password stored in Active Directory.

Trust relationship failed

The two passwords must be in sync for a trust relationship to be created. If they aren't in sync, you will receive the infamous error message The trust relationship between this workstation and the primary domain failed.

Unfortunately, there has never been a single solution that myself and other sysadmins have found that works 100% of the time. That's why I wrote this guide.

This guide is intended to be a single repository for every, single way to fix this issue once and for all and to automate the process with PowerShell.

Active Directory Computer Account Passwords

When a new computer is added to Active Directory, a computer account is created with a password. That password is valid for 30 days, by default. After 30 days, it automatically changes.

Viewing Existing Policies

You can view the domain-wide policy by opening up the Group Policy Management Console, clicking on the Default Domain Policy and navigating to Computer Configuration > Windows Settings > Security Settings > Local Policies > Security Options and looking for the policy called Domain member: Maximum machine account password age.

Computer Account Password Age Policy

You can find the policy defined for a local computer by navigating to the HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters registry key and looking at the MaximumPasswordAge value.

Local Computer Account Password Age Registry Value

While you're in there, you can disable the local computer changing the password at all by setting the DisablePasswordChange value to 1.

When the computer account changes, both the local computer and AD computer account should change their passwords together. AD knows the current one and the previous one in case they become out of sync for a brief period.

The Computer Account Password Change Process

When things are normally working, using the Netlogon Windows service, the computer initiates a password change automatically. This happens during a computer reboot or when the computer account needs to authenticate to AD.

Using the Netlogon Windows service, the local computer initiates a password change sequence. The computer first initiates a password change on a domain controller. If that is successful, it then attempts to change the local password to match within the HKLM\SECURITY\Policy\Secrets<hostname>.ACC registry key.

Normally this process works great even if the computer is shut off or offline for longer than 30 days because the local computer initiates a password change.

However, a problem occurs when:

  • the computer changes the AD computer account but unable to change the local password
  • the computer is reimaged without running sysprep
  • the OS is reinstalled and is attempting to authenticate with the old, enabled, AD computer account
  • ...and more?

Verifying the Problem

Once you know the problem exists, how do you replicate it or at least have a method to determine which computers have the problem? You could try to interactively log into each computer but that's not scalable and I don't want to get up from my desk!

Let's build a script we can run both locally and remotely to determine which computers in the domain have this problem.

First of all, since you're assuming domain authentication isn't working, you'll need to know a local user account in the administrators group. I hope you know your local administrator password!

nltest (Command-Line Tool)

nltest is an old-school command-line tool that will test a trust relationship for a computer. This tool is installed when you install RSAT or is available directly on a domain controller.

You can verify a trust relationship on a computer when logged on the computer by running:

> nltest /sc_verify:<your domain FQDN>
WARNING: This method isn't recommended because nltest only works in the user context in which it was launched. If the computer has a broken trust and you're logged in as a local user, it will attempt to connect to the domain using the local user's credentials. This results in an access denied error.

netdom (Command-Line Tool)

netdom is another command-line tool you can use to verify a trust relationship. This tool is also installed when you install RSAT or is available directly on a domain controller.

You can verify a trust using netdom verify by providing:

  • the name of the computer name to verify
  • FQDN of the domain
  • username to authenticate the request
  • password of the user account

Below is an example:

> netdom verify MYCOMPUTER /Domain:domain.local /UserO:abertram /PasswordO:*

By providing the value of * to the PasswordO parameter, netdom will prompt for the password.

Test-ComputerSecureChannel (PowerShell)

One of the best ways to verify a broken trust relationship is to use the Test-ComputerSecureChannel cmdlet. This PowerShell cmdlet comes with Windows 10 and is easier to use.

The Test-ComputerSecureChannel cmdlet works locally on a Windows 10 computer. When logged into the computer interactively, open up a PowerShell console and run Test-ComputerSecureChannel without any parameters. It will return either True or False depending on if the trust is valid.

PS51> Test-ComputerSecureChannel
True

You may also specify a particular domain controller to confirm the passwords are in sync by using the Server parameter.

PS51> Test-ComputerSecureChannel -Server 'DC.domain.local'
False

This cmdlet is straightforward to use and has a Repair option but we'll save a demonstration of that for the fixing section.

If you know the local administrator password of those computers you'd like to check and PowerShell Remoting is enabled on them, you can also use the Invoke-Command cmdlet to run this cmdlet remotely on one or many computers at once.

PS51> Invoke-Command -ComputerName PC1, PC2, PC3 -ScriptBlock { Test-ComputerSecureChannel }

Checking Trust Relationships in Bulk

Now that you know how to remotely check a trust relationship, here's a code snippet you can use to check all of your AD computers! In this script, I'm first testing to ensure the computer is online. If not, it will return Offline. If so, it will run Test-ComputerSecureChannel on each computer and either return True or False.

$localCredential = Get-Credential
 
@(Get-AdComputer -Filter *).foreach({
 
   $output = @{ ComputerName = $_.Name }
 
   if (-not (Test-Connection -ComputerName $_.Name -Quiet -Count 1)) { $output.Status = 'Offline'
   } else {
       $trustStatus = Invoke-Command -ComputerName $_.Name -ScriptBlock { Test-ComputerSecureChannel } -Credential $localCredential
       $output.Status = $trustStatus
   }
 
   [pscustomobject]$output
 
})
Testing trust relationships in bulk

Knowing and understanding the problem is the first step but how do you fix it? You now know that you need to get the computer account stored on the local computer the same as the computer account stored in AD.

There are many different "solutions" out there for this problem. These solutions can be performed via the GUI, via PowerShell or via old-school command-line tools.

  1. Reset the computer account password in AD
  2. Resetting the local computer account password
  3. Unjoin and rejoin the Windows computer
  4. Remove the computer account completely and rejoin the Windows computer

That's a lot of options! In this guide, we're going to focus on fixing this problem with PowerShell and command-line tools (for completeness). If you aren't already using PowerShell, you should!

Fixing the Problem: Resetting Computer Passwords

netdom (Command-Line Tool)

A trust can be repaired by using the old-school netdom command-line tool. If you're logged into the computer locally as an administrative user, you can run netdom resetpwd to initiate the password reset sequence as shown below.

In this example, DC is the name of the domain controller, abertram is the name of the Active Directory user account with rights to reset the computer account and * is a placeholder for the user account password which will prompt for the password.

netdom resetpwd /s:DC /ud:abertram /pd:*

Reset-ComputerMachinePassword (PowerShell)

One of the best ways to fix a trust relationship is by using the Reset-ComputerMachinePassword cmdlet. This cmdlet is run on the local computer and will initiate a password reset sequence. It's syntax couldn't be simpler.

PS51> Reset-ComputerMachinePassword

If you'd like to specify a particular DC to reset, you can specify it using the Server parameter along with an option credential (it will default to the local user).

The below example will prompt for an AD username and password and attempt to reset the password on the local computer and the DC domain controller.

PS51> Reset-ComputerMachinePassword -Server DC -Credential (Get-Credential)

This can also be run remotely by using Invoke-Command if PowerShell Remoting is available on the computer. Below, I'm obtaining the username and password for the local administrator account on the computer. I'm also obtaining the credential that has rights to reset this computer's AD account password. I'm then passing $domainCredential into the remote session using the $using construct.

$localAdminCredential = Get-Credential
$domainCredential = Get-Credential

PS51> Invoke-Command -Computername MYCOMPUTER -Credential $localAdminCredential -ScriptBlock { Reset-ComputerMachinePassword -Server DC -Credential $using:domainCredential }
Note that this also works even if the computer account has been removed from Active Directory. Create a computer account with the same name and Reset-ComputerMachinePassword will ensure the password is synced up.

Resetting Local Computer Account Passwords in Bulk

Using a handy foreach loop, we can run Reset-ComputerMachinePassword in bulk too.

$localAdminCredential = Get-Credential
$domainCredential = Get-Credential
 
@(Get-AdComputer -Filter *).foreach({
 
   $output = @{ ComputerName = $_.Name }
 
   if (-not (Test-Connection -ComputerName $_.Name -Quiet -Count 1)) { $output.Status = 'Offline'
   } else {
       $pwChangeOutput = Invoke-Command -Computername $_.Name -Credential $localAdminCredential -ScriptBlock { Reset-ComputerMachinePassword -Server DC -Credential $using:domainCredential }
       $output.PasswordChangeOutput = $pwChangeOutput
   }
 
   [pscustomobject]$output
 
})
Resetting computer account passwords in bulk

Test-ComputerSecureChannel -Repair (PowerShell)

Another way to initiate the password change process is to run Test-ComputerSecureChannel but this time use the Repair option. From what I can tell, this process is identical to using Reset-ComputerMachinePassword. On a the computer console use the Repair parameter and the Credential parameter. �

PS51> Test-ComputerSecureChannel -Repair -Credential (Get-Credential)

Be sure to always use the Credential parameter here. If you don't, similar with the nltest utility, it will attempt to use the local account and won't work.

Repair Trust Relationships in Bulk

Drop this command into the handy foreach loop we've been using and Bob's your uncle!

$localAdminCredential = Get-Credential
$domainCredential = Get-Credential
 
@(Get-AdComputer -Filter *).foreach({
 
   $output = @{ ComputerName = $_.Name }
 
   if (-not (Test-Connection -ComputerName $_.Name -Quiet -Count 1)) { $output.Status = 'Offline'
   } else {
       $repairOutput = Invoke-Command -Computername $_.Name -Credential $localAdminCredential -ScriptBlock { Test-ComputerSecureChannel -Repair -Credential $using:domainCredential }
       $output.RepairOutput = $repairOutput
   }
 
   [pscustomobject]$output
 
})
Resetting computer account passwords in bulk

Fixing the Problem: Rejoining the Domain

If resetting the computer account passwords don't work for you, there's always the nuclear option. You can rejoin a computer to the Active Directory domain. Although not necessary all the time, there have been times I've had to use this approach.

Note that I've heard some reports that an disjoin isn't necessary. You may be able to get away by just forcing a new join. YMMV.

You could log onto the computer via a local administrative account, go to System Properties, click on Change, set it to a workgroup, reboot and then set it back to the domain. Notice how I mention could. Don't do this. It's a waste of your time when you can automate it PowerShell.

Joining a domain manually

There are two ways I've found that you can use PowerShell to unjoin a domain and use PowerShell to join a domain.

Using CIM

You can join a domain with PowerShell (and unjoin it) using the Win32_ComputerSystem CIM class has two methods that allow you to unjoin a computer and join a computer to a domain called UnJoinDomainOrWorkgroup() and JoinDomainOrWorkGroup.

Since this is CIM, you can run this just as easily remotely as you can locally. Since I assume you'd prefer to run this remotely from the comfort of your desk, here's a code snippet that does just that.

$computername = 'PITA'

$instance = Get-CimInstance -ComputerName $computername -ClassName 'Win32_ComputerSystem'

$invCimParams = @{
    MethodName = 'UnjoinDomainOrWorkGroup'
    Arguments = @{ FUnjoinOptions=0;Username="Administrator";Password="mypassword" }
}
$instance | Invoke-CimMethod @invCimParams
Notice the FUnjoinOptions parameter above. I've chosen to specify 4 here. This performs the default behavior when unjoining a computer manually. This option disables the computer account in Active Directory (if it can find one). If you'd rather not have this behavior, you can use option 0 here.

Once the computer is unjoined, you can then rejoin the domain using the JoinDomainOrWorkGroup() method.

$computername = 'PITA'

$instance = Get-CimInstance -ComputerName $computername -ClassName 'Win32_ComputerSystem'

$invCimParams = @{
    MethodName = 'JoinDomainOrWorkGroup'
    Arguments = @{ FJoinOptions=3;Name=mydomain.local;Username="mydomain\domainuser";Password="mypassword" }
}
$instance | Invoke-CimMethod @invCimParams
Notice the FJoinOptions parameter above. I've chosen to specify 3 here. This performs the default behavior when joining a computer manually. This option creates an AD computer account. You can find a few other options like adding to a specific OU via the JoinDomainOrWorkgroup documentation.
TIP: You can also unjoin and rejoin many computers at once via this method by specifying multiple computers via the ComputerName parameter on Get-CimInstance.

Using the Remove-Computer and Add-Computer Cmdlets

You can also use built-in PowerShell cmdlets to unjoin and join a computer to a domain with PowerShell. You can use the Remove-Computer and Add-Computer cmdlets.

To unjoin a computer with PowerShell, log onto the computer console and use the Remove-Computer cmdlet. Provide the domain credential with permissions to unjoin the computer. You can also specify the Restart parameter to force a restart after the unjoin and Force to not prompt for confirmation.

PS51> Remove-Computer -UnjoinDomaincredential (Get-Credential) -Restart -Force

Once the computer has been rebooted, you can then use the Add-Computer cmdlet to join the computer to the domain with PowerShell. You can use the Add-Computer cmdlet remotely by providing the ComputerName parameter. You'll also use local user credential to make the connection and the domain credential to authenticate to the domain.

$localCredential = Get-Credential
$domainCredential = Get-Credential

Add-Computer -ComputerName PITA -LocalCredential $localCredential -DomainName domain.local -Credential $domainCredential -Restart -Force

Automagical Domain Unjoin and Rejoin

Because I had to do this process way too many times, I built a PowerShell script that does everything for you. If you provide it the name of the computer, it will:

  • Unjoin the computer
  • Reboot and wait to come back up
  • Join the computer
  • Reboot and wait to come back up

You can try out this script via GitHub.

Summary

You should now have a full understanding of the problem and multiple solutions to the infamous The trust relationship between this workstation and the primary domain failed error message. I hope this guide provided you with some insights and allowed you to come up with some solutions of your own to problem of computers falling of the domain!

I've missed anything important or made a mistake, please let me know. I'll fix it ASAP.

Further Reading

Be sure to check out some other related posts!