通过System.Diagnostics.Process或System.Management.Automation.Runspaces执行PowerShell脚本时出现问题。
通过System.Diagnostics.Process或System.Management.Automation.Runspaces执行PowerShell脚本时出现问题。
需要您的帮助来解决以下问题。
我们有一个类似于以下的PowerShell脚本:
invoke-command -ScriptBlock { [cmdletbinding()] param( [parameter(mandatory=$True)] [string] $ticktfilepath ) $ticketdetails=get-content $ticktfilepath |%{if ( $_ -like '"AB*' ) {$_}}|%{echo "$($_.Split(',')[7].Split('"')[1])=$($_.Split(',')[3].Split(':')[0].Split(' ')[$_.Split(',')[3].Split(':')[0].Split(' ').length-1])=$($_.Split(',')[0].Split('"')[1]);"} write-output $ticketdetails } -ArgumentList 'D:\file.csv'
该脚本读取一个CSV文件,并对其中以“AB…”开头的行进行一些字符串解析。传递的CSV文件中有符合“AB…”条件的行,因此会返回结果。当通过PowerShell控制台或ISE执行时,它可以完美运行。
但根据我们的要求,我们尝试通过以下方式执行相同的脚本:
1. 使用System.Diagnostics.Process和进程启动信息,文件名为powershell.exe,参数为上述脚本。使用“-like”时失败,即在|%{if ( $_ -like '"AB*' )。即使预期结果应该为true,但条件始终为false。
注:其他PowerShell脚本可以通过这种方式完美运行。
2. 通过System.Management.Automation.Runspaces执行时出现相同问题。
因此,看起来是使用“-like”操作符的某些限制。
我们甚至尝试使用System.Diagnostics.Process方法逐行编写脚本,利用Process.StandardInput.WriteLine(line),但是PowerShell仍然无法运行。
非常感谢您提供解决此问题的任何指导。
在使用System.Diagnostics.Process时,我使用了以下代码:
ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.UseShellExecute = false; processStartInfo.RedirectStandardError = true; processStartInfo.RedirectStandardOutput = true; processStartInfo.FileName = "powershell.exe"; processStartInfo.Arguments =; Process powerShellProc = new Process(); powerShellProc.StartInfo = processStartInfo; powerShellProc.Start(); string successMessage = powerShellProc.StandardOutput.ReadToEndAsync().Result; string errorMessage = powerShellProc.StandardError.ReadToEndAsync().Result; powerShellProc.WaitForExit();
其中,
ScriptContent- 是上述的PowerShell脚本。
尝试使用startswith替代like,但结果相同。但是在PowerShell控制台或ISE中,它可以完美运行。
在通过System.Diagnostics.Process或System.Management.Automation.Runspaces执行PowerShell脚本时遇到问题。
问题原因:在进程实际完成之前调用powerShellProc.StandardOutput.ReadToEndAsync().Result会导致问题。
解决方法:可以使用来自How to capture process output asynchronously in powershell?的Invoke-Executable函数。
以下是可行的顺序:
$outTask = $oProcess.StandardOutput.ReadToEndAsync(); $errTask = $oProcess.StandardError.ReadToEndAsync(); $bRet=$oProcess.WaitForExit($TimeoutMilliseconds) $outText = $outTask.Result; $errText = $errTask.Result;
这样可以解决问题。