PsExec Throws Error Messages, but works without any problems

前端 未结 3 754
不思量自难忘°
不思量自难忘° 2020-12-01 22:05

So we are using PsExec a lot in our automations to install virtual machines, as we can\'t use ps remote sessions with our windows 2003 machines. Everything works great and t

相关标签:
3条回答
  • 2020-12-01 22:11

    redirect stderr to null worked best for me. see below link

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

    Here's the relevant section from that link:

    To avoid this you can redirect stderr to null e.g.:

    du 2> $null Essentially the console host and ISE (as well as remoting) treat the stderr stream differently. On the console host it was important for PowerShell to support applications like edit.com to work along with other applications that write colored output and errors to the screen. If the I/O stream is not redirected on console host, PowerShell gives the native EXE a console handle to write to directly. This bypasses PowerShell so PowerShell can't see that there are errors written so it can't report the error via $error or by writing to PowerShell's stderr stream. ISE and remoting don't need to support this scenario so they do see the errors on stderr and subsequently write the error and update $error.

    .\PsExec.exe \$hostname -u $script:userName -p $script:password /accepteula -h cmd /c $powerShellArgs 2> $null

    0 讨论(0)
  • 2020-12-01 22:18

    This is because PowerShell sometimes reports a NativeCommandError when a process writes to STDERR. PsExec writes the infoline

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

    to STDERR which means it can cause this.

    For more information, see these questions / answers:

    • https://stackoverflow.com/a/1416933/478656
    • https://stackoverflow.com/a/11826589/478656
    • https://stackoverflow.com/a/10666208/478656
    0 讨论(0)
  • 2020-12-01 22:19

    I have created a psexec wrapper for powershell, which may be helpful to people browsing this question:

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题