在Powershell中使用带有BeginInvoke的PSDataCollection

时间:2012-06-12 16:27:19

标签: powershell powershell-v2.0

我正在尝试在PowerShell脚本中处理来自管道的输出。现在,我看到输出的唯一方法是当我为管道发出EndInvoke方法时,但由于我的一些调用可以长时间运行并且可以有很多输出我想要能够在流程运行时显示输出。

看起来我可以通过将输入和输出参数传递给BeginInvoke方法来实现这一点,但我似乎无法使语法正确。有什么建议?我正在尝试的一个例子如下:

$scriptBlock = {param([int]$pauseTime = 10); Write-Output "Test"; Start-Sleep -Seconds $pauseTime; Write-Output "Test 2"}

# Create objects and set stuff up
$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$runspacepool = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, 4, $initialSessionState, $Host)
$runspacepool.Open()
$pipeline = [powershell]::Create().AddScript($scriptBlock).AddParameter("pauseTime", 30)
$pipeline.RunspacePool = $runspacepool

# These two lines are not correct
$inputStream = New-Object [System.Management.Automation]
$outputStream = New-Object [System.Management.Automation.PSDataCollection]

$async = $pipeline.BeginInvoke($inputStream, $outputStream)

# Do something with the $outputStream here???

$pipeline.EndInvoke($async)

# Clean-up code    
$pipeline.Dispose()
$async = $null
$pipeline = $null
if ($runspacepool -ne $null) {$runspacepool.Close()}

1 个答案:

答案 0 :(得分:1)

我不知道你想要完成什么(它看起来过于复杂,只是为了处理脚本输出的简单目的)但是对你的PowerShell脚本进行这么小的修改至少会得到一个输出:< / p>

` $scriptBlock = {
    param([int]$pauseTime = 1)
    Write-Output "Test 1"
    Start-Sleep -Seconds $pauseTime
    Write-Output "Test 2"
   }

    # Create objects and set stuff up
    $initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
    $runspacepool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, 4, $initialSessionState, $Host)
    $runspacepool.Open()
    $pipeline = [powershell]::Create().AddScript($scriptBlock).AddParameter("pauseTime", 5)
    $pipeline.RunspacePool = $runspacepool

    $outputStream = New-Object -Typename  System.Management.Automation.PSDataCollection[PSObject]

    $async = $pipeline.BeginInvoke()
    1..10 | Foreach { "Im waiting..."; Start-Sleep -Milliseconds 500 }

    $outputStream = $pipeline.EndInvoke($async)

    # Clean-up code    
    $pipeline.Dispose()
    $async = $null
    $pipeline = $null
    if ($runspacepool -ne $null) {$runspacepool.Close()}

    $outputStream
`