【问题标题】:How to create a custom hashtable with arrays of objects - powershell / cmd如何使用对象数组创建自定义哈希表 - powershell / cmd
【发布时间】:2019-11-16 07:10:21
【问题描述】:

尝试使用 get-WmiObject 从类中获取多个对象。我必须将其作为哈希表/字典类型返回。

我正在使用的命令:


get-WmiObject -class win32_SoundDevice | select-object Name, Status

我得到了什么:

Name                   Status
----                   ------
Intel(R) Display Audio OK
Realtek Audio          OK

我想创建一个看起来像这样的东西:

[
    {
        "Name":  "Intel(R) Display Audio",
        "Status":  "OK"
    },
    {
        "Name":  "Realtek Audio",
        "Status":  "OK"
    }
]

我知道我可以将 | convertTo-json 命令附加到初始命令,但我想从头开始创建哈希表,因为我将在可能不使用 convertTo-json 命令的旧系统上使用它。

【问题讨论】:

  • “哈希表”是什么意思?我在您的示例中的任何地方都看不到任何哈希表... [grin]
  • Select-Object 返回System.Management.Automation.PSObject,而不是哈希表。 ConvertTo-Json 在 PowerShell 3.0+ 中可用。
  • @Lee_Dailey key : 值对对象,格式如上所示。
  • @JosefZ 正如我在底部所说,我不想依赖 convertto-Json 命令。
  • 第二次@Lee_Dailey 你想要什么? Hashtable 类型的对象、Dictionary 类型的对象、自定义 PS 对象、以 JSON 格式格式化的 text 类型的对象?通过简单地将命令的输出分配给一个变量,您就拥有了一个键值对象的对象数组。

标签: arrays powershell object command hashtable


【解决方案1】:

如果您无法使用 ConvertTo-Json cmdlet,这应该会有所帮助:

function ConvertTo-Json20([object] $item){
    # serializes object(s) to JSON. The result will be in compressed format.
    Add-Type -AssemblyName System.Web.Extensions

    $jsSerializer = New-Object System.Web.Script.Serialization.JavascriptSerializer
    return $jsSerializer.Serialize($item)
}


# When using 'Select-Object Name, Status' you will get an array of PSObjects which the above function 
# cannot handle. Therefore, I'm using Old-School to get the results from the Get-WmiObject cmdlet
# into an array of Hashtables.

$result = Get-WmiObject -Class win32_SoundDevice | ForEach-Object {
    @{
        'Name' = $_.Name
        'Status' = $_.Status
    }
}

ConvertTo-Json20 $result

在我的机器上,结果是

[{"Name":"Conexant ISST Audio","Status":"OK"},{"Name":"Intel(R) 显示音频","状态":"OK"}]

【讨论】:

  • 追加到数组是一项昂贵的内存操作。请不要教别人这样做。您实际上可以通过捕获循环的所有输出在内存中分配一次变量。只需$result = Get-WmiObject -Class win32_SoundDevice | ForEach-Object { @{ 'Name' = $_.Name; 'Status' = $_.Status } }
  • @JosefZ 你是对的,尽管在他的案例中,内存影响可以忽略不计,因为迭代次数很少。更新了我的答案。
【解决方案2】:

要将 PowerShell 对象序列化为 PowerShell 表达式,您可以考虑使用此 ConvertTo-Expression cmdlet:

ConvertTo-Expression (get-WmiObject -class win32_SoundDevice | select-object Name, Status)

结果:

[PSCustomObject]@{
        'Name' = 'USB Multi-Channel Audio Device'
        'Status' = 'OK'
},
[PSCustomObject]@{
        'Name' = 'High Definition Audio Device'
        'Status' = 'OK'
},
[PSCustomObject]@{
        'Name' = 'High Definition Audio Device'
        'Status' = 'OK'
}

欲了解更多信息,请参阅:Save hash table in PowerShell object notation (PSON)

【讨论】:

  • 请注意,PSv3 之前的旧系统不支持通过[PSCustomObject]@{...} 方法创建对象。对于此系统,您应该使用 New-Object cmdlet。因此,您可能希望使用ConvertTo-Expression -Explore 开关,该开关将抑制所有类型前缀,从而导致任何对象转换为HashTable
猜你喜欢
  • 2011-03-01
  • 2021-02-15
  • 2010-10-22
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
相关资源
最近更新 更多