2013-08-22 9 views
7

Windowsのマシンでpsリモートセッションを使用できないため、PsExecを使用して仮想マシンをインストールしています。すべてがうまく動作し、問題はありませんが、PsExecはエラーをスローし続け、すべてのコマンドが正しく実行されていません。たとえば :PsExecはエラーメッセージを表示しますが、問題なく動作します

D:\tools\pstools\psexec.exe $guestIP -u $global:default_user -p $global:default_pwd -d -i C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command "Enable-PSRemoting -Force" 

がゲストにPsRemotingを有効にするだけでなく、このエラーメッセージスロー:エラーメッセージの

psexec.exe : 
Bei D:\Scripts\VMware\VMware_Module5.ps1:489 Zeichen:29 
+  D:\tools\pstools\psexec.exe <<<< $guestIP -u $global:default_user -p $global:default_pwd -d -i C:\Windows\System32\WindowsPowerShell\ 
v1.0\powershell.exe -command "Enable-PSRemoting -Force" 
+ CategoryInfo   : NotSpecified: (:String) [], RemoteException 
+ FullyQualifiedErrorId : NativeCommandError 

PsExec v1.98 - Execute processes remotely 
Copyright (C) 2001-2010 Mark Russinovich 
Sysinternals - www.sysinternals.com 


Connecting to 172.17.23.95...Starting PsExec service on 172.17.23.95...Connecting with PsExec service on 172.17.23.95...Starting C:\Windows\ 
System32\WindowsPowerShell\v1.0\powershell.exe on 172.17.23.95... 
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe started on 172.17.23.95 with process ID 2600. 

これらの種類はつくれ常に関係なく、私は引用符と同じように、PSEXECを使用する方法、 vriables /固定値、他のフラグなどで誰も私がこれを修正する方法のアイデアを持っていますか?それは本当の問題ではありませんが、 "エラー"がどこにでもあるので、お尻の痛みを見つけることができます。 psexecのエラーメッセージをすべて無効にすると、...

+1

私は同じ問題を抱えています。私は '$ ErrorActionPreference =" SilentlyContinue "をpsexecコマンドの前に使用しています。しかし、それは本当の解決策ではありません。 – plunkets

+0

さて、私の "ソリューション"よりも良いアイデアではありません。私は、psexec-silent関数を書いて、psexecコマンドの前にErrorActionPreferenceをオンとオフに調整すると思います。少なくとも私は明らかに1つではないエラーメッセージをオフにすることができます。 – Simons0n

+0

これをチェックしてください。 http://stackoverflow.com/a/2095623/469777 –

答えて

12

これは、プロセスがSTDERRに書き込むときに、PowerShellがNativeCommandErrorを報告することがあるためです。 PsExecは、これを引き起こす可能性があることを意味するインフォリン

PsExec v1.98 - Execute processes remotely 
Copyright (C) 2001-2010 Mark Russinovich 
Sysinternals - www.sysinternals.com 

を書き込みます。詳細については

、これらの質問/回答は以下を参照してください。nullに

+1

この回答とすべてのリンクに感謝しています。 –

2

リダイレクト標準エラー出力は私のために最高の働いていました。下のリンクを参照

Error when calling 3rd party executable from Powershell when using an IDE

ここにリンクしているページから該当するセクションです:あなたはnullに標準エラー出力をリダイレクトすることができ

はこれを回避するには、例えば:> $ nullに 基本的に2

デュコンソールホストとISE(およびリモーティング)はstderrストリームを別々に扱います。コンソールホストでは、PowerShellがedit.comのようなアプリケーションをサポートし、色付きの出力やエラーを画面に書き込む他のアプリケーションと連携することが重要でした。 I/Oストリームがコンソールホスト上でリダイレクトされない場合、PowerShellは、ネイティブEXEに直接書き込むためのコンソールハンドルを提供します。これはPowerShellをバイパスするので、PowerShellはエラーが書き込まれていることを確認できないため、$ error経由でエラーを報告したり、PowerShellのstderrストリームに書き込んだりできません。 ISEとリモーティングは、このシナリオをサポートする必要はありません。そのため、stderrでエラーが表示された後、エラーを書き込み、$ errorを更新します。

\ PSEXEC.EXE \ $ホスト名-uの$スクリプト:。userNameの-p $スクリプト:パスワード/ ACCEPTEULA -h CMD/C $ powerShellArgs 2> $ nullに

+0

リンクが古くなった場合に備えて、リンクに記載されている情報を詳しく説明できますか? – sushain97

+0

このリンクは質問に答えるかもしれませんが、答えの本質的な部分をここに含めて参考にしてください。リンクされたページが変更された場合、リンクのみの回答は無効になります。 – Onik

