Execute Powershell Add-Computer remotely via Invoke-Command

5,627

Solution 1

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

Solution 2

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 [email protected].

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

Share:
5,627

Related videos on Youtube

Razvan Zoitanu
Author by

Razvan Zoitanu

Available now, SQL DBA contracts, London or remote. Microsoft certified SQL DBA with real passion for all things tech. Inquisitive, reliable, trustworthy, hard-working. Managed SQL Server since 2004, with a strong IT infrastructure background. Owner and Lead consultant of dbAZ Ltd, a consultancy focused on DBA services for SQL Server on-prem and Azure.

Updated on September 18, 2022

Comments

  • Razvan Zoitanu
    Razvan Zoitanu over 1 year

    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)
    
  • Razvan Zoitanu
    Razvan Zoitanu about 9 years
    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 !