Powershell后台线程和返回值

时间:2019-05-22 11:16:50

标签: multithreading powershell runspace

我无法让后台线程在Powershell中工作。我想使用运行空间,可以在其中插入脚本并在有脚本时获取更新,并允许我的主线程根据需要处理该数据。我不确定这段代码为什么不返回正确的值?我测试过的所有服务器都没有在运行空间中使用时返回true,但是这里的返回值为0。

我对使用Powershell作业不感兴趣。

$servers = @("x1","x2","x3");
$results = New-Object Collections.Generic.List[String];
$input = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$output = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$results.Clear();
foreach ($server in $servers)
{
    Write-Host $server;
    $powerShell = [Management.Automation.PowerShell]::Create();
    [Void]$PowerShell.AddScript({
        $result = Test-Connection $server -Count 1 -Quiet; 
        return ($server - $result)
    })

    $handle = $powerShell.BeginInvoke($input,$output);
    $results.Add($output);
}

$results;

$results = New-Object Collections.Generic.List[String];
$input = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$output = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$results.Clear();
foreach ($server in $servers)
{
    Write-Host $server;
    $powerShell = [Management.Automation.PowerShell]::Create();
    [Void]$PowerShell.AddScript({
        param ($server)
        $result = Test-Connection $server -Count 1 -Quiet; 
        return ($server - $result)
    })

    $handle = $powerShell.BeginInvoke($server,$output);
    #$handle = $powerShell.BeginInvoke($input,$output);
    $results.Add($output);
}

$results;

1 个答案:

答案 0 :(得分:0)

玩得开心。

$servers = @("x1","x2","x3");
$input   = New-Object 'System.Management.Automation.PSDataCollection[psobject]'
$output  = New-Object 'System.Management.Automation.PSDataCollection[psobject]'

$GH = [hashtable]::Synchronized(@{})

[System.Collections.Generic.List[PSObject]]$GH.results = @()
[System.Collections.Generic.List[PSObject]]$jobs = @()

$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()

$runspacePool = [RunspaceFactory]::CreateRunspacePool(1, ([int]$env:NUMBER_OF_PROCESSORS + 1), $initialSessionState, $host )
$runspacePool.ApartmentState = 'MTA'
$runspacePool.ThreadOptions  = "ReuseThread"
[void]$runspacePool.Open()

$jobCounter = 1

foreach ($server in $servers)
{
    Write-Host $server;

    $job = [System.Management.Automation.PowerShell]::Create($initialSessionState)
    $job.RunspacePool = $runspacePool

    $scriptBlock = { param ( [hashtable]$GH, [string]$server ); $result = Test-Connection $server -Count 1 -Quiet; $GH.results.Add( [PSObject]@{ 'Server' = $server; 'Result' = $result } ) }

    [void]$job.AddScript( $scriptBlock ).AddArgument( $GH ).AddArgument( $server )
    $jobs += New-Object PSObject -Property @{
                                    RunNum = $jobCounter++
                                    JobObj = $job
                                    Result = $job.BeginInvoke() }

    do {
        Sleep -Seconds 1 
    } while( $runspacePool.GetAvailableRunspaces() -lt 1 )

}

Do {
    Sleep -Seconds 1
} While( $jobs.Result.IsCompleted -contains $false)


$GH.results;


$runspaces = Get-Runspace | Where { $_.Id -gt 1 }

foreach( $runspace in $runspaces ) {
    try{
        [void]$runspace.Close()
        [void]$runspace.Dispose()
    }
    catch {
    }
}

[void]$runspacePool.Close()
[void]$runspacePool.Dispose()