1

所以我有一个 XP Pro 工作站报告“Windows 无法连接到域,因为域控制器已关闭或不可用,或者因为找不到您的计算机帐户。请稍后再试。如果此消息继续出现,请联系您的系统管理员寻求帮助。” 使用域凭据登录时。要手动修复此问题,我只需使用本地管理员帐户登录,将其放入工作组,然后将其重新添加到域中。然而,考虑到这个问题在我的工作中经常出现,这个过程可能需要相当长的时间。我正在尝试做的是以编程方式自动化删除/重新加入过程。以下代码有效,但前提是计算机正确位于域或工作组中,而不是像现在这样处于不确定状态。

Const JOIN_DOMAIN             = 1
Const ACCT_CREATE             = 2
Const ACCT_DELETE             = 4
Const WIN9X_UPGRADE           = 16
Const DOMAIN_JOIN_IF_JOINED   = 32
Const JOIN_UNSECURE           = 64
Const MACHINE_PASSWORD_PASSED = 128
Const DEFERRED_SPN_SET        = 256
Const INSTALL_INVOCATION      = 262144

Const WbemAuthenticationLevelPktPrivacy = 6

'On Error Resume Next 

SystemName = "SystemName"
strNamespace = "root\cimv2"
ComputerBLogin = "LoginB"
ComputerBPass = "PassB"
ComputerALogin = "LoginA"
ComputerAPass = "PassA"
DomainName = "domain.com"
OU = "OU=desiredou,DC=domain,DC=com"

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & SystemName & "\root\cimv2")

If Err.Number <> 0 Then

    Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objwbemLocator.ConnectServer(SystemName, strNamespace, ComputerBLogin, ComputerBPass)

    objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy

    Err.Clear
End IF

Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

For Each objComputer in colComputers
    Return = objComputer.UnJoinDomainOrWorkGroup(NULL, NULL)
    Return = objComputer.JoinDomainOrWorkGroup("WORKGROUP", NULL, NULL)
    If Err.Number <> 0 Then
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup (SystemName & " could not be dropped to the workgroup!" & vbCr &_
                "Error: " & Err.Description,, "Title", 0 + 16)
    Else
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup (SystemName & " was successfully dropped to the WORKGROUP!",, "Title", 0 + 64)
    End If
Next

For Each objComputer in colComputers
    ReturnValue = objComputer.JoinDomainOrWorkGroup(DomainName, ComputerAPass, ComputerALogin, OU, JOIN_DOMAIN + ACCT_CREATE)

    If Err.Number <> 0 Then
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup ("Unable to join " & SystemName & " to the domain! Please join manually.",, "Title", 0 + 16)
    Else
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup ("Domain joining was successful!",, "Title", 0 + 64)
    End If
Next

当脚本到达第 24 行时:

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & SystemName & "\root\cimv2")

它错误“远程服务器机器不存在或不可用:'GetObject'”。如果机器在域中正确,该行将正常工作。AD 对象确实存在。如果出现此错误,我将其编码为在第 29 行使用本地管理员凭据登录机器:

Set objWMIService = objwbemLocator.ConnectServer(SystemName, strNamespace, ComputerBLogin, ComputerBPass)

这将与“SWbemLocator:访问被拒绝”出错。

因此,当机器处于这种状态时,使用我熟悉的两种方法都无法访问 WMI。在我的研究中,似乎“工作站和域之间的信任关系已经失败”,但对我来说,这并不能解释为什么我无法使用本地管理员凭据登录。

我不想求助于 NETDOM,但我还是尝试了。它也错误地谈论失败的信任关系。

所以我的问题是:
A)当出现此错误消息时,有没有办法以编程方式将工作站放到工作组中并将其重新添加到域中?
B)以编程方式修复工作站和域之间的信任关系(如果这实际上是什么问题)?
C)当出现此错误消息时,使用管理员凭据登录工作站?

提前感谢大家的任何潜在帮助,如果需要更多详细信息,请告诉我。

4

2 回答 2

