修复“计算机与主域之间的信任关系失败”

一度困扰Windows系统管理员的最常见问题之一是信任的问题,Active Directory计算机似乎脱离了域。臭名昭著的“此工作站与主域之间的信任关系失败”错误是司空见惯的。

在这个指南中,您将学习到我在管理Active Directory 20多年中所遇到的每一个技巧,以及如何使用PowerShell进行自动化。

此工作站与主域之间的信任关系失败”错误消息

当AD域不再信任计算机时,很可能是因为本地计算机的密码与Active Directory中存储的密码不匹配。

The Trust Relationship Between This Workstation and the Primary Domain Failed

这两个密码必须同步才能让AD信任计算机。如果它们不同步,您将收到臭名昭著的错误消息“此工作站与主域之间的信任关系失败”

不幸的是,我和其他系统管理员从未找到一种解决方案能够100%有效。这就是我写这篇指南的原因。

本指南旨在成为解决此问题的每一个方法的单一存储库,并使用PowerShell自动化该过程。

Active Directory计算机帐户密码

当将新计算机添加到Active Directory时,会创建一个带有密码的计算机账户。该密码默认有效期为30天。30天后,它会自动更改。如果更改了密码但客户端密码没有更改,则会收到“此工作站与主域之间的信任关系失败”错误消息。

查看现有策略

您可以通过打开Group Policy管理控制台(GPMC)来查看域范围策略。在GPMC中,点击默认域策略,然后导航至计算机配置 –> Windows设置 –> 安全设置 –> 本地策略 –> 安全选项

进入安全选项后,寻找名为域成员: 最大机器账户密码年龄

Computer Account Password Age Policy

在加入AD的计算机上,打开regedit并导航至HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters注册表键,并查找如下所示的MaximumPasswordAge值。

Local Computer Account Password Age Registry Value

在这里,您可以通过将DisablePasswordChange值设置为1来完全禁用本地计算机更改密码。

当计算机账户更改时,本地计算机和AD计算机账户应同时更改密码。AD知道当前密码和上一个密码,以防它们在短时间内不同步。

计算机账户密码更改过程

当事物正常运作时,使用Netlogon Windows服务,计算机会自动启动密码更改。这通常发生在计算机重新启动或计算机对象需要对AD进行身份验证时。

使用Netlogon Windows服务,本地计算机启动密码更改序列。计算机首先在域控制器上启动密码更改。如果成功,然后尝试更改本地密码以匹配HKLM\SECURITY\Policy\Secrets<hostname>.ACC注册表键。

通常,即使计算机关闭或离线时间超过30天,此过程也会正常工作,因为本地计算机会启动密码更改。

但是,当出现以下问题时会发生问题:

  • 计算机更改了AD计算机帐户但无法更改本地密码
  • 计算机在未运行Sysprep的情况下重新映像
  • 重新安装操作系统并尝试使用旧的启用的AD计算机帐户进行身份验证
  • …等等?

如果发生上述任何情况,您将看到“此工作站与主域之间的信任关系失败”错误消息。

验证问题

一旦您知道问题存在,如何复制它或至少有一种方法来确定哪些计算机存在问题呢?您可以尝试交互式登录每台计算机,但这不可扩展,而且我不想离开我的办公桌!

让我们构建一个脚本,既可以在本地运行,也可以远程运行,以确定域中的哪台计算机出现了这个问题,从而彻底消除“此工作站与主域之间的信任关系失败”错误消息。

首先,由于您假设域身份验证不起作用,您需要知道管理员组中的本地用户帐户。希望您知道本地管理员密码!

nltest(命令行工具)

nltest是一款老式的命令行工具,用于测试计算机的信任关系。安装RSAT时将安装此工具,或者它可以直接在域控制器上使用。

您可以在计算机上登录后通过运行以下命令来验证计算机上的信任关系:

> nltest /sc_verify:<your domain FQDN>

警告:不推荐使用此方法,因为nltest仅在启动它的用户上下文中工作。如果计算机的信任关系已损坏,并且您以本地用户身份登录,则它将尝试使用本地用户的凭据连接到域。这将导致拒绝访问错误。

netdom(命令行工具)

netdom 是另一个您可以使用的命令行工具来验证信任关系。当您安装 RSAT 或直接在域控制器上安装时,也会安装此工具。