+0

修正しました。ハイパーリンクから関連するセクションを追加しました。 –

0

私はPowerShellのPSEXECラッパーを作成しました

function Return-CommandResultsUsingPsexec { 
    param(
     [Parameter(Mandatory=$true)] [string] $command_str, 
     [Parameter(Mandatory=$true)] [string] $remote_computer, 
     [Parameter(Mandatory=$true)] [string] $psexec_path, 
     [switch] $include_blank_lines 
    ) 

    begin { 
     $remote_computer_regex_escaped = [regex]::Escape($remote_computer) 

     # $ps_exec_header = "`r`nPsExec v2.2 - Execute processes remotely`r`nCopyright (C) 2001-2016 Mark Russinovich`r`nSysinternals - www.sysinternals.com`r`n" 

     $ps_exec_regex_headers_array = @(
      '^\s*PsExec v\d+(?:\.\d+)? - Execute processes remotely\s*$', 
      '^\s*Copyright \(C\) \d{4}(?:-\d{4})? Mark Russinovich\s*$', 
      '^\s*Sysinternals - www\.sysinternals\.com\s*$' 
     ) 

     $ps_exec_regex_info_array = @(
      ('^\s*Connecting to ' + $remote_computer_regex_escaped + '\.{3}\s*$'), 
      ('^\s*Starting PSEXESVC service on ' + $remote_computer_regex_escaped + '\.{3}\s*$'), 
      ('^\s*Connecting with PsExec service on ' + $remote_computer_regex_escaped + '\.{3}\s*$'), 
      ('^\s*Starting .+ on ' + $remote_computer_regex_escaped + '\.{3}\s*$') 
     ) 

     $bypass_regex_array = $ps_exec_regex_headers_array + $ps_exec_regex_info_array 

     $exit_code_regex_str = ('^.+ exited on ' + $remote_computer_regex_escaped + ' with error code (\d+)\.\s*$') 

     $ps_exec_args_str = ('"\\' + $remote_computer + '" ' + $command_str) 
    } 

    process { 
     $return_dict = @{ 
      'std_out' = (New-Object 'system.collections.generic.list[string]'); 
      'std_err' = (New-Object 'system.collections.generic.list[string]'); 
      'exit_code' = $null; 
      'bypassed_std' = (New-Object 'system.collections.generic.list[string]'); 
     } 

     $process_info = New-Object System.Diagnostics.ProcessStartInfo 
     $process_info.RedirectStandardError = $true 
     $process_info.RedirectStandardOutput = $true 
     $process_info.UseShellExecute = $false 
     $process_info.FileName = $psexec_path 
     $process_info.Arguments = $ps_exec_args_str 

     $process = New-Object System.Diagnostics.Process 
     $process.StartInfo = $process_info 
     $process.Start() | Out-Null 

     $std_dict = [ordered] @{ 
      'std_out' = New-Object 'system.collections.generic.list[string]'; 
      'std_err' = New-Object 'system.collections.generic.list[string]'; 
     } 

     # $stdout_str = $process.StandardOutput.ReadToEnd() 
     while ($true) { 
      $line = $process.StandardOutput.ReadLine() 
      if ($line -eq $null) { 
       break 
      } 
      $std_dict['std_out'].Add($line) 
     } 

     # $stderr_str = $process.StandardError.ReadToEnd() 
     while ($true) { 
      $line = $process.StandardError.ReadLine() 
      if ($line -eq $null) { 
       break 
      } 
      $std_dict['std_err'].Add($line) 
     } 

     $process.WaitForExit() 

     ForEach ($std_type in $std_dict.Keys) { 
      ForEach ($line in $std_dict[$std_type]) { 
       if ((-not $include_blank_lines) -and ($line -match '^\s*$')) { 
        continue 
       } 

       $do_continue = $false 
       ForEach ($regex_str in $bypass_regex_array) { 
        if ($line -match $regex_str) { 
         $return_dict['bypassed_std'].Add($line) 
         $do_continue = $true 
         break 
        } 
       } 
       if ($do_continue) { 
        continue 
       } 

       $exit_code_regex_match = [regex]::Match($line, $exit_code_regex_str) 

       if ($exit_code_regex_match.Success) { 
        $return_dict['exit_code'] = [int] $exit_code_regex_match.Groups[1].Value 
       } elseif ($std_type -eq 'std_out') { 
        $return_dict['std_out'].Add($line) 
       } elseif ($std_type -eq 'std_err') { 
        $return_dict['std_err'].Add($line) 
       } else { 
        throw 'this conditional should never be true; if so, something was coded incorrectly' 
       } 
      } 
     } 

     return $return_dict 
    } 
} 
関連する問題