Powershell 运行空间输出的行为取决于返回自定义对象的定义方式

科林·克雷格

我正在试验 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}
}
科林·克雷格

除了代码中的错误之外,我的主要问题似乎是缺乏与 powershell 的默认对象处理相关的理解。当键值对少于四个时,Powershell 将对象的输出显示为表格,当键值对更多时,则显示为列表。

在我的测试模块中返回的自定义对象不止键值对,而我直接返回的自定义对象只有两个。这导致了我认为是奇怪的行为。我通过删除我发布的代码中的一些键值对来缩短它,然后没有测试它(对不起),从而使问题复杂化。

这个 stackoverflow 帖子有一个冗长的答案,解释了一些行为并提供了更改默认输出的示例。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

自定义PowerShell对象输出

来自分类Dev

定义自定义Powershell对象

来自分类Dev

在Powershell中定义自定义对象

来自分类Dev

PowerShell自定义输出@ {n =; e =}

来自分类Dev

Powershell输出的自定义字体颜色

来自分类Dev

自定义对象到CSV PowerShell

来自分类Dev

Powershell:CSV的自定义对象

来自分类Dev

Powershell 数组和自定义对象

来自分类Dev

如何创建Powershell自定义错误输出?

来自分类Dev

powershell 脚本创建自定义列以筛选输出

来自分类Dev

Powershell:向自定义对象添加行

来自分类Dev

通过PowerShell上的Rest获取自定义对象

来自分类Dev

使用Powershell在自定义对象中存储整数

来自分类Dev

Powershell自定义对象隐藏属性类型

来自分类Dev

创建我的自定义对象数组的Powershell

来自分类Dev

Powershell-在自定义对象中组合线

来自分类Dev

powershell:从变量内容填充自定义对象

来自分类Dev

PowerShell:向自定义对象添加“行”

来自分类Dev

Powershell的-split行为取决于方法参数

来自分类Dev

在PowerShell中加载自定义函数

来自分类Dev

Powershell | .jpg的自定义参数/属性

来自分类Dev

PowerShell列的多个自定义标题

来自分类Dev

如何自定义PowerShell继续提示?

来自分类Dev

Powershell自定义表的问题

来自分类Dev

Powershell DataGridViewButtonColumn:自定义按钮文本

来自分类Dev

Powershell:如何创建自定义对象并将其传递给Powershell中的函数?

来自分类Dev

从另一个自定义cmdlet运行许多自定义C#PowerShell cmdlet

来自分类Dev

如何在Powershell中的自定义对象中的每个单独对象上执行foreach循环?

来自分类Dev

Powershell-如何在自定义对象的属性中添加多个对象?

Related 相关文章

热门标签

归档