您可以使用 netdom verify 来验证信任,提供:

  • 要验证的计算机名称
  • 域的完全限定域名(FQDN)
  • 用于验证请求的用户名
  • 用户帐户的密码

以下是一个示例:

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

通过将 * 值提供给 PasswordO 参数,netdom 将提示输入密码。

Test-ComputerSecureChannel(PowerShell)

解决“此工作站与主域之间的信任关系失败”问题的最佳方法之一是使用 Test-ComputerSecureChannel 命令。这个 PowerShell 命令配备于 Windows 10,并且更易于使用。

Test-ComputerSecureChannel cmdlet在Windows 10计算机上本地运行。当交互登录到计算机后,打开PowerShell控制台并运行Test-ComputerSecureChannel而不带任何参数。它将根据信任是否有效返回True或False。

PS51> Test-ComputerSecureChannel
True

您还可以使用Server参数指定特定的域控制器来确认密码是否同步。

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

此cmdlet易于使用,并带有Repair选项,但我们将在修复部分保存演示。

如果您知道这些计算机的本地管理员密码并且已启用了PowerShell远程操作,还可以使用Invoke-Command cmdlet。通过使用Invoke-Command cmdlet,您可以一次在一个或多个计算机上远程运行Test-ComputerSecureChannel

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

批量检查信任关系

现在您知道如何远程检查信任关系了,这里有一个代码片段,您可以用来检查所有AD计算机!在此脚本中,我首先测试以确保计算机处于联机状态。如果不是,它将返回离线。如果是,它将在每台计算机上运行Test-ComputerSecureChannel并返回TrueFalse

Testing trust relationships in bulk
$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 })

了解并理解问题是第一步,但如何修复呢?您现在知道需要将本地计算机上存储的计算机帐户与存储在AD中的计算机帐户相同。

有许多针对“工作站与主域之间的信任关系失败”问题的不同“解决方案”。这些解决方案可以通过图形界面、PowerShell或老式命令行工具执行。

  1. 在AD中重置计算机帐户密码
  2. 重置本地计算机帐户密码
  3. 取消加入并重新加入Windows计算机
  4. 彻底删除计算机帐户并重新加入Windows计算机

选择很多!在本指南中,我们将专注于使用PowerShell和命令行工具(为了完整性)解决此问题。如果您尚未使用PowerShell,建议您开始使用!

解决问题:重置计算机密码

netdom(命令行工具)

A trust can be repaired and the “the trust relationship between this workstation and the primary domain failed” error message can be eliminated 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.

在此示例中:

  • DC是域控制器的名称
  • abertram是具有重置计算机帐户权限的Active Directory用户帐户的名称
  • *是提示输入用户帐户密码的占位符。
> netdom resetpwd /s:DC /ud:abertram /pd:*

Reset-ComputerMachinePassword(PowerShell)

修复信任关系的最佳方式之一是使用Reset-ComputerMachinePassword cmdlet。此cmdlet在本地计算机上运行,将启动密码重置序列。其语法非常简单。

PS51> Reset-ComputerMachinePassword

如果您想指定要重置的特定DC,可以使用Server参数并提供选项凭据(它将默认为本地用户)。

以下示例将提示输入AD用户名和密码,并尝试重置本地计算机和DC域控制器上的密码。

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

如果计算机上启用了PowerShell远程管理,还可以通过使用Invoke-Command进行远程运行。下面,我正在获取计算机上本地管理员帐户的用户名和密码。我还获取了具有重置此计算机AD帐户密码权限的凭据。然后,我使用$using结构将$domainCredential传递到远程会话中。

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

PS51> Invoke-Command -Computername MYCOMPUTER -Credential $localAdminCredential -ScriptBlock { Reset-ComputerMachinePassword -Server DC -Credential $using:domainCredential }

请注意,即使计算机帐户已从Active Directory中删除,此方法也有效。创建一个具有相同名称的计算机帐户,然后使用Reset-ComputerMachinePassword将确保密码同步。

批量重置本地计算机帐户密码

想要一次性解决大量计算机出现“此工作站与主域之间的信任关系失败”的问题吗?没问题。使用方便的foreach循环,我们也可以批量运行Reset-ComputerMachinePassword

Resetting computer account passwords in bulk
$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 })

Test-ComputerSecureChannel -Repair(PowerShell)

