0

This is curiosity, I'm not stuck, just wondering... I've never seen this behaviour before and couldn't find the reason...

The code I'm executing works fine but I don't understand why the order of my columns doesn't match the order I'm adding them to my $record...

So I create these :

$result = @()

$record = @{

    "Server" = ""
    "Primary DNS" = ""
    "Secundary DNS" = ""
    "DHCP Enabled" = ""

}

Later I add my values :

$record."Server" = $server
$record."Primary DNS" = $DNS1
$record."Secundary DNS" = $DNS2
$record."DHCP Enabled" = $NetAdapter.DHCPEnabled
$objRecord = New-Object psobject -Property $record
$result += $objRecord

But then the output of $result gives me a table where the columns go "Primary DNS", "DHCP Enabled", "Server", "Secundary DNS".

It's not random... if I don't specify an order myself with Select-Object, the above order is always the one I get.

Thanks in advance for the education (^^,)

  • Another (possible) learning item: [try to avoid using the increase assignment operator (`+=`) to create an object collection](https://stackoverflow.com/a/60708579/1701026) as it is exponential expensive. – iRon Jul 17 '20 at 12:20
  • 1
    Alright iRon - thanks ! Took me a few trials to figure out how I had to change my code but in the end it was pretty simple. Basically I removed `$result = @()` and I replaced `$result += $objRecord` with `$objRecord` (and now I can either have that output or pipe to `Export-CSV` or whatever...) Thanks again ! – Michel Balencourt Sep 08 '20 at 13:40

2 Answers2

3

@{ ... } creates a Hashtable, which doesn't have a defined order for the entries:

PS> $record = @{
  "Server" = ""
  "Primary DNS" = ""
  "Secundary DNS" = ""
  "DHCP Enabled" = ""
}

PS> $record.GetType().FullName
System.Collections.Hashtable

PS> $record
Name                           Value
----                           -----
Primary DNS
DHCP Enabled
Server
Secundary DNS

If you use [ordered] @{ ... } it creates an OrderedDictionary instead, which does maintain the order of entries:

PS> $record = [ordered] @{
  "Server" = ""
  "Primary DNS" = ""
  "Secundary DNS" = ""
  "DHCP Enabled" = ""
}

PS> $record.GetType().FullName
System.Collections.Specialized.OrderedDictionary

PS> $record

Name                           Value
----                           -----
Server
Primary DNS
Secundary DNS
DHCP Enabled
mclayton
  • 8,025
  • 2
  • 21
  • 26
1

@mclayton posted an helpful answer regarding ordered list. As we can see, you are adding the values later, then you can use this format:

$record = New-Object PSObject
$record | Add-Member -MemberType NoteProperty -Name Server -Value $server -PassThru | 
Add-Member -MemberType NoteProperty -Name "Primary DNS" -Value $DNS1 -PassThru |
Add-Member -MemberType NoteProperty -Name "Secondary DNS" -Value $DNS2 -PassThru | 
Add-Member -MemberType NoteProperty -Name "DHCP Enabled" -Value $NetAdapter.DHCPEnabled -PassThru
$objRecord = [pscustomobject]$record
Wasif
  • 14,755
  • 3
  • 14
  • 34