5

I have a function in Powershell which populates a list with dictionaries.

Function Process-XML-Audit-File-To-Controls-List($nodelist){
    #Keep an array list to track the different controls
    $control_list = New-Object System.Collections.ArrayList
    foreach($var in $nodelist)
    {  
     $lines  = [string]($var.InnerText) -split '[\r\n]'
     $control_dict = @{}
     foreach($line in $lines){
         $line_split = $line.Trim() -split ':',2
         if($line_split.Length -eq 2){ 
             $control_dict.Add($line_split[0],$line_split[1])       
         }
     }
     $control_list.Add($control_dict)
    }
    return $control_list
}

Instead of receiving an ArrayList which returns only Hashtables it returns a list which has Int32 and Hashtable, where there is an Int32 in it for each hashtable element:

True     True     Int32                                    System.ValueType                                                                                  
True     True     Int32                                    System.ValueType                                                                                  
True     True     Int32                                    System.ValueType                                                                                                                                                                   
True     True     Hashtable                                System.Object                                                                                     
True     True     Hashtable                                System.Object                                                                                     
True     True     Hashtable                                System.Object

I'm not really sure why I have those integers in my ArrayList.

3 Answers 3

11

The problem here is that ArrayList.Add() returns the index at which the new item was added. When you return $control_list, the integers representing the index locations have already been written to the pipeline

Prefix the method call with [void] to remove the output from Add():

[void]$control_list.Add($control_dict)

Or pipe to Out-Null:

$control_list.Add($control_dict) | Out-Null
Sign up to request clarification or add additional context in comments.

Comments

1

Why don't you just declare an empty array and then use "+=" instead of Add()?

$control_list = @()
$hash = [PSCustomObject]@{}
$control_list += $hash

Also, why do you parse the nodes as text?

Comments

0

System.Collections.ArrayList::Add() adds objects, not pairs of key-value, so when you do this $control_dict.Add($line_split[0],$line_split[1]) you are adding two objects, one integer and one hashtable. If you want to use integers as keys instead, you should use a hashtable property assignment, like this:

$control_dict.($line_split[0]) = $line_split[1]

You need to wrap the $line_split[0] into brackets so that the proper key would be added, otherwise the value queried will be $control_dict.$line_split which is valid as hash tables accept objects as keys, and null as never assigned, and then getting [0] out of null value will net you an exception.

1 Comment

Except $control_dict is of type hashtable no? Just tried your method and it still yields the same

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.