'Blank records when returning ArrayList of PSObjects from function
So I'm refactoring a Powershell script and moving a lot of stuff into functions. When I return an ArrayList of 42 PSObjects from a function (called Get-OutList) with return $out, 42 blank records are inserted into the beginning of the ArrayList, and my original records then follow.
My function looks like this:
function Get-OutList {
param (
[Parameter(Position=0,mandatory=$true)]
[PSObject]$RoleCollection,
[Parameter(Position=1,mandatory=$true)]
[PSObject]$MemberCollection
)
$out = New-Object System.Collections.ArrayList
$MemberCollection.result | ForEach-Object {
$currentMember = $_
$memberDetail = New-Object PSObject
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name FirstName -Value $($currentMember.user.first_name)
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name LastName -Value $($currentMember.user.last_name)
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name Email -Value $($currentMember.user.email)
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name Status -Value $($currentMember.status)
$RoleCollection.result | ForEach-Object {
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name $_.name -Value (&{If($currentMember.roles.name -contains $_.name){"Y"}Else{""}})
}
$out.Add($memberDetail)
}
return $out
}
I understand Powershell enumerates each record back to where the function was called, and I've tried a few things to no avail:
- Behaviour is the same in PS v5.1.x and v7.3.0.
- Returning with
return @($out)makes no difference (i.e. results in a System.Object with 42 blank records followed by my 42 original records for a total of 84 records). - Returning with
return Write-Output -NoEnumerate $outresults in a System.Object with 42 blank records and my 42 original records nested in a 43rd record. - Typing the result of the function call as ArrayList with
$results = [System.Collections.ArrayList](Get-OutList)makes no difference.
Why can't I get my object to be the same as before it's returned from a function?? Any assistance would be greatly appreciated!
Edit #1 Including an easily-reproducible example:
function Get-OutList {
param (
[Parameter(Position=0,mandatory=$true)]
[PSObject]$MemberCollection
)
$out = New-Object 'System.Collections.ArrayList'
$MemberCollection | ForEach-Object {
$memberDetail = New-Object PSObject
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name FirstName -Value "One"
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name LastName -Value "Two"
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name Email -Value "Three"
Add-Member -InputObject $memberDetail -MemberType NoteProperty -Name Status -Value "Four"
$out.Add($memberDetail)
}
return $out
}
$members = @("Joe Bloggs", "Some Dude", "The Dude")
$memberDetails = Get-OutList -MemberCollection $members
Write-Output $memberDetails
If you add a breakpoint before $out is passed back, you'll see there are three records, and if you keep stepping, you should see $memberDetails will have six records (the first three blank).
Edit #2
Appears there's no such problem when using Generic.List instead of ArrayList. Used $out = [System.Collections.Generic.List[PSObject]]::new() instead of $out = New-Object 'System.Collections.ArrayList' and it's working just fine.
Solution 1:[1]
Used $out = [System.Collections.Generic.List[PSObject]]::new() instead of $out = New-Object 'System.Collections.ArrayList' and it's working just fine. No extra blankies.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nathan C |