1

好吧,我觉得有点愚蠢,不早点想到这一点,但Lizz提到映射驱动器让我思考。我试图映射驱动器,但它一直想使用我当前的凭据或我的域和备用域用户名。所以我尝试了“.\LoginB”,但它只使用了我的计算机名称,后跟“LoginB”。我最终不得不使用“SystemName\LoginB”并成功映射驱动器。使用它,我可以通过将 ComputerBLogin 变量更改为以下内容来更正上面的代码,这实际上是有效的:

Const JOIN_DOMAIN             = 1
Const ACCT_CREATE             = 2
Const ACCT_DELETE             = 4
Const WIN9X_UPGRADE           = 16
Const DOMAIN_JOIN_IF_JOINED   = 32
Const JOIN_UNSECURE           = 64
Const MACHINE_PASSWORD_PASSED = 128
Const DEFERRED_SPN_SET        = 256
Const INSTALL_INVOCATION      = 262144

Const WbemAuthenticationLevelPktPrivacy = 6

On Error Resume Next 

SystemName = "SystemName"
strNamespace = "root\cimv2"
ComputerBLogin = SystemName & "\LoginB"
ComputerBPass = "PassB"
ComputerALogin = "LoginA"
ComputerAPass = "PassA"
DomainName = "domain.com"
OU = "OU=desiredou,DC=domain,DC=com"

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & SystemName & "\root\cimv2")

If Err.Number <> 0 Then

    Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objwbemLocator.ConnectServer(SystemName, strNamespace, ComputerBLogin, ComputerBPass)

    objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy

    Err.Clear
End IF

Set colComputers = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

For Each objComputer in colComputers
    Return = objComputer.UnJoinDomainOrWorkGroup(NULL, NULL)
    Return = objComputer.JoinDomainOrWorkGroup("WORKGROUP", NULL, NULL)
    If Err.Number <> 0 Then
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup (SystemName & " could not be dropped to the workgroup!" & vbCr &_
                "Error: " & Err.Description,, "Title", 0 + 16)
    Else
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup (SystemName & " was successfully dropped to the WORKGROUP!",, "Title", 0 + 64)
    End If
Next

For Each objComputer in colComputers
    ReturnValue = objComputer.JoinDomainOrWorkGroup(DomainName, ComputerAPass, ComputerALogin, OU, JOIN_DOMAIN + ACCT_CREATE)

    If Err.Number <> 0 Then
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup ("Unable to join " & SystemName & " to the domain! Please join manually.",, "Title", 0 + 16)
    Else
        Set WshShell = CreateObject("WScript.Shell")
        message = WshShell.Popup ("Domain joining was successful!",, "Title", 0 + 64)
    End If
Next

感谢灯泡时刻 Lizz!

于 2012-08-29T00:24:01.047 回答
0

据我所知,当它处于这种状态时,它与主机及其域的关系是无法修复的;我们从来没有能够以务实的方式做到这一点。为此,还需要在脚本中硬编码您的本地管理员和 Active Directory 帐户凭据,这是一个非常危险的过程。

相反,您必须使用您的域凭据从 AD 中删除主机,然后重新启动主机。也许在从 AD 中删除它之后,您将能够使用本地管理员凭据登录它。为测试目的复制此条件的一种方法是删除测试 PC 的域对象,然后重新启动并查看您是否可以进行身份​​验证。

最后,这可能是只能以交互方式完成的事情。而且我不会使用 WMI,因为 WMI 比其他方法具有更多的安全检查和限制,例如使用 RPC 启动 psexec 会话以在损坏的主机上复制和运行脚本。

上面链接中的脚本会提示您输入 AD 凭据。此链接假定您正在使用这些凭据运行脚本,如下所示。

strComputer = "atl-pro-040"

set objComputer = GetObject("LDAP://CN=" & strComputer & _
    ",CN=Computers,DC=fabrikam,DC=com")
objComputer.DeleteObject (0)
于 2012-08-28T02:53:14.003 回答