4

Scenario:

When executed locally on the Azure VM, succesfully adds the machine to the AD, and restarts.

$DomainName = "test.local"
$AdminUserName = "sysadmin"
$Password = <mypass>
$SecurePassword = ConvertTo-SecureString $Password -asplaintext -force
$Credential = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist $AdminUserName, $SecurePassword
$Credential

Add-Computer -DomainName $DomainName -Credential $Credential -Restart -Passthru -Verbose

Question:

Using the same variables, but now running the script on my machine, with another Azure VM as the target, via remote Powershell:

$ScriptBlockContent = { 
Param ($Arg1,$Arg2)
Add-Computer -DomainName $Arg1 -Credential $Arg2 -Restart -Passthru -Verbose}

$Session = New-PSSession -ConnectionUri $Uri -Credential $Credential
Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($DomainName,$Credential)

This fails when executed remotely. Why ?

PS C:\> Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList $DomainName, $Credential
VERBOSE: Performing the operation "Join in domain 'test.local'" on target "testvm2".
Computer 'rzlab1sql1' failed to join domain 'test.local' from its current workgroup 'WORKGROUP' with following error
message: Unable to update the password. The value provided as the current password is incorrect.
    + CategoryInfo          : OperationStopped: (testvm2:String) [Add-Computer], InvalidOperationException
    + FullyQualifiedErrorId : FailToJoinDomainFromWorkgroup,Microsoft.PowerShell.Commands.AddComputerCommand
    + PSComputerName        : mylab.cloudapp.net

Yet something more basic, without arguments, has no problems running remotely, so my $Uri, $Credential and general syntax seem ok, the sessions starts and runs my code:

$Path = "C:\"
$Attribute = "d"

$ScriptBlockContent = { 
Param ($Arg1,$Arg2)
Get-ChildItem -Path $Arg1 -Attributes $Arg2}

$Session = New-PSSession -ConnectionUri $Uri -Credential $Credential
Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList $Path, $Attribute

Is there a problem with Invoke-Command and the way I'm storing the credentials ? Any other options to get this done (to add new VM to domain from a PS script) ?

Solution

Use test.local\sysadmin instead of the sysadmin user to connect to AD.

$DomainName = "test.local"
$AdminUserName = "sysadmin"
$DomainUserName = $DomainName+"\"+$AdminUserName
$Password = <mypass>
$SecurePassword = ConvertTo-SecureString $Password -asplaintext -force
$Credential = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist ($AdminUserName, $SecurePassword)
$DomainCredential = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist ($DomainUserName, $SecurePassword)

$ScriptBlockContent = { 
Param ($Arg1,$Arg2)
Add-Computer -DomainName $Arg1 -Credential $Arg2 -Restart -Passthru -Verbose}

$Session = New-PSSession -ConnectionUri $Uri -Credential $Credential
Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($DomainName, $DomainCredential)

Another solution (less secure) is to send the plain text user and password to the remote session, and create the credential there:

$ScriptBlockContent = { 
Param ($Arg1,$Arg2,$Arg3,$Arg4)
Add-Computer -ComputerName $Arg4 -DomainName $Arg1 -Credential (New-Object -Typename System.Management.Automation.PSCredential -Argumentlist ($Arg1+"\"+$Arg2), (ConvertTo-SecureString $Arg3 -asplaintext -force)) -Restart -Passthru -Verbose}

$Session = New-PSSession -ConnectionUri $Uri -Credential $Credential
Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($DomainName,$AdminUserName,$Password,$VMName)
  • 2
    Try adding a -Authentication CredSSP to your creation of the pssesion perhaps? It seems to be about your authentication. – Zoredache Mar 12 '15 at 17:56
  • Thank you, but I'm quite sure it's not that, as other cmdlets run well under the same session. – Razvan Zoitanu Mar 13 '15 at 14:37
5

I think the problem might be with the way you're generating the credential using ConvertTo-SecureString. By default, that cmdlet uses an encryption key specific to the current host (I think) unless you provide an explicit encryption key with the -Key parameter. On the remote side, it needs to decrypt the string using the same encryption key which it doesn't have (because the host key is different).

First, I'd try passing the plaintext username and password as another parameter to the invoke and doing the credential creation within the script block. That will at least prove whether this is actually your problem or not.

*Edit: Here's a link to the documentation for ConvertTo-SecureString

  • Did the credential creation in the new session as a test, as you mentioned, and it works ! Will update the question with the complete solution code. Thank you Ryan ! – Razvan Zoitanu Mar 13 '15 at 14:41
1

Taken from: http://www.gi-architects.co.uk/2017/01/powershell-add-computer-error-when-executed-remotely/

The root of the problem is (given that your password is correct) when running interactively the domain is pre-appended and as such you only need to provide the user. But in a non-interactive environment, the domain is not known. Make sure you either include the short domain names like contoso\DMAdmin or the full FQDN DMAdmin@contoso.com.

You can use the following PowerShell script if you pass the username and password as variables securely via azure automation:

$PasswordSec = ConvertTo-SecureString $Password -AsPlainText -Force $djuser = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $PasswordSec Add-Computer -DomainName "contoso.com" -Credential $djuser -Restart

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.