使用参数和凭据从 PowerShell 启动 .ps1 脚本并从中获取输出

Starting .ps1 Script from PowerShell with Parameters and Credentials and getting output from it

我认为我的问题有一个简单的解决方案。但现在我有点困惑。 我有 Java 代码,启动 1 个 Powershell 脚本。此 Powershell 脚本必须启动其他脚本。
Java ->
Powershell。ps1 ->
脚本 1.ps1 脚本 2.ps1 脚本 3.ps1 脚本....

Script1,2,..etc 执行多项任务和 return 字符串值。

我试过了 启动进程、调用命令和调用表达式

假设 script1.ps1 是:

$a = 1+2
$a

Start-Process 最适合我,但我没有得到输出:

$arguments = "C:\..\script1.ps1" + " -ClientName" + $DeviceName
$output = Start-Process powershell -ArgumentList $arguments -Credential $credentials
$output 

$输出为空。

非常感谢!

Start-Process 默认产生 no 输出。

(使其直接 产生输出的唯一方法是使用 -PassThru,这不会 return 脚本的 输出,但是一个 System.Diagnostics.Process 实例 表示新创建的进程 - 见下文。)

通过Start-Process从脚本捕获输出的唯一方法是使用-RedirectStandardOutput
-RedirectStandardError 参数用于捕获脚本的输出 as text,在 files.
[1] 中[2]

然后您可以在 PowerShell 中读取这些文件在新进程完成后,您可以通过以下两种方式之一确保这一点:

  • 也将-Wait开关传给Start-Process,使调用同步,也就是说当Start-Processreturns时,输出已在指定文件中捕获。

  • 以后用-PassThru得到一个System.Diagnostics.Process instance and pass it to Wait-Process(或者直接用它的.WaitForExit()方法;属性.HasExited可以用检查进程是否还在运行).

以下可能适用于您的情况:

$arguments = "-File C:\...\script1.ps1" + " -ClientName" + $DeviceName

# Launch the script in a new window running as the given user,
# capture its standard output in file ./out.txt,
# and wait for it to finish.
Start-Process -Wait -RedirectStandardOutput ./out.txt powershell -ArgumentList $arguments -Credential $credentials

"Running script1.ps1 produced the following output:"
Get-Content ./out.txt

PowerShell CLI,遗憾的是,报告 PowerShell 6 output streams, via standard output (see this answerall),因此以上捕获了您的 all 输出脚本,包括错误输出。

但是,您可以使用 -RedirectStandardError ./err.txt 来单独捕获错误流。


[1] 通过它的 CLI 调用另一个 PowerShell 实例 提供 一个 结构化替代方法 来捕获非结构化文本(打印到控制台的用于显示的输出,这是默认情况下发生的情况):

-OutputFormat xml(或-of xml / -o xml)使 PowerShell 将其输出格式化为 CLIXML 格式,即PowerShell 远程处理和后台作业中用于 序列化 丰富对象 的相同基于 XML 的序列化格式,您可以 稍后 Import-Clixml 呼叫“补充水分”

注意:对于大多数复杂对象,存在 类型保真度损失:也就是说,它们被序列化为 模拟原始对象;简而言之,没有方法的“属性 包”,但是可能就足够了 - 请参阅 .

这是一个快速演示,使用 [datetime] 实例, 以类型保真度反序列化:

# Call Get-Date via the PowerShell CLI and save the output
# in CLIXML format in file ./out.xml
Start-Process -Wait -RedirectStandardOutput ./out.xml powershell '-of xml -c Get-Date'

# Import the CLIXML file and convert its content back to a [datetime] instance.
"Type of the CLIXML-serialized and deserialized `Get-Date` output:"
(Import-CliXml ./out.xml).GetType().FullName # -> System.DateTime

[2]输出文件的字符编码由存储在[Console]::OutputEncoding中的编码决定,它反映了当前控制台输出代码页,默认为系统的活动遗留OEM代码页。