Cenário:
Quando executado localmente na VM do Azure, adiciona a máquina ao AD e reinicia.
$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
Pergunta:
Usando as mesmas variáveis, mas agora executando o script na minha máquina, com outra VM do Azure como destino, por meio do Powershell remoto:
$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)
Isso falha quando executado remotamente. Por quê?
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
No entanto, algo mais básico, sem argumentos, não tem problemas em rodar remotamente, então minha sintaxe $ Uri, $ Credential e geral parece ok, as sessões iniciam e executam meu código:
$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
Existe algum problema com o Invoke-Command e a maneira como estou armazenando as credenciais? Quaisquer outras opções para fazer isso (adicionar nova VM ao domínio de um script PS)?
Solução
Use test.local \ sysadmin em vez do usuário sysadmin para se conectar ao 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)
Outra solução (menos segura) é enviar o usuário em texto simples e a senha para a sessão remota e criar a credencial lá:
$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)