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)