web-dev-qa-db-ja.com

Invoke-Commandを使用してPowershellAdd-Computerをリモートで実行する

シナリオ:

Azure VMでローカルに実行すると、マシンがADに正常に追加され、再起動します。

$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

質問:

同じ変数を使用しますが、リモートPowershellを介して、別のAzure VMをターゲットとして、自分のマシンでスクリプトを実行しています。

$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)

これは、リモートで実行すると失敗します。どうして ?

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

しかし、引数のないより基本的なものはリモートで実行しても問題がないため、$ Uri、$ Credential、および一般的な構文は問題ないようです。セッションが開始され、コードが実行されます。

$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

Invoke-Commandと、資格情報の保存方法に問題はありますか?これを行うための他のオプション(PSスクリプトからドメインに新しいVM)を追加するため)?

解決策

sysadminユーザーの代わりにtest.local\sysadminを使用して接続します広告。

$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)

別の解決策(安全性が低い)は、プレーンテキストのユーザーとパスワードをリモートセッションに送信し、そこで資格情報を作成することです。

$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)
4
Razvan Zoitanu

問題は、ConvertTo-SecureStringを使用して認証情報を生成する方法にあると考えられます。デフォルトでは、そのコマンドレットは、現在のホストに固有の暗号化キーを使用します(私はそう思います)でない限り-Keyパラメータ。リモート側では、所有していない同じ暗号化キーを使用して文字列を復号化する必要があります(ホストキーが異なるため)。

まず、平文のユーザー名とパスワードを別のパラメーターとして呼び出しに渡し、スクリプトブロック内で資格情報を作成してみます。それは少なくともこれが実際にあなたの問題であるかどうかを証明するでしょう。

*編集: ConvertTo-SecureString のドキュメントへのリンクは次のとおりです

5
Ryan Bolger

取得元: http://www.gi-architects.co.uk/2017/01/powershell-add-computer-error-when-executed-remotely/

問題の根本は(パスワードが正しい場合)ドメインが事前に追加されているため、ユーザーを提供するだけで十分です。ただし、非インタラクティブ環境では、ドメインは不明です。 contoso\DMAdminのような短いドメイン名または完全なFQDN[email protected]のいずれかを含めるようにしてください。

Azureオートメーションを介してユーザー名とパスワードを変数として安全に渡す場合は、次のPowerShellスクリプトを使用できます。

$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

1
Lubenk