Is there a way to clear the return values inside of a function so I can guarantee that the return value is what I intend? Or maybe turn off this behaviour for the function?<
Why not using the Powershell Array
object, instead of the .Net arrayList ?
You could do something like :
function GetArray() {
# set $myArray as a powershell array
$myArray = @()
$myArray+="Hello"
$myArray+="World"
# $myArray=@("Hello", "World") would work as well
return $myArray
}
This will return a "clean" array, as expected.
If you really need to get a System.collections.ArrayList, you could do it in 2 steps :
Convert your powershell array in a .Net arrayList this way :
# Get the powershellArray
$x = getArray
# Create a .Net ArrayList
$myArrayList = New-Object System.Collections.ArrayList
# Fill your arraylist with the powershell array
$myArrayList.AddRange($x)
Hoping this helps a bit.
Using the information from user1654962, here is the way that I worked around this PowerShell issue. Since, if there is output information, PowerShell will return it as an array, I decided to make sure the function output was always an array. Then the calling line can use [-1] to get the last element of the array and we'll get a consistent return value.
function DoSomething()
{
# Code that could create output
Write-Output "Random output that we don't need to return"
Write-Output "More random output"
# Create the return value. It can be a string, object, etc.
$MyReturnString = "ImportantValue"
# Other code
# Make sure the return value is an array by preceding it with a comma
return ,$MyReturnString
}
$CleanReturnValue = ( DoSomething() )[-1]
I too am having this exact same frustration! I had a function where a variable is supposed to count up $<variablename>
++
Except. I had forgotten the "++" at the end in one iteration. Which was causing the variable's value to be sent to the output buffer. It was very aggravating and time consuming to find! MS should have provided, at minimum, an ability to flush the output buffer before the user gets to assign their desired return value. Anywhew... I believe I have a work around.
Since I assign a return value at the end of the function, my desired value will always be the last entry of the output buffer array. So I've changed the way I call my functions from:
If (FunctionName (parameters)) {}
To:
If ((FunctionName (parameters))[-1]) {}
My particular scenario bit me when I was trying to capture a function $False return. because of my typo above, my IF statement saw it as true because of the garbage in the output, even though my last function output was "Return $False". The last output assigned from the function was the $False value due to the problem resulting from the typo causing mis-calculation. So changing my Function Return Evaluation to:
If (!((FunctionName (parameters))[-1])) {#something went wrong!}
Did the trick by allowing me to evaluate only the last element of the output array. I hope this helps others.
I ran into the same issue. In PS a function would return all output pipe information. It gets tricky to | Out-Null
rest of the code in the function.
I worked around this by passing return variable as a reference parameter [ref]
. This works consistently. Check the sample code below.
Note: some of the syntax is important to avoid errors. e.g. parameter has to be passed in brackets ([ref]$result)
function DoSomethingWithFile( [ref]$result, [string]$file )
{
# Other code writing to output
# ....
# Initialize result
if (Test-Path $file){
$result.value = $true
} else {
$result.value = $false
}
}
$result = $null
DoSomethingWithFile ([ref]$result) "C:\test.txt"
Pipe output to Out-Null
, redirect output to $null
, or prefix the function calls with [void]
:
$myArray.Add("Hello") | Out-Null
or
$myArray.Add("Hello") >$null
or
[void]$myArray.Add("Hello")
Just wanted to post this in case it helps. I had multiple functions I was calling. Each function returned a 0 or a 1. I used that to see if everything worked.
So basically...
function Funct1
{
# Do some things
return 1
}
$myResult += Funct1
$myResult += Funct2
$myResult += Funct3
if ($myResult -eq 3) { "All is good" }
Everything went along fine until I added a function that had some Copy-Item and such commands.
Long story short and an hour or two I'll never get back, I discovered this same issue with this darn pipeline thing. Anyway, with the help of sites like this, I found the cleanest way to assure you get your "Return" and nothing else.
$myResult += Funct1 -split " " | Select-Object -Last 1
$myResult += Funct2 -split " " | Select-Object -Last 1
$myResult += Funct3 -split " " | Select-Object -Last 1