PowerShell DISCUSSION

Why does my PowerShell function return an array of extra values instead of only the value after return?

Started by ksravankumarreddy PowerShell function outputreturn statementpipeline outputOut-NullWrite-Host vs Write-Output
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

Why does my PowerShell function return an array of extra values instead of only the value after return?

ksravankumarreddy PowerShell Forum
#1

This function should return a total: inside it I create $list = New-Object System.Collections.ArrayList, call $list.Add(5) and $list.Add(7), print a progress message, and finish with return 12. The caller does $total = Get-Total and gets an array containing 0, 1 and 12 instead of just 12.

Where do the 0 and 1 come from, and how do I make a function return exactly one value?

Community replies 5

Re: Why does my PowerShell function return an array of extra values instead of only the value after return?

#2

A PowerShell function does not return only what follows return. Every value produced by any statement in the body that is not assigned to a variable or redirected is written to the function's output stream, and the caller receives all of it. return 12 simply means "output 12, then leave the function".

ArrayList.Add returns the index at which the item was inserted, so the two calls emit 0 and 1. Those, followed by 12, make up the three-element array you see.

Re: Why does my PowerShell function return an array of extra values instead of only the value after return?

#3

Discard the values you do not want. Any of these works: [void]$list.Add(5), $null = $list.Add(5) or $list.Add(5) | Out-Null. The first two avoid setting up a pipeline and are the usual choice inside loops.

Better still, use [System.Collections.Generic.List[int]]::new() instead of ArrayList. Its Add method returns nothing, so there is nothing to suppress, and the list is typed.

Re: Why does my PowerShell function return an array of extra values instead of only the value after return?

#4

Progress messages must not go to the output stream either. Write-Output "working", or a bare string on a line of its own, becomes part of the return value. Write-Host writes to the host display (the information stream since PowerShell 5) and Write-Verbose writes to the verbose stream, shown only when the caller passes -Verbose to an advanced function. Neither affects what the caller captures.

To find a leak, call the function without assigning it and see what is printed, or check (Get-Total).Count and Get-Total | ForEach-Object { $_.GetType().Name }.

Re: Why does my PowerShell function return an array of extra values instead of only the value after return?

#5

Related behaviour that surprises people: collections written to the output stream are unrolled. A function that outputs an array with three items gives the caller three objects; one that outputs a single-item array gives back just that item, not an array; and one that outputs nothing gives $null. If the caller always needs an array, wrap the call: $items = @(Get-Items), and then $items.Count is reliably 0, 1 or more.

To hand back a collection as one object, prefix it with the unary comma, return ,$list, or use Write-Output -NoEnumerate $list.

Re: Why does my PowerShell function return an array of extra values instead of only the value after return?

#6

If you want strict, C#-like return semantics, PowerShell classes provide them. In a class method only the return statement produces the result; stray values inside the method body are discarded rather than leaked, and the declared return type is enforced. For ordinary functions, the convention is the opposite of other languages: leave out return unless you need to exit early, and think of the function as emitting objects to a pipeline, which is what lets your own functions be combined with Where-Object and Sort-Object like any cmdlet.

TEP COMMUNITY