如何从 Powershell v3 中的哈希数组生成 PSCustomObjects 数组?

How can I generate an array of PSCustomObjects from an array of hashes in Powershell v3?

假设我在 Powershell v3 中有一个哈希数组:

> $hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}

我可以像这样将单个散列转换成 PSCustomObject

> $co = [PSCustomObject] $hashes[0]
> $co | ft -AutoSize

Value Name  
----- ----  
    1 Item 1

> $co.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object 

到目前为止,还不错。当我尝试将整个哈希数组转换为管道中的 PSCustomObjects 时出现问题:

> ($hashes | foreach { [PSCustomObject] $_})[0].getType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     -------- 
True     True     Hashtable                                System.Object

如您所见,我得到了 Hashtable 个对象的数组,而不是 PSCustomObjects。为什么我会得到不同的行为,我怎样才能完成我想要的?

谢谢。

尝试直接调用 New-Object 而不是转换:

# > ($hashes | foreach { New-Object -TypeName PSCustomObject -Property $_})[0].getType()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                  
-------- -------- ----                                     --------                                                                                                                                                  
True     False    PSCustomObject                           System.Object    

此外,奇怪的是,这似乎有效:

# > (0..4 |  foreach { ([PSCustomObject]$hashes[$_])})[0].GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                  
-------- -------- ----                                     --------                                                                                                                                                  
True     False    PSCustomObject                           System.Object                   

为什么?我不知道,使用流水线哈希表条目执行转换似乎有问题。

这似乎有效:

$hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}

foreach ($hash in $hashes)
{([PSCustomObject]$hash).gettype()}

我还没有找出确切的原因(每个人都还在学习一些东西)但是你的问题不知何故与 $_ 管道元素有关。如果我强制转换 $_

,我可以让你的代码工作
$hashes = 1..5 | foreach { @{Name="Item $_"; Value=$_}}
$hashes | %{([pscustomobject][hashtable]$_)}

输出

Value Name  
----- ----  
    1 Item 1
    2 Item 2
    3 Item 3
    4 Item 4
    5 Item 5

有点好奇

我在测试时不喜欢 NameValue(这就是文字散列 table 对 headers 的影响,我发现它令人困惑在我测试时),所以我将后者更改为 Data 然后输出不同。我只是post它,因为它很好奇。很难在 post.

中显示结果
Name                                                                                                                                                     Data
----                                                                                                                                                     ----
Item 1                                                                                                                                                      1
Item 2                                                                                                                                                      2
Item 3                                                                                                                                                      3
Item 4                                                                                                                                                      4
Item 5                                                                                                                                                      5

似乎管道变量 $_ 的值被包装到 PSObject 中,并且 break 转换为 PSCustomObject

> $hashes=@{Value=1},[PSObject]@{Value=2}

> $hashes[0].GetType().FullName
System.Collections.Hashtable
> $hashes[1].GetType().FullName
System.Collections.Hashtable
# It seems that both $hashes elements are Hashtable,

> [Type]::GetTypeArray($hashes).FullName
System.Collections.Hashtable
System.Management.Automation.PSObject
# But, as you can see, second one is not.

> ([PSCustomObject]$hashes[0]).GetType().FullName
System.Management.Automation.PSCustomObject
> ([PSCustomObject]$hashes[1]).GetType().FullName
System.Collections.Hashtable
# And that difference break cast to PSCustomObject.