2013-08-22 40 views
7

因此,我們在自動化中使用PsExec來安裝虛擬機,因爲我們無法在Windows 2003計算機上使用ps遠程會話。一切都很好,沒有任何問題,但是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" 

啓用guest虛擬機上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. 

這些類型的錯誤消息apear總是不管我如何使用PSEXEC,喜歡用引號,與Vriables /固定值,其他標誌等有沒有人有一個想法,我可以解決這個問題?這不是一個真正的問題,但它使得發現錯誤成爲屁股疼痛,因爲「錯誤」無處不在。禁用psexec的錯誤信息也會有所幫助...

+1

我有同樣的問題,我用'$ ErrorActionPreference =「SilentlyContinue」'的PSEXEC命令。但這不是一個真正的解決方案。 – plunkets

+0

好吧,不是最好的主意,但比我的「解決方案」更好。我猜,我會編寫一個psexec-silent函數,在psexec命令之前打開和關閉ErrorActionPreference。至少我可以關掉錯誤信息,這顯然不是一個。 – 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 

到STDERR這意味着它可以導致這種情況。

欲瞭解更多信息,請參閱這些問題/回答:

+1

不能感謝你足夠的這個答案和所有的鏈接。 –

2

重定向錯誤輸出到空的工作最適合我。見下面的鏈接

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

下面是該鏈接的相關章節:

爲了避免這種情況,你可以將stderr重定向爲null如:

杜2> $空 本質上控制檯主機和ISE(以及遠程處理)不同地處理stderr流。在控制檯主機上,PowerShell支持像edit.com這樣的應用程序與其他應用程序一起工作非常重要,該應用程序會在屏幕上寫入彩色輸出和錯誤。如果I/O流未在控制檯主機上重定向,則PowerShell會爲本機EXE提供控制檯句柄以直接寫入。這繞過PowerShell,因此PowerShell無法看到寫入錯誤,因此無法通過$ error或通過寫入PowerShell的stderr流來報告錯誤。 ISE和遠程處理不需要支持這種情況,所以他們確實看到stderr上的錯誤,然後編寫錯誤並更新$錯誤。

\ PsExec.exe \ $主機名-u $腳本:用戶名-p $腳本:密碼/ ACCEPTEULA -h CMD/C $ powerShellArgs 2> $空

+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 
    } 
} 
相關問題