如何解决PowerShell中Format-List与ConvertTo-Json序列化差异问题
问题原因
Format-List 输出的是PowerShell内置的类型格式化视图,会基于预定义规则自动将复杂嵌套的CIM对象转换为用户友好的展示值;而ConvertTo-Json默认序列化的是对象的原始内存结构,深度不足时就会直接输出类型名称而非友好值。
可行解决方案
方案1:通用扁平化转换函数(推荐)
写一个通用的管道函数,自动将嵌套对象转换为Format-List一致的展示值,无需单独配置每个字段:
function ConvertTo-FlatObject { process { $_ | ForEach-Object { $flatObj = [PSCustomObject]@{} foreach ($prop in $_.PSObject.Properties) { $val = $prop.Value # 处理CIM实例类型(即MSFT_xxx开头的系统对象) if ($val -is [Microsoft.Management.Infrastructure.CimInstance]) { # DNS服务器特殊处理取地址数组,其余取默认ToString()值(和Format-List完全一致) if ($prop.Name -eq "DNSServer") { $val = $val.ServerAddresses -join " " } else { $val = $val.ToString() } } # 数组类型自动拼接为空格分隔的字符串,匹配Format-List输出格式 elseif ($val -is [array]) { $val = $val -join " " } $flatObj | Add-Member -NotePropertyName $prop.Name -NotePropertyValue $val -Force } return $flatObj } } }
使用方法:
Get-NetIPConfiguration | ConvertTo-FlatObject | ConvertTo-Json
输出的JSON字段值和Format-List完全一致,体积和-Depth 1的输出几乎相同。
方案2:直接解析Format-List输出(零自定义成本)
如果不想写自定义函数,可以直接解析Format-List的文本输出转换为JSON,完全匹配展示效果:
Get-NetIPConfiguration | ForEach-Object { $ht = @{} $lastKey = "" $_ | Format-List | Out-String -Stream | Where-Object { $_ -match '^\s*(.+?)\s*:\s*(.*)$' } | ForEach-Object { $key = $matches[1].Trim() $value = $matches[2].Trim() # 处理换行的多值字段(比如多行DNS地址) if ([string]::IsNullOrEmpty($key)) { $ht[$lastKey] += " $value" } else { $ht[$key] = $value $lastKey = $key } } [PSCustomObject]$ht } | ConvertTo-Json
内容的提问来源于stack exchange,提问作者BoppreH
相关产品推荐
相关产品推荐

