web-dev-qa-db-ja.com

リモートのPowerShellセッションで資格情報を保持する方法は?

Azureファイル共有を持っていますが、これをAzure VMから使用したいと思います-cmdkeyを使用してVMの資格情報を永続化し、Net Useを使用してマウントした後。これは、Windows Server 2012 R2のローカルPowershellセッションでこれらのコマンドを実行することによりテストされました。

しかし、このステップをAzureデプロイメントスクリプトに追加する必要があります。 Azure Powershellスクリプトは私のラップトップから実行され、Azureサブスクリプションに接続し、多くの変数を使用してVMを最初から構築します。

Invoke-Commandを使用して変数をAzure Powershellスクリプトから新しく作成されたVMのリモートPowershellセッションに渡すことがわかりました。

$Session = New-PSSession -ConnectionUri $Uri -Credential $DomainCredential

$ScriptBlockContent = { 
Param ($Arg1,$Arg2,$Arg3)
cmdkey /add:$Arg1 /user:$Arg2 /pass:$Arg3}

Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($Share,$AccountName,$Key)

そしてエラー:

PS C:\> Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent -ArgumentList ($Share,$AccountName,$Key)
CMDKEY: Credentials cannot be saved from this logon session.

構文を確認するためにcmdkey/listに置き換えられました。エラーはありません。

PS C:\> Invoke-Command -Session $Session -ScriptBlock $ScriptBlockContent
Currently stored credentials:
* NONE *

Windows Update PowerShellモジュール(Invoke-WUInstall)でも同様の問題があり(修正できませんでした)、VMのローカルPowershellセッションでは問題なく実行されますが、リモートPowershellを介して起動すると更新されません。

これを回避する方法はありますか?

13
Razvan Zoitanu

Windowsが認証を処理する方法により、リモートのPowerShellセッションを介してCMDKEYを使用して資格情報を設定することはできないため、CMDKEYを使用する場合は対話的に行う必要があります。

あなたに似た答えを探しているスレッドから Don Jones を引用するには:

これはCmdkeyコマンドの制限であり、実際にはPowerShellではありません。しかし、それはRemotigが資格情報を処理する方法に関連しています。リモートセッションは実際には認証情報を取得せず、委任されたチケットを取得するため、実際に保存するトークンはありません。これはすべて設計によるものであり、再構成できるものではありません。

2
Persistent13

スケジュールされたタスクを使用したくない場合は、Sysinternalの PsExec.exe を使用できます。通常、PowerShellセッションを開始すると、cmdkeyに失敗したローカルユーザーではなく、servicesプロセスで実行されます(これは、リモートコンピューターでquery sessionコマンドを実行して確認できます)。

これを克服するには、PsExec.exe's -iフラグを使用して、ローカルユーザーのプロセスでcmdkey.exeを実行する必要があります。

リモートシステム上の指定されたセッションのデスクトップと対話するようにプログラムを実行します。セッションが指定されていない場合、プロセスはコンソールセッションで実行されます。

ここでの課題は、リモートマシン上のローカルユーザーのセッションIDを取得することです。マシンでアクティブなセッションのリストを表示するquery sessionコマンドを実行して、これを実現しました。可能な解決策の1つは-

$processId = Invoke-Command $session -ScriptBlock  {
param($user)
    $sessions = query session $user;
    return $sessions[1].split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)[2];

} -ArgumentList ($user)

ここで$userには、リモートコンピュータ上のローカルユーザーのユーザー名が含まれています。

セッションIDを取得したら、単純に実行できます

PsExec \\<computer_name> -u <local_user_name> -p <password> -h -i $processId cmdkey.exe /generic:testtt /user:userr /pass:pass

注:

  1. リモートマシン上のユーザーのセッションIDを取得するより良い方法がある場合があります。
  2. 現在、PsExecの実行中に、回避できるリモートシステムとの接続を再度確立しています(テストしていません)。
  3. コマンドを実行するユーザーには、リモートマシンに対する管理者アクセス権が必要です。
2
Ankit Aggarwal