gpt4 book ai didi

powershell - Powershell流水线数据到外部控制台应用程序

转载 作者:行者123 更新时间:2023-12-02 23:06:25 25 4
gpt4 key购买 nike

我有一个控制台应用程序,可以接受标准输入。它缓冲数据直到执行命令,然后执行所有命令,然后将输出发送到标准输出。
目前,我正在Powershell中运行此应用程序,将命令管道传输到其中,然后解析输出。管道中的数据相对较小;但是,此应用程序被调用了大约1000次。每次执行时,都必须加载并创建网络连接。我想知道将所有命令传递到控制台应用程序的单个实例中是否更有效。
我通过将所有为控制台创建标准输入的Powershell脚本添加到函数中,然后将该函数通过管道传递到控制台应用程序来进行尝试。这似乎起初是可行的,但是您最终意识到它正在缓冲Powershell中的所有数据,直到功能完成,然后将其发送到控制台的StdIn。您可以看到此信息,因为我有大量的Write-Host语句在闪烁,然后才看到输出。
例如

Function Run-Command1
{
Write-Host "Run-Command1"
"GET nethost xxxx COLS id,name"
"EXEC"
}

Function Run-Command2
{
Write-Host "Run-Command2"
"GET nethost yyyy COLS id,name"
"GET users yyyy COLS id,name"
"EXEC"
}

...

Function Run-CommandX
{
...
}
以前,我将其用作:
Run-Command1 | netapp.exe -connect QQQQ -U user -P password
Run-Command2 | netapp.exe -connect QQQQ -U user -P password
...
Run-CommandX | netapp.exe -connect QQQQ -U user -P password
但是现在我想做的是:
Function Run-Commands
{
Run-Command1
Run-Command2
...
Run-CommandX
}

Run-Commands |
netapp.exe -connect QQQQ -U user -P password
理想情况下,我希望将Powershell管道行为扩展到外部应用程序。这可能吗?

最佳答案

编辑:正如@ mklement0指出的那样,在PowerShell Core中这是不同的。
在PowerShell 5.1(及更低版本)中,您必须手动将每个管道项目写入外部应用程序的输入流。
这是为此构建函数的尝试:

function Invoke-Pipeline {
[CmdletBinding()]
param (
[Parameter(Mandatory, Position = 0)]
[string]$FileName,

[Parameter(Position = 1)]
[string[]]$ArgumentList,

[int]$TimeoutMilliseconds = -1,

[Parameter(ValueFromPipeline)]
$InputObject
)
begin {
$process = [System.Diagnostics.Process]::Start((New-Object System.Diagnostics.ProcessStartInfo -Property @{
FileName = $FileName
Arguments = $ArgumentList
UseShellExecute = $false
RedirectStandardInput = $true
RedirectStandardOutput = $true
}))
$output = [System.Collections.Concurrent.ConcurrentQueue[string]]::new()
$event = Register-ObjectEvent -InputObject $process -EventName 'OutputDataReceived' ` -Action {
$Event.MessageData.TryAdd($EventArgs.Data)
} -MessageData $output
$process.BeginOutputReadLine()
}
process {
$process.StandardInput.WriteLine($InputObject)
[string]$line = ""
while (-not ($output.TryDequeue([ref]$line))) {
start-sleep -Milliseconds 1
}
do {
$line
} while ($output.TryDequeue([ref]$line))
}
end {
if ($TimeoutMilliseconds -lt 0) {
$exited = $process.WaitForExit()
}
else {
$exited = $process.WaitForExit($TimeoutMilliseconds)
}
if ($exited) {
$process.Close()
}
else {
try {$process.Kill()} catch {}
}
}
}

Run-Commands | Invoke-Pipeline netapp.exe "-connect QQQQ -U user -P password"
问题是,没有完美的解决方案,因为根据定义,您不知道外部程序何时将某些内容写入其输出流,或写入多少。
注意:此函数不会重定向错误流。但是,方法是相同的。

关于powershell - Powershell流水线数据到外部控制台应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64662888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com