Execute o Powershell Add-Computer remotamente via Invoke-Command

4

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)
    
por Razvan Zoitanu 12.03.2015 / 18:41

2 respostas

5

Acho que o problema pode estar na forma como você está gerando a credencial usando ConvertTo-SecureString . Por padrão, esse cmdlet usa uma chave de criptografia específica do host atual (acho) a menos que forneça uma chave de criptografia explícita com o parâmetro -Key . No lado remoto, ele precisa descriptografar a string usando a mesma chave de criptografia que não possui (porque a chave do host é diferente).

Primeiro, eu tentaria passar o nome de usuário e a senha em texto simples como outro parâmetro para a chamada e fazer a criação da credencial dentro do bloco de script. Isso pelo menos provará se isso é realmente seu problema ou não.

* Edit: aqui está um link para a documentação para ConvertTo-SecureString

    
por 12.03.2015 / 21:55
1

Extraído de: link

A raiz do problema é (desde que sua senha esteja correta) ao executar interativamente o domínio é pré-anexado e, como tal, você só precisa fornecer o usuário. Mas em um ambiente não interativo, o domínio não é conhecido. Certifique-se de incluir os nomes de domínio curtos como contoso\DMAdmin ou o FQDN completo [email protected] .

Você pode usar o seguinte script do PowerShell se passar o nome de usuário e a senha como variáveis de forma segura por meio da automação azure:

$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

    
por 09.01.2017 / 01:22