通过System.Diagnostics.Process或System.Management.Automation.Runspaces执行PowerShell脚本时出现问题。

19 浏览
0 Comments

通过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中,它可以完美运行。

0
0 Comments

在通过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;

这样可以解决问题。

0