Question

So I've got an XP Pro workstation that is reporting "Windows cannot connect to the domain, either because the domain controller is down or otherwise unavailable, or because your computer account was not found. Please try again later. If this message continues to appear, contact your system administrator for assistance." when logging in with domain credentials. To fix this manually I would simply log in with the local admin account, drop it to a workgroup, and re-add it to the domain. This process however can take a decent amount of time considering this issue crops up at my work rather frequently. What I'm trying to do is programmatically automate the dropping/rejoining process. The following code works, but only if the computer is correctly in a domain or workgroup, not in limbo like it is now.

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

When the script hits line 24:

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

it errors with "The remote server machine does not exist or is unavailable: 'GetObject'". This line would normally work if the machine were correctly in the domain. The AD object does exist. If this errors I have it coded to log into the machine with the local admin credentials on line 29:

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

That will error out with "SWbemLocator: Access is denied."

So using both methods I'm familiar with there's no way to access WMI when the machine is in this limbo. In my research it seems as though the "Trust relationship between the workstation and the domain has failed" but to me that doesn't explain why I can't log in with the local admin credentials.

I didn't want to have to resort to NETDOM, but I tried anyway. It errors out as well talking about the failed trust relationship.

So my questions are:
A) When this error message is present is there any way to programmatically drop the workstation to a workgroup and re-add it to the domain?
B) Programmatically repair the trust relationship between the workstation and domain (If that is in fact what's wrong with it)?
C) When this error message is present log into the workstation with admin credentials?

Thanks everyone in advance for any potential help and please let me know if any more details are needed.

Was it helpful?

Solution

Ok, I feel a bit foolish not thinking of this sooner but Lizz's mention of mapping the drive got me thinking. I attempted to map the drive but it continually wanted to use either my current credentials or my domain with an alternate domain username. So I tried ".\LoginB" but that just used MY computer's name followed by "LoginB". I ended up having to use "SystemName\LoginB" and was successfully able to map the drive. Using that I was able correct the code above by changing the ComputerBLogin variable to the following which does in fact work:

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

Thanks for the lightbulb-moment Lizz!

OTHER TIPS

To my knowledge, the relationship with a host and its domain cannot be repaired when it's in this state; we have never been able to do that progmatically. To do so also requires your local admin and Active Directory account credentials be hard coded in the script, which is quite a risky process.

Instead, you must delete the host from AD using your domain credentials, then reboot the host. Perhaps after its removal from AD you'll be able to log into it with local admin credentials. One way to replicate this condition for testing purposes is to delete a test PC's domain object then reboot and see if you can authenticate.

In the end, this may be something that can only be done interactively. And I wouldn't use WMI, since WMI has more security checks and limitations than do other methods, like starting a psexec session using RPC to copy and run a script on the damaged host.

The script in the link above prompts you for AD credentials. This link assumes you're running the script with those creds, as follows.

strComputer = "atl-pro-040"

set objComputer = GetObject("LDAP://CN=" & strComputer & _
    ",CN=Computers,DC=fabrikam,DC=com")
objComputer.DeleteObject (0)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top