This script can be used to repair the trust relationship of a PC to an Active Directory domain.
# This script will reset the machine password in an effort to restore the trust relationship to a DC
#Requires -RunAsAdministrator
# If the computer object does not yet exist for this computer a new object will be created.
# Set this $ou variable to the OU of where the object will be created.
$ou = 'OU=Computers,DC=my,DC=domain,DC=com'
# Check if the PC is on a domain already
Write-Host -ForegroundColor Gray 'Testing if PC is on a domain...'
try {
$system = Get-CimInstance -ClassName Win32_ComputerSystem -ErrorAction Stop
$domain = $system.Domain
$hostname = $system.DNSHostName
$joined = $system.PartOfDomain
}
catch {
$message = $_.Exception.message
Write-Error 'Exception recieved while retrieving computer information with WMI:'
throw $message
}
if ( $joined -ne $True ) {
Write-Error 'PC does not appear to be a member of a domain - join the PC to a domain first.'
break
} else {
Write-Host -ForegroundColor Gray "PC name $hostname is a member of domain '$domain'"
}
function Test-DomainWorking {
Write-Host -ForegroundColor Gray 'Running Test-ComputerSecureChannel...'
if ( Test-ComputerSecureChannel ) {
Write-Host -ForegroundColor Gray 'Test-ComputerSecureChannel passed'
} else {
Write-Host -ForegroundColor Gray 'Test-ComputerSecureChannel failed'
return $False
}
Write-Host -ForegroundColor Gray 'Querying domain status with nltest.exe...'
try {
$nltest = (nltest.exe /sc_query:$($domain) | Out-String) -split "`n" | Select-String "0 0x0 NERR_Success"
}
catch {
$message = $_.Exception.message
Write-Error 'Exception running nltest.exe:'
Write-Error $message
return $False
}
if ( $nltest ) {
Write-Host -ForegroundColor Gray 'nltest.exe returned success'
return $True
} else {
Write-Host -ForegroundColor Gray 'nltest.exe test failed'
return $False
}
}
# Check if there is any action required
Write-Host -ForegroundColor Yellow 'Testing domain connection...'
if ( Test-DomainWorking ) {
Write-Host -ForegroundColor Green 'Secure channel is working. If there is a problem logging in to domain accounts you may need to restart the computer and run this script again.'
break
}
Write-Host -ForegroundColor DarkRed 'Secure channel test failed, proceeding with repair'
# Get credentials with modification access to the computer object
Write-Host -ForegroundColor Yellow 'Requesting AD account login...'
$credential = Get-Credential -Message 'Please enter your AD login that has access to modify this computer object. You must use the format "<DOMAIN>\<USERNAME>" eg. INTERNAL\myuser'
if ( $credential ) {
Write-Host -ForegroundColor Green 'Got login credentials'
} else {
Write-Host -ForegroundColor DarkRed 'Credentials must be provided for this script to work.'
break
}
# Get the computer object from Active Directory
Write-Host -ForegroundColor Yellow 'Checking for existing computer object in Active Directory...'
try {
$adsi = New-Object adsi("LDAP://$($system.domain)",$credential.UserName,$credential.GetNetworkCredential().password)
$object = (New-Object adsisearcher($adsi,"(&(cn=$($hostname))(objectCategory=Computer))")).FindOne()
$computer = $object.GetDirectoryEntry()
}
catch {
$message = $_.Exception.message
$type = $_.Exception.GetType().fullname
if ( $type -eq 'System.Management.Automation.MethodInvocationException' ) {
Write-Error 'The credentials entered may be incorrect (see full message below for details). Make sure the username is in the format "<DOMAIN>\<USERNAME>".'
} else {
Write-Error 'Exception trying to retrieve computer object:'
}
throw $message
}
# Request computer to be created if it doesn't exist or verify the object is enabled if it does exist
if ( $computer.distinguishedname ) {
Write-Host -ForegroundColor Green "Computer object found: $($computer.distinguishedname)"
# Check the current status of the computer to see if it is disabled
if ( $computer.useraccountcontrol -eq '4096' ) {
Write-Host -ForegroundColor Green 'Computer object is enabled already'
} elseif ( $computer.useraccountcontrol -eq '4098' ) {
Write-Host -ForegroundColor Yellow 'Computer object is currently in the disabled state, attempting to enable...'
try {
$computer.userAccountControl = 4096
$computer.setInfo()
$computer.refreshcache()
}
catch {
$message = $_.Exception.message
Write-Error 'Exception trying to update computer object, possibly the account you are using does not have permissions to update it:'
throw $message
}
if ( $computer.useraccountcontrol -eq '4096' ) {
Write-Host -ForegroundColor Green 'Computer object enabled'
Write-Host -ForegroundColor Yellow 'Checking to see if problem has been resolved...'
if ( Test-DomainWorking ) {
Write-Host -ForegroundColor Green 'Repair process complete. It is recommended that the computer is rebooted now.'
break
} else {
Write-Host -ForegroundColor DarkRed 'Issue still occurs, continuing repair'
}
} else {
Write-Error 'Computer object does not have the correct status after update, this requires fixing manually.'
break
}
} else {
Write-Host -ForegroundColor DarkRed "Computer object has an account status that is not expected: '$($computer.useraccountcontrol)'"
Write-Host -ForegroundColor DarkRed 'The state for the object should be 4096 if it is active. Please fix this manually then try running this script again.'
break
}
} else {
# Computer object does not exist in AD, leave the domain and join it again
Write-Host -ForegroundColor Yellow "Attempting to leave domain..."
try {
Remove-Computer -WorkgroupName TEMP -UnjoinDomaincredential $credential
Write-Host -ForegroundColor Green 'Computer has left the domain'
}
catch {
$message = $_.Exception.message
Write-Error 'Exception while leaving domain:'
Write-Error $message
}
# Try to join domain again
Write-Host -ForegroundColor Yellow "Attempting to re-join domain..."
try {
Add-Computer -Credential $credential -DomainName $domain -OUPath $ou -Options AccountCreate -Force -ErrorAction Stop
Write-Host -ForegroundColor Green "Computer object for $hostname has been created in OU $ou. Please move this to the correct place."
}
catch {
$message = $_.Exception.message
Write-Error 'Exception while joining domain. Please reboot the PC and leave/join the domain manually. Exception:'
throw $message
}
Write-Host -ForegroundColor Green 'Computer has joined domain. The PC will be rebooted in 30 seconds unless you push "Control + C" or "Control + Break" now.'
Write-Host -ForegroundColor Green 'If the problem still occurs after reboot try running this script again.'
Write-Host -ForegroundColor Yellow 'Reboot in 30 seconds...'
Start-Sleep -Seconds 10
Write-Host -ForegroundColor Yellow 'Reboot in 20 seconds...'
Start-Sleep -Seconds 10
Write-Host -ForegroundColor Yellow 'Reboot in 10 seconds...'
Start-Sleep -Seconds 10
Write-Host -ForegroundColor Yellow 'Proceeding with reboot'
try {
Restart-Computer -Confirm:$False -Force
}
catch {
$message = $_.Exception.message
Write-Error 'Exception while rebooting computer.'
throw $message
}
break
}
# Try using Test-ComputerSecureChannel with the repair flag
Write-Host -ForegroundColor Yellow 'Running Test-ComputerSecureChannel with repair parameter...'
try {
$result = Test-ComputerSecureChannel -Repair -Credential $credential -ErrorAction Stop -Confirm:$False
}
catch {
$message = $_.Exception.message
Write-Error 'Test-ComputerSecureChannel returned exception while attempting repair:'
Write-Error $message
}
# If the repair worked execute a check to verify that the problem is resolved
if ( $result -eq $True ) {
Write-Host -ForegroundColor Green 'Test-ComputerSecureChannel repair returned success'
Write-Host -ForegroundColor Yellow 'Validating repair fixed the problem...'
if ( Test-DomainWorking ) {
Write-Host -ForegroundColor Green 'Repair process complete. It is recommended that the computer is rebooted now.'
break
} else {
Write-Host -ForegroundColor DarkRed 'Test-ComputerSecureChannel repair did not fix the issue.'
}
} else {
Write-Host -ForegroundColor DarkRed 'Test-ComputerSecureChannel repair failed'
}
# Repair did not fix the issue so try an alternative method
Write-Host -ForegroundColor Yellow 'Attempting to reset the machine password...'
$done = $False
try {
Reset-ComputerMachinePassword -Credential $credential -Confirm:$False -ErrorAction Stop
Write-Host -ForegroundColor Green 'Machine password reset successfully'
$done = $True
}
catch {
$message = $_.Exception.message
Write-Error 'Reset-ComputerMachinePassword returned exception while attempting repair:'
Write-Error $message
}
# Check to see if the repair worked again
if ( $done -eq $True ) {
if ( Test-DomainWorking ) {
Write-Host -ForegroundColor Green 'Repair process complete. It is recommended that the computer is rebooted now.'
break
}
}
Write-Error 'Repair failed. If this is the first time attempting to run this script try rebooting the PC and then running this script again.'
Write-Error 'If you have already tried running this script again after a reboot you will need to resolve this issue manually.'
Set the $ou
variable to suite your environment. This variable will only be used to store the computer object if it has to be re-added to the domain.