I'm trying to parse the results of PowerShell's Get-NetIPConfiguration
in Python.
The results contain the values I want in the default formatting (Format-List), but not when converted to JSON, which is the format I would like to consume.
Note how DNSServer
is serialized by 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
[...]
while ConvertTo-Json -Depth 1
serializes the DNSServer attribute differently (in a completely useless way):
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#",
"IPv6Address": "",
"IPv6TemporaryAddress": "",
"IPv6LinkLocalAddress": "fe80::d83f:9609:86ff:2b57#",
"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\")"
},
[...]
It's not until depth level 4 that the addresses become visible, but by then the output is several times larger and much harder to navigate.
My current alternative is to pipe the results in Select-Object
and use calculated properties to convert the values myself (in the case of DNSServer it's $_.DNSServer.ServerAddresses -join " "
), but this is cumbersome to do for each property and makes other properties serialize differently too.
How can I force the JSON serializer to format values like the list formatter?
CodePudding user response:
Note how
DNSServer
is serialized byFormat-List
The Format-*
cmdlets do not serialize, they produce for-display string representations, using PowerShell's output-formatting system (as opposed to its serialization infrastructure).
These representations are not meant to be used for programmatic processing, but if you do want to process them as strings, you can pipe them to 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?
Your only option is indeed to simplify the object graph by constructing your own [pscustomobject]
instances, such as via Select-Object
and calculated properties, or in a ForEach-Object
loop with [pscustomobject]
literals (e.g.
[pscustomobject] @{ foo = 'bar'; baz = 'quux' }
).
For instance:
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
}
}
Piping the above to ConvertTo-Json
gives a reasonable representation.
Do note that Get-NetIPConfiguration
's formatting data has additional logic built in that varies the output fields in its for-display representations by adapter type, which the above doesn't take into account.