Reputation: 203
Is it possible to format the output of a hashtable in Powershell to output all the values onto one line?
e.g.
I have the hash table $hashErr with the below values:
$hashErr = @{"server1" = "192.168.17.21";
"server2" = "192.168.17.22";
"server3" = "192.168.17.23"}
Which are written to a log with the below:
$hashErr.GetEnumerator() | Sort-Object Name | ForEach-Object {ForEach-Object {"{0}`t{1}" -f $_.Name,($_.Value -join ", ")} | Add-Content $log
The will cause the below to be written to the log:
Name Value
---- -----
server2 192.168.17.22
server1 192.168.17.21
server3 192.168.17.23
My question is, how can I format this hash table so the output is written all to one line, like the below?
server2 192.168.17.22 | server1 192.168.17.21 | server3 192.168.17.23
This could be done by looping through all the values in the hash table and putting them into an array but surely there is a more direct way?
Upvotes: 20
Views: 46123
Reputation: 1174
Not the exact output as you want but also 1 line output.
$hashErr | ConvertTo-Json -Compress
outputs:
{"server2":"192.168.17.22","server3":"192.168.17.23","server1":"192.168.17.21"}
Upvotes: 14
Reputation: 342
GetEnumerator allows to iterate over the Key-Value pairs. The resulting code looks looks alot cleaner and easier to understand.
($hashErr.GetEnumerator() | ForEach-Object{ "$($_.Key) $($_.Value)" }) -join " | "
server2 192.168.17.22 | server3 192.168.17.23 | server1 192.168.17.21
Upvotes: 0
Reputation: 3080
A bit late to the party, expanding on @mjolinor's solution, you can use the type accelerator [ordered]:
$hashErr = [ordered]@{"server1" = "192.168.17.21";
"server2" = "192.168.17.22";
"server3" = "192.168.17.23"}
$hashErr.Keys.ForEach({"$_ $($hashErr.$_)"}) -join ' | '
server1 192.168.17.21 | server2 192.168.17.22 | server3 192.168.17.23
I think [ordered] was introduced in PS v. 3.0.
Upvotes: 2
Reputation: 68263
The V4 version of Richard's solution:
$hashErr = @{"server1" = "192.168.17.21";
"server2" = "192.168.17.22";
"server3" = "192.168.17.23"}
$hashErr.Keys.ForEach({"$_ $($hashErr.$_)"}) -join ' | '
server3 192.168.17.23 | server2 192.168.17.22 | server1 192.168.17.21
Upvotes: 6
Reputation: 95652
Do you want to keep the sorting, and support for multiple ip addresses on a single server, both of which are in the code you showed but not in your output?
If so I think the best you'll get is just a minor modification on the original:
C:\scripts> ($hashErr.GetEnumerator() | sort Name | % { "$($_.Name) $($_.Value -join ',')" }) -join "|"
server1 192.168.17.21|server2 192.168.17.22|server3 192.168.17.23,1.2.3.4
Upvotes: 1
Reputation: 108985
You can iterate over the keys of a hash table, and then in the loop lookup the values. By using the pipeline you don't need an intermediate collection:
($hashErr.Keys | foreach { "$_ $($hashErr[$_])" }) -join "|"
Upvotes: 13