title: Can't get data out of ordered dictionary
body: <p>I'm trying to get data out of my ordered dictionary, and for some reason it's not printing the data in it.  I can get to the first item in the data structure, but I'm having trouble iterating over all the rows. I'm using PowerShell 5.1 and visual studio code.</p>
  <p>The code queries an mdb file, and returns multiple rows.</p>
  <pre><code>Function ProcessHelpMDB{
  [cmdletbinding()]
    Param ([string]$mdbLookupError, [string]$mdbFilePath, [string]$mdbPrinterSeries) 
    Process
    {
     $adOpenStatic = 3
     $adLockOptimistic = 3
     $deviceTable = $mdbPrinterSeries + &quot;PP&quot;
     $mdbLookupError -Match '[0-9]*-([0-9]*)'
     $errLookup = $Matches[1]
  
      $selectQuery = “SELECT [$($deviceTable)].[HelpCode],
      [$($deviceTable)].[ScreenNumber],
      [$($deviceTable)].[TextID],
      [$($deviceTable)].[PictureID]
          FROM [$($deviceTable)]
          WHERE
              [$($deviceTable)].[HelpCode] = $($errLookup)&quot;
  
          $cn = new-object -comobject ADODB.Connection
          $rs = new-object -comobject ADODB.Recordset
          $cn.Open(&quot;Provider = Microsoft.ACE.OLEDB.16.0;Data Source = $mdbFilePath&quot;) 
  
          $rs.Open($selectQuery,
          $cn, $adOpenStatic, $adLockOptimistic)
          $i=0
          $ret = [ordered]@{}
          if($rs.EOF)
          {
              Write-Host &quot;$mdbLookupString not in $mdbFileName...record set returned emtpy for query&quot;
          }#if
          else
          {  
              while($rs.EOF -ne $True)
              {
  
                  $result = [ordered]@{}
                  foreach ($field in $rs.Fields)
                  {
                      $result[$field.name] = $field.Value
                  }#result
                  $newObject = [PSCustomObject]$result
                  $ret.Add($i,$newObject) ###ordered dictionary needs key to add values
                  $i++ 
                  $rs.MoveNext()
              } #while
   
              Write-Host &quot;retArr[] $($ret)&quot; #prints retArr[] System.Collections.Specialized.OrderedDictionary
              Write-Host &quot;retArr[0] $($ret[0,&quot;TextID&quot;])&quot; #prints retArr[0]
              Write-Host &quot;retArr[0] $($ret[0])&quot; #prints retArr[0] @{PictureID=HELP_BLAH; TextID=HELP_INFO; HelpCode=9; ScreenNumber=1}
              foreach($row in $ret)
              {
                  foreach($item in $row.value) #it's skipping these
                  {
                      Write-Host $item #
                      Write-Host $item[0] #
                      Write-Host $item[0].'TextID' #
                      Write-Host $item.'TextID' #
                  }#foreach
              }
  
              $cn.Close()
              return $ret
        } #end Process
      }# End of Function process mdb's
  </code></pre>
  <p>The data looks like this in the mdb table:</p>
  <pre><code>HelpCode   ScreenNumber    TextID                PictureID
  1000           1           HELP_INFO             HELP_BLAH
  1000           2           HELP_INFO2            HELP_BLAH2
  ...
  </code></pre>
  <p>My question is, how do I print out the data in the table, from the data structure? I'll need to access it later to re-piece it into a string with other data.  My problem is that I can't figure out how to access each row. in the data structure, and each item individually in each row.  I seem to know how to access the first row, but not other rows.</p>
  <p>I've been looking at this most recently: <a href="https://riptutorial.com/powershell/example/26068/looping-over-a-hash-table" rel="nofollow noreferrer">looping over hash table</a></p>
  <p>Update:
  I got the <code>TextID</code> to print for each row of <code>ret</code> as follows per comments below..thank you!!:</p>
  <pre><code>foreach($row in $ret.GetEnumerator()) #this is working for each row, using 
  {
      Write-Host $row.TextID #prints nothing
      Write-Host $row.'TextID' #prints nothing
      Write-Host $($row.TextID) #prints nothing
      Write-Host $($row.'TextID') #prints nothing
      Write-Host $($row[0].TextID) #prints nothing
      Write-Host $($row[0].'TextID') #prints nothing
      Write-Host $($row[0].Value.TextID) #prints TextID value of current row
      Write-Host $($row[0].Value.'TextID') #prints TextID value of current row
  }
  </code></pre>
  <p>Update2:
  I'm trying to data structure improvement suggested in the answer below.  Thank you!! It's a great simplification.</p>
  <pre><code>$ret = [System.Collections.Generic.List[psobject]]::new() #different data struc
  if($rs.EOF)
  {
      Write-Host &quot;$mdbLookupString not in $mdbFileName...record set returned emtpy for query&quot;
  }#if
  else
  {  
      while($rs.EOF -ne $True)
      {
          $result = [ordered]@{}
          foreach ($field in $rs.Fields)
          {
              $result[$field.name] = $field.Value
          }#result
          $newObject = [PSCustomObject]$result
          $ret.Add($newObject) ###
          $rs.MoveNext()
      } #while
  }#else
  Write-Host &quot;retArr[] $($ret)&quot; #prints retArr[] 
  Write-Host &quot;retArr[0] $($ret[0,&quot;TextID&quot;])&quot; #prints retArr[0]
  Write-Host &quot;retArr[0] $($ret[0])&quot; #prints retArr[0] @{PictureID=...; TextID=...; HelpCode=9; ScreenNumber=1}
  $i=0
  foreach($row in $ret) #goes thru all rows
  {
      Write-Host &quot;retArr[] $($ret)&quot; #prints retArr[] 
      Write-Host &quot;retArr[0] $($ret[$i,&quot;TextID&quot;])&quot; #prints retArr[0] @{HelpCode=9; ScreenNumber=1; TextID=...; PictureID=...}
      Write-Host &quot;retArr[0] $($ret[$i].TextID)&quot; #prints retArr[0] HELP_...
      Write-Host &quot;retArr[0] $($ret[$i].'TextID')&quot; #retArr[0] HELP_...
      ####
      Write-Host &quot;retArr[] $($row)&quot; #prints retArr[] @{HelpCode=9; ScreenNumber=1; TextID=...; PictureID=HELP_...}
      Write-Host &quot;retArr[0] $($row[$i,&quot;TextID&quot;])&quot; #prints retArr[0]
      Write-Host &quot;retArr[0] $($row[$i])&quot; #prints retArr[0] @{HelpCode=9; ScreenNumber=1; TextID=HELP_...; PictureID=HELP_...}
      Write-Host &quot;retArr[0] $($row[$i].TextID)&quot; #prints retArr[0] HELP_...
      Write-Host &quot;retArr[0] $($row[$i].'TextID')&quot; #retArr[0] HELP_...
      $i++
  }
  
  foreach($row in $ret.GetEnumerator()) #this is working for each row
  {
      Write-Host $row.TextID #prints HELP_...
      Write-Host $row.'TextID' #prints HELP_...
      Write-Host $($row.TextID) #prints HELP_...
      Write-Host $($row.'TextID') #prints HELP_...
      Write-Host $($row[0].TextID) #HELP_...
      Write-Host $($row[0].'TextID') #HELP_...
      Write-Host $($row[0].Value.TextID) #prints nothing
      Write-Host $($row[0].Value.'TextID') #prints nothing
  }
  </code></pre>
  <p>This works great. Thanks for the help @mathias!</p>
  <p>Update3:
  I'm trying the pipeline idea from @iRon comment, with update2 (optimized data structure):</p>
  <pre><code>$ret | ForEach-Object {
          Write-Host TextID= $($_.TextID) #prints TextID= HELP_...
          Write-Host TextID= $($_.'TextID') #prints TextID= HELP_...
          Write-Host TextID= $($_.Value.TextID) #prints TextID=
          Write-Host TextID= $($_.Value.'TextID') #prints TextID=
      }
  </code></pre>
  <p>Thanks iRon! That's a good way to access the data in the data structure.     :)</p>