Фоновые потоки Powershell и возвращаемые значения - PullRequest
0 голосов
/ 22 мая 2019

У меня проблемы с получением фоновых потоков для работы в 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 голосов
/ 22 мая 2019

Веселитесь.

$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()
...