PsExec Throws Error Messages, but works without any problems

前端 未结 3 767
不思量自难忘°
不思量自难忘° 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: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
        }
    }
    

提交回复
热议问题