2013-08-22 8 views
7

So verwenden wir PsExec viel in unseren Automatisierungen, um virtuelle Maschinen zu installieren, wie wir ps Remote-Sitzungen mit unseren Windows 2003-Maschinen nicht verwenden können. Alles funktioniert gut und es gibt keine Probleme, aber PsExec wirft immer Fehler, sogar jeder Befehl wird korrekt ausgeführt. Zum Beispiel:PsExec wirft Fehlermeldungen, aber funktioniert ohne Probleme

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" 

das PSRemoting auf dem Gast ermöglicht, sondern wirft auch diese Fehlermeldung:

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. 

Diese Arten von Fehlermeldungen immer keine apear ganz gleich, wie ich psexec verwenden, wie mit Zitaten, mit vriables/fixed values, anderen flags usw. Hat jemand eine idee wie ich das beheben könnte? Es ist kein wirkliches Problem, aber es macht Fehler, Fehler zu finden, weil die "Fehler" überall sind. Das Deaktivieren der Fehlermeldungen von psexec würde auch helfen ...

+1

ich habe das gleiche Problem, und ich verwende '$ ErrorActionPreference =„SilentlyContinue“' vor dem psexec Befehl. Aber es ist keine echte Lösung. – plunkets

+0

Nun, nicht die beste Idee, aber viel besser als meine "Lösung". Ich schätze, ich werde eine psexec-Silent-Funktion schreiben, die ErrorActionPreference vor dem psexec-Befehl ein- und ausschaltet. Zumindest kann ich die Fehlermeldung abschalten, die eindeutig keine ist. – Simons0n

+0

Überprüfen Sie dies; http://StackOverflow.com/a/2095623/469777 –

Antwort

12

Dies liegt daran, PowerShell meldet manchmal einen NativeCommandError, wenn ein Prozess in STDERR schreibt. PsExec schreibt die Infoline

an STDERR, was bedeutet, dass dies verursacht werden kann. siehe

Weitere Informationen auf diese Fragen/Antworten:

+1

Ich kann Ihnen nicht genug für diese Antwort und alle Links danken. –

2

Umleitung stderr auf null am besten funktioniert für mich. siehe Link unten

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

Hier ist der relevante Abschnitt von diesem Link:

Um dies zu vermeiden Sie stderr umleiten kann auf null zB:

du 2> $ null Wesentlichen die Konsolen-Host und ISE (sowie Remoting) behandeln den stderr-Stream anders. Auf dem Konsolenhost war es wichtig, dass PowerShell Anwendungen wie edit.com unterstützt, die mit anderen Anwendungen zusammenarbeiten, die farbige Ausgaben und Fehler auf dem Bildschirm schreiben. Wenn der E/A-Stream nicht auf dem Konsolenhost umgeleitet wird, gibt PowerShell der nativen EXE ein Konsolenhandle, auf das direkt geschrieben werden kann. Dadurch wird PowerShell umgangen, sodass PowerShell nicht sehen kann, dass Fehler geschrieben wurden, sodass der Fehler nicht über $ error oder durch Schreiben in den stderr-Stream von PowerShell gemeldet werden kann. ISE und Remoting müssen dieses Szenario nicht unterstützen, damit sie die Fehler in stderr sehen und anschließend den Fehler schreiben und $ error aktualisieren.

\ psexec.exe \ $ hostname -u $ script. Benutzername -p $ script: Passwort/accepteula -h cmd/c $ powerShellArgs 2> $ null

+0

Können Sie die Informationen im Link weiterleiten, falls es schal wird? – sushain97

+0

Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. – Onik

+0

Problem behoben. Relevanter Abschnitt vom Hyperlink hinzugefügt. –

0

ich einen psexec Wrapper für Powershell erstellt haben , die diese Frage für Menschen hilfreich sein können Surfen im Internet:

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 
    } 
} 
Verwandte Themen