This should be very simple - I need to return an array of hashtables from a function. This works when there is more than one hashtable, but when there is only one then the result is not an array. I'd rather not test if the result is an array or not.
function GetArrayWith1Hashtable()
{
$array = @()
$hashtable = @{}
$hashtable["a"] = "a"
$hashtable["b"] = "b"
$hashtable["c"] = "c"
$array += $hashtable
Write-Host "GetArrayWith1Hashtable array.Length =" $array.Length
Write-Host "GetArrayWith1Hashtable array.Count" $array.Count
Write-Host "GetArrayWith1Hashtable array[0].Keys" $array[0].Keys
$array
}
function GetArrayWith2Hashtables()
{
$array = @()
$hashtable = @{}
$hashtable["a"] = "a"
$hashtable["b"] = "b"
$hashtable["c"] = "c"
$array += $hashtable
$hashtable2 = @{}
$hashtable2["d"] = "d"
$hashtable2["e"] = "e"
$hashtable2["f"] = "f"
$array += $hashtable2
Write-Host "GetArrayWith2Hashtables array.Length = " $array.Length
Write-Host "GetArrayWith2Hashtables array.Count = " $array.Count
Write-Host "GetArrayWith2Hashtables array[0].Keys =" $array[0].Keys
Write-Host "GetArrayWith2Hashtables array.Count = "$array[1].Keys
$array
}
$result1 = GetArrayWith1Hashtable
# $result1.Length - not available
Write-Host "Result of GetArrayWith1Hashtable result1.Count = " $result1.Count # Count = 2 (would expect this to be 1)
# $result1[0] not available - not an array
$result2 = GetArrayWith2Hashtables
Write-Host "Result of GetArrayWith2Hashtables result2.Length = " $result2.Length # Length = 2
Write-Host "Result of GetArrayWith2Hashtables result2.Count = " $result2.Count # Count = 2
Write-Host "Result of GetArrayWith2Hashtables result2[0].Keys = " $result2[0].Keys # Keys = c a b
Write-Host "Result of GetArrayWith2Hashtables result2[1].Keys = " $result2[1].Keys # Keys = d e f
<#
FULL OUTPUT:
GetArrayWith1Hashtable array.Length = 1
GetArrayWith1Hashtable array.Count 1
GetArrayWith1Hashtable array[0].Keys c a b
Result of GetArrayWith1Hashtable result1.Count = 2
GetArrayWith2Hashtables array.Length = 2
GetArrayWith2Hashtables array.Count = 2
GetArrayWith2Hashtables array[0].Keys = c a b
GetArrayWith2Hashtables array.Count = d e f
Result of GetArrayWith2Hashtables result2.Length = 2
Result of GetArrayWith2Hashtables result2.Count = 2
Result of GetArrayWith2Hashtables result2[0].Keys = c a b
Result of GetArrayWith2Hashtables result2[1].Keys = d e f
#>
Actually you would only add a comma in front of your returned item like so. This tells PowerShell to return it as is without trying to be smart about it. This also allows you to fix it in one place and not everywhere it was being called.
function GetArrayWith1Hashtable()
{
$array = @()
$hashtable = @{}
$hashtable["a"] = "a"
$hashtable["b"] = "b"
$hashtable["c"] = "c"
$array += $hashtable
Write-Host "GetArrayWith1Hashtable array.Length =" $array.Length
Write-Host "GetArrayWith1Hashtable array.Count" $array.Count
Write-Host "GetArrayWith1Hashtable array[0].Keys" $array[0].Keys
# The only edit was to add the comma below
,$array
}
Update: Though, I don't think you are wanting this functionality, I will mention it so that others will understand the difference and make an educated choice for their approach.
To have your function be compatible to be used more efficiently within pipelines, the better approach would be to make a call to Write-Output for each item.
function GetArrayWith1Hashtable()
{
Write-Output "a"
Write-Output "b"
Write-Output "c"
}
By using Write-Output, you are allowing PowerShell to call the next command's Process block in the pipeline, individually for each object. Otherwise it would call the next command and pass a single array object to it. You can read more about piping objects here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With