Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreach Loop in PowerShell Not in Order

I am working with a config file for PowerShell and every time I call a foreach loop to grab the data it grabs it in the wrong order. See below:

config.ini

[queries]

query01=stuff1

query02=stuff2

query03=stuff3

query04=stuff4

The foreach loop:

#Loads an INI file data into a variable
$iniContent = Get-IniContent 'config.ini'
#grabs the hashtable for the data under the [queries] section
$queries = $iniContent['queries']

foreach($query in $queries.GetEnumerator())
{
    write-host $query.name
}

I get the following output:

stuff1
stuff4
stuff2
stuff3

I am assuming this has something to do with asynchronous processing from PowerShell, but what would be the best way to handle the queries from the config.ini file in the order I store them in there?

Note: I added the number to the end of the query (query01) just for testing purposes. The queries will not have them in my final config.ini.

EDIT:

Get-IniContent function:

function Get-IniContent ($filePath)
{
    $ini = @{}
    switch -regex -file $FilePath
    {
        “^\[(.+)\]” # Section
        {
            $section = $matches[1]
            $ini[$section] = @{}
            $CommentCount = 0
        }
        “(.+?)\s*=(.*)” # Key
        {
            $name,$value = $matches[1..2]
            $ini[$section][$name] = $value
        }
    }
    return $ini
}
like image 539
Webtron Avatar asked Dec 15 '22 03:12

Webtron


1 Answers

You need to change both hashtable declarations to ordered dictionaries. If you only change

$ini = @{}

to

$ini = [ordered]@{}

your $ini is now an ordered dictionay but the nested hashtable created at

$ini[$section] = @{}

is still an unordered hashtable. You would need to change both of them to ordered dictionaries.

function Get-IniContent ($filePath)
{
  $ini = [ordered]@{}
  switch -regex -file $FilePath
  {
    “^\[(.+)\]” # Section
    {
        $section = $matches[1]
        $ini[$section] = [ordered]@{}
        $CommentCount = 0
    }
    “(.+?)\s*=(.*)” # Key
    {
        $name,$value = $matches[1..2]
        $ini[$section][$name] = $value
    }
  }
  return $ini
}

EDIT

There is also a ConvertTo-OrderedDictionary script on the Script Center that allows you to convert hashtables and arrays to ordered dictionaries if you don't want to rewrite your function.

like image 112
StephenP Avatar answered Jan 04 '23 08:01

StephenP