Я экспериментирую с пространствами выполнения Powershell и заметил разницу в том, как вывод выводится на консоль в зависимости от того, где я создаю свой настраиваемый объект. Если я создаю настраиваемый объект непосредственно в блоке сценария, вывод записывается в консоль в виде таблицы. Однако таблица кажется открытой, пока в пуле пространства выполнения все еще есть открытые потоки, то есть создается таблица, но я могу видеть результаты завершенных заданий, динамически добавляемых к таблице. Это желаемое поведение. Я буду называть это поведением 1.
Несоответствие возникает, когда я добавляю настраиваемый модуль в пул пространств выполнения, а затем вызываю функцию, содержащуюся в этом модуле, которая затем создает настраиваемый объект. Этот объект выводится на экран в виде списка для каждого возвращенного объекта. Это нежелательное поведение. Я назову это поведение 2
Я попытался передать вывод из поведения 2 в формат Format-Table, но это просто создает новую таблицу для каждого возвращаемого объекта. Я могу добиться желаемого эффекта, используя Write-Host для печати строки значений объекта, но я не думаю, что это уместно, учитывая, что, похоже, есть встроенное поведение, которое может достичь желаемого результата, если я его понимаю.
Я думаю по этому поводу, что это как-то связано с асинхронным поведением пространства выполнения. Я новичок в PowerShell, но, возможно, когда пользовательский объект поступает непосредственно из блока сценария, существует скрытый метод или объявление типа, сообщающее PowerShell, чтобы держать таблицу открытой и ждать результата? Это будет отменено при использовании второго метода, потому что он исходит из моей пользовательской функции?
Я хотел бы понять, почему это происходит и как я могу добиться поведения 1, имея возможность использовать настраиваемый модуль, который в конечном итоге будет очень большим. Я открыт и для другой методики, если только можно увидеть, как таблица результатов растет по мере завершения работы. Используемый код приведен ниже.
$ISS = [InitialSessionState]::CreateDefault()
[void]$ISS.ImportPSModule(".\Modules\Test-Item.psm1")
$Pool = [RunspaceFactory]::CreateRunspacePool(1, 5, $ISS, $Host)
$Pool.Open()
$Runspaces = @()
# Script block to run code in
$ScriptBlock = {
Param ( [string]$Server, [int]$Count )
Test-Server -Server $Server -Count $Count
# Uncomment the three lines below and comment out the two
# lines above to test behavior 1.
#[int] $SleepTime = Get-Random -Maximum 4 -Minimum 1
#Start-Sleep -Seconds $SleepTime
#[pscustomobject]@{Server=$Server; Count=$Count;}
}
# Create runspaces and assign to runspace pool
1..10 | ForEach-Object {
$ParamList = @{ Server = "Server A" Count = $_ }
$Runspace = [PowerShell]::Create()
[void]$Runspace.AddScript($ScriptBlock)
[void]$Runspace.AddParameters($ParamList)
$Runspace.RunspacePool = $Pool
$Runspaces += [PSCustomObject]@{
Id = $_
Pipe = $Runspace
Handle = $Runspace.BeginInvoke()
Object = $Object
}
}
# Check for things to be finished
while ($Runspaces.Handle -ne $null)
{
$Completed = $Runspaces | Where-Object { $_.Handle.IsCompleted -eq $true }
foreach ($Runspace in $Completed)
{
$Runspace.Pipe.EndInvoke($Runspace.Handle)
$Runspace.Handle = $null
}
Start-Sleep -Milliseconds 100
}
$Pool.Close()
$Pool.Dispose()
Пользовательский модуль, который я использую, выглядит следующим образом.
function Test-Server {
Param ([string]$Server, [int]$Count )
[int] $SleepTime = Get-Random -Maximum 4 -Minimum 1
Start-Sleep -Seconds $SleepTime
[pscustomobject]@{Server = $Server;Item = $Count}
}
(Begin/End)Invoke
не возвращает ничего, кроме успешного вывода. Если вам нужно что-то еще, например ошибки, предупреждения и т. Д., Вам необходимо проверить _ 2_. - person user4003407   schedule 28.07.2018