另一种启动密码更改流程的方法是运行Test-ComputerSecureChannel,但这次使用Repair选项。据我所知,这个过程与使用Reset-ComputerMachinePassword是相同的。在计算机控制台上使用Repair参数和Credential参数。

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

确保在这里始终使用Credential参数。如果不这样做,类似于nltest实用工具,它将尝试使用本地帐户而无法工作。

批量修复信任关系

将此命令放入我们一直在使用的方便的foreach循环中,问题就解决了!

Resetting computer account passwords in bulk
$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 })

解决问题:重新加入域

如果重置计算机帐户密码对您无效,总是有核选择。您可以将计算机重新加入Active Directory域。虽然并非始终必要,但有时我不得不使用这种方法。

请注意,我听说过有些报告称取消加入并不是必要的。您可以尝试强制新加入。结果可能有所不同。

可以

  • 通过本地管理员帐户登录计算机
  • 转到系统属性
  • 点击更改
  • 将其设置为工作组
  • 重新启动
  • 将其重新设置为域

注意我提到可以。不要这样做。当您可以使用PowerShell自动化时,这是浪费时间。

有两种方法可以使用 PowerShell 来取消加入域并使用 PowerShell 加入域。

使用 CIM

您可以使用 Win32_ComputerSystem CIM 类来加入域(并取消加入)。该类具有两种方法,允许您取消加入域并将计算机加入域,分别称为 UnJoinDomainOrWorkgroup()JoinDomainOrWorkGroup

由于这是 CIM,您可以像在本地运行一样轻松地远程运行它。由于我假设您更喜欢从您的办公桌舒适地远程运行此命令,因此这里有一个可以做到这一点的代码片段。

“工作站与主域之间的信任关系失败”错误消失了!

$computername = 'PITA'

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

$invCimParams = @{
    MethodName = 'UnjoinDomainOrWorkGroup'
    Arguments = @{ FUnjoinOptions=0;Username="Administrator";Password="mypassword" }
}
$instance | Invoke-CimMethod @invCimParams

请注意上面的 FUnjoinOptions 参数。我选择在此处指定 4。这将执行手动取消加入计算机时的默认行为。此选项会禁用 Active Directory 中的计算机帐户(如果可以找到)。如果您不希望出现此行为,可以在此处使用选项 0。

计算机取消加入后,您可以使用 JoinDomainOrWorkGroup() 方法重新加入域。

$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

注意上面的FJoinOptions参数。我选择在这里指定3。这会在手动加入计算机时执行默认行为。此选项将创建一个AD计算机帐户。您可以在JoinDomainOrWorkgroup文档中找到一些其他选项,比如添加到特定的OU。

提示:您还可以通过在Get-CimInstance上的ComputerName参数中指定多台计算机,一次取消关联并重新加入多台计算机。

使用Remove-Computer和Add-Computer Cmdlets

您还可以使用内置的PowerShell cmdlets使用PowerShell将计算机取消关联并加入域。您可以使用Remove-ComputerAdd-Computer cmdlets。

要使用PowerShell取消加入计算机,请登录计算机控制台并使用Remove-Computer cmdlet。提供具有取消加入计算机权限的域凭据。您还可以指定Restart参数,在取消加入后强制重新启动,并使用Force以避免确认提示。

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

计算机重新启动后,您可以使用Add-Computer cmdlet使用PowerShell将计算机加入域。通过提供ComputerName参数,您还可以远程使用Add-Computer cmdlet。您将使用本地用户凭据建立连接,并使用域凭据进行域身份验证。

当计算机重新启动后,希望您不再收到“此工作站与主域之间的信任关系失败”错误消息。

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

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

自动域取消加入和重新加入

因为我不得不执行这个过程太多次,我构建了一个PowerShell脚本,可以为您完成所有操作。如果您提供计算机名称,它将:

  • 取消加入计算机
  • 重新启动并等待重新启动
  • 加入计算机
  • 重新启动并等待重新启动

您可以通过GitHub尝试此脚本。

摘要

你现在应该对这个问题有了全面的了解,并对臭名昭著的“计算机与主域之间的信任关系失败”错误消息有了多个解决方案。希望本指南为你提供了一些见解,并让你对计算机脱离域的问题有了一些解决方案!

进一步阅读

请务必查看一些其他相关的帖子!

Source:
https://adamtheautomator.com/the-trust-relationship-between-this-workstation-and-the-primary-domain-failed/