PowerShell 的 Format-List 和 ConvertTo-Json 之间的序列化差异
Serialization differences between PowerShell's Format-List and ConvertTo-Json
我正在尝试在 Python 中解析 PowerShell Get-NetIPConfiguration
的结果。
结果包含我想要的默认格式(格式列表)的值,但在转换为 JSON 时不包含,这是我想要使用的格式。
注意 DNSServer
是如何被 Format-List
序列化的:
PS C:\Users\BoppreH> Get-NetIPConfiguration | Format-List
InterfaceAlias : VirtualBox Host-Only Network
InterfaceIndex : 23
InterfaceDescription : VirtualBox Host-Only Ethernet Adapter
IPv4Address : 192.168.56.1
IPv6DefaultGateway :
IPv4DefaultGateway :
DNSServer : fec0:0:0:ffff::1
fec0:0:0:ffff::2
fec0:0:0:ffff::3
[...]
而 ConvertTo-Json -Depth 1
以不同方式序列化 DNSServer 属性(以完全无用的方式):
PS C:\Users\BoppreH> Get-NetIPConfiguration | ConvertTo-Json -Depth 1
[
{
"Detailed": false,
"ComputerName": "BOPPREH-DESKTOP",
"InterfaceAlias": "VirtualBox Host-Only Network",
"InterfaceIndex": 23,
"InterfaceDescription": "VirtualBox Host-Only Ethernet Adapter",
"CompartmentId": 1,
"NetAdapter": "MSFT_NetAdapter (CreationClassName = \"MSFT_NetAdapter\", DeviceID = \"{EAF79493-7C78-44D2-ADB4-F3EF196D2F49}\", SystemCreationClassName = \"CIM_NetworkPort\", SystemName = \"boppreh-desktop\")",
"NetCompartment": "MSFT_NetCompartment (InstanceID = \";55;\")",
"NetIPv6Interface": "MSFT_NetIPInterface (Name = \"??55??55;\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"\")",
"NetIPv4Interface": "MSFT_NetIPInterface (Name = \"??55?55;\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"\")",
"NetProfile": null,
"AllIPAddresses": "192.168.56.1 fe80::d83f:9609:86ff:2b57%23",
"IPv6Address": "",
"IPv6TemporaryAddress": "",
"IPv6LinkLocalAddress": "fe80::d83f:9609:86ff:2b57%23",
"IPv4Address": "192.168.56.1",
"IPv6DefaultGateway": null,
"IPv4DefaultGateway": null,
"DNSServer": "MSFT_DNSClientServerAddress (Name = \"23\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"23\") MSFT_DNSClientServerAddress (Name = \"23\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"2\")"
},
[...]
直到深度级别 4 地址才可见,但到那时输出会大几倍并且更难导航。
我目前的替代方法是将结果通过管道传输到 Select-Object
并使用计算属性自行转换值(在 DNSServer 的情况下是 $_.DNSServer.ServerAddresses -join " "
),但这对每个人来说都很麻烦属性 并使其他属性也以不同方式序列化。
如何强制 JSON 序列化程序像列表格式化程序一样格式化值?
Note how DNSServer
is serialized by Format-List
Format-*
cmdlet 不序列化,它们使用 PowerShell 的output-formatting system (as opposed to its 生成用于显示的字符串表示 ]).
这些表示 不是 用于 程序化处理 ,但如果您确实想将它们处理为 strings,你可以将它们传送到 Out-String
:
# Returns a single-line string; add -Stream to get an array of lines.
# Add -Width to explicitly specify a line width (console window width is the default).
# Note: Since Format-List is used for formatting *by default*,
# you don't strictly need the Format-List here.
# Alternatively, use Format-Table for a *table* representation
$stringRep = Get-NetIPConfiguration | Format-List | Out-String
How can I force the JSON serializer to format values like the list formatter?
您唯一的选择确实是通过构建您自己的 [pscustomobject]
实例来简化对象图,例如通过 Select-Object
and calculated properties, or in a ForEach-Object
循环 [pscustomobject]
文字 (例如
[pscustomobject] @{ foo = 'bar'; baz = 'quux' }
).
例如:
Get-NetIPConfiguration | ForEach-Object {
[pscustomobject] @{
InterfaceAlias = $_.InterfaceAlias
InterfaceIndex = $_.InterfaceIndex
InterfaceDescription = $_.InterfaceDescription
'NetProfile.Name' = $_.NetProfile.Name
IPv4Address = $_.IPv4Address -join "`n"
IPv6DefaultGateway = $_.IPv6DefaultGateway.NextHop
IPv4DefaultGateway = $_.IPv4DefaultGateway.NextHop
}
}
将以上内容通过管道传输到 ConvertTo-Json
给出了合理的表示。
请注意,Get-NetIPConfiguration
的 formatting data 具有额外的内置逻辑,可以根据适配器类型 改变其显示表示中的输出字段 ,以上没有考虑到。
我正在尝试在 Python 中解析 PowerShell Get-NetIPConfiguration
的结果。
结果包含我想要的默认格式(格式列表)的值,但在转换为 JSON 时不包含,这是我想要使用的格式。
注意 DNSServer
是如何被 Format-List
序列化的:
PS C:\Users\BoppreH> Get-NetIPConfiguration | Format-List
InterfaceAlias : VirtualBox Host-Only Network
InterfaceIndex : 23
InterfaceDescription : VirtualBox Host-Only Ethernet Adapter
IPv4Address : 192.168.56.1
IPv6DefaultGateway :
IPv4DefaultGateway :
DNSServer : fec0:0:0:ffff::1
fec0:0:0:ffff::2
fec0:0:0:ffff::3
[...]
而 ConvertTo-Json -Depth 1
以不同方式序列化 DNSServer 属性(以完全无用的方式):
PS C:\Users\BoppreH> Get-NetIPConfiguration | ConvertTo-Json -Depth 1
[
{
"Detailed": false,
"ComputerName": "BOPPREH-DESKTOP",
"InterfaceAlias": "VirtualBox Host-Only Network",
"InterfaceIndex": 23,
"InterfaceDescription": "VirtualBox Host-Only Ethernet Adapter",
"CompartmentId": 1,
"NetAdapter": "MSFT_NetAdapter (CreationClassName = \"MSFT_NetAdapter\", DeviceID = \"{EAF79493-7C78-44D2-ADB4-F3EF196D2F49}\", SystemCreationClassName = \"CIM_NetworkPort\", SystemName = \"boppreh-desktop\")",
"NetCompartment": "MSFT_NetCompartment (InstanceID = \";55;\")",
"NetIPv6Interface": "MSFT_NetIPInterface (Name = \"??55??55;\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"\")",
"NetIPv4Interface": "MSFT_NetIPInterface (Name = \"??55?55;\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"\")",
"NetProfile": null,
"AllIPAddresses": "192.168.56.1 fe80::d83f:9609:86ff:2b57%23",
"IPv6Address": "",
"IPv6TemporaryAddress": "",
"IPv6LinkLocalAddress": "fe80::d83f:9609:86ff:2b57%23",
"IPv4Address": "192.168.56.1",
"IPv6DefaultGateway": null,
"IPv4DefaultGateway": null,
"DNSServer": "MSFT_DNSClientServerAddress (Name = \"23\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"23\") MSFT_DNSClientServerAddress (Name = \"23\", CreationClassName = \"\", SystemCreationClassName = \"\", SystemName = \"2\")"
},
[...]
直到深度级别 4 地址才可见,但到那时输出会大几倍并且更难导航。
我目前的替代方法是将结果通过管道传输到 Select-Object
并使用计算属性自行转换值(在 DNSServer 的情况下是 $_.DNSServer.ServerAddresses -join " "
),但这对每个人来说都很麻烦属性 并使其他属性也以不同方式序列化。
如何强制 JSON 序列化程序像列表格式化程序一样格式化值?
Note how
DNSServer
is serialized byFormat-List
Format-*
cmdlet 不序列化,它们使用 PowerShell 的output-formatting system (as opposed to its
这些表示 不是 用于 程序化处理 ,但如果您确实想将它们处理为 strings,你可以将它们传送到 Out-String
:
# Returns a single-line string; add -Stream to get an array of lines.
# Add -Width to explicitly specify a line width (console window width is the default).
# Note: Since Format-List is used for formatting *by default*,
# you don't strictly need the Format-List here.
# Alternatively, use Format-Table for a *table* representation
$stringRep = Get-NetIPConfiguration | Format-List | Out-String
How can I force the JSON serializer to format values like the list formatter?
您唯一的选择确实是通过构建您自己的 [pscustomobject]
实例来简化对象图,例如通过 Select-Object
and calculated properties, or in a ForEach-Object
循环 [pscustomobject]
文字 (例如
[pscustomobject] @{ foo = 'bar'; baz = 'quux' }
).
例如:
Get-NetIPConfiguration | ForEach-Object {
[pscustomobject] @{
InterfaceAlias = $_.InterfaceAlias
InterfaceIndex = $_.InterfaceIndex
InterfaceDescription = $_.InterfaceDescription
'NetProfile.Name' = $_.NetProfile.Name
IPv4Address = $_.IPv4Address -join "`n"
IPv6DefaultGateway = $_.IPv6DefaultGateway.NextHop
IPv4DefaultGateway = $_.IPv4DefaultGateway.NextHop
}
}
将以上内容通过管道传输到 ConvertTo-Json
给出了合理的表示。
请注意,Get-NetIPConfiguration
的 formatting data 具有额外的内置逻辑,可以根据适配器类型 改变其显示表示中的输出字段 ,以上没有考虑到。