为何PowerShell的ConvertTo-Json管道输入与InputObject参数行为不同?
PowerShell中ConvertTo-Json管道传递与-InputObject参数的行为差异解析
核心原因在于PowerShell管道与-InputObject参数处理集合的逻辑完全不同:
1. 管道传递的处理逻辑
当使用Get-PhysicalDisk | ConvertTo-Json时,PowerShell管道会将Get-PhysicalDisk输出的每个磁盘对象逐个传递给ConvertTo-Json。cmdlet会针对每个对象单独序列化,最终拼接成一个JSON数组(顶层结构为[...])。
转换回对象后,$disks是包含多个磁盘对象的数组,PowerShell会自动枚举数组的属性,因此直接访问$disks.Size会返回所有磁盘的Size值,符合预期。
2. -InputObject参数的处理逻辑
当使用ConvertTo-Json -InputObject (Get-PhysicalDisk)时,Get-PhysicalDisk返回的整个对象集合会被当作单个整体对象传入参数。此时ConvertTo-Json会把这个集合(本质是System.Collections.ObjectModel.Collection类型)序列化成包含Count和Value属性的JSON结构:
{ "Count": 1, "Value": [ { "Size": 1024209543168, // 其他磁盘属性 } ] }
经过ConvertFrom-Json转换后,$disks是一个包含Value数组的顶层对象,Size属性嵌套在$disks.Value中,直接访问$disks.Size自然返回$null。
验证差异
可以直接输出两种方式生成的JSON字符串对比结构:
# 管道方式生成JSON数组 Get-PhysicalDisk | ConvertTo-Json -Depth 1 # -InputObject方式生成包含Count/Value的对象 ConvertTo-Json -InputObject (Get-PhysicalDisk) -Depth 1
解决办法
要让-InputObject实现和管道一致的效果,需要手动展开集合:
# 方法1:用@()强制展开集合为多个对象 $jsonString = ConvertTo-Json -InputObject @(Get-PhysicalDisk) $disks = $jsonString | ConvertFrom-Json $disks.Size # 方法2:保持管道传递的方式(最直接推荐) $jsonString = Get-PhysicalDisk | ConvertTo-Json $disks = $jsonString | ConvertFrom-Json $disks.Size
内容的提问来源于stack exchange,提问作者Jelphy
相关产品推荐
相关产品推荐

