Return object from PowerShell using a parameter ("By Reference" parameter)?

21.9k views Asked by At

I have one PowerShell (2.0) script calling another. I want to receive back not only the main output, but an additional object that I can use separately, e.g. to display a Summary Line in a message.

Let's have Test2.ps1 as the script being called:

param([String]$SummaryLine)
$Issues = "Potentially long list of issues"
$SummaryLine = "37 issues found"
$Issues

And Test1.ps1 as the script that calls it:

$MainOutput = & ".\Test2.ps1" -SummaryLine $SummaryOutput
$MainOutput
$SummaryOutput

The output is simply:

Potentially long list of issues

Although the parameter $SummaryLine is filled in by Test2, $SummaryOutput remains undefined in Test1.

Defining $SummaryOutput before calling Test2 doesn't help; it just retains the value assigned before calling Test2.

I've tried setting up $SummaryOutput and $SummaryLine as a [ref] variables (as one can apparently do with functions), but the $SummaryOutput.Value property is $null after calling Test2.

Is it possible in PowerShell to return a value in a parameter? If not, what are the workarounds? Directly assigning a parent-scoped variable in Test2?

2

There are 2 answers

6
OldFart On BEST ANSWER

Ref should work, you don't say what happened when you tried it. Here is an example:

Test.ps1:

Param ([ref]$OptionalOutput)

"Standard output"
$OptionalOutput.Value = "Optional Output"

Run it:

$x = ""
.\Test.ps1 ([ref]$x)
$x

Here is an alternative that you might like better.

Test.ps1:

Param ($OptionalOutput)

"Standard output"
if ($OptionalOutput) {
    $OptionalOutput | Add-Member NoteProperty Summary "Optional Output"
}

Run it:

$x = New-Object PSObject
.\Test.ps1 $x
$x.Summary
2
mjolinor On

Is this closer to what you want to do?

Test2.ps1

 $Issues = "Potentially long list of issues"
 $SummaryLine = "37 issues found"
 $Issues
 $SummaryLine

Test1.ps1

 $MainOutput,$SummaryOutput = & ".\Test2.ps1" 
 $MainOutput 
 $SummaryOutput

This:

 param([String]$SummaryLine)
 $Issues = "Potentially long list of issues"
 $SummaryLine = "37 issues found"
 $Issues

Is irrational. You're passing a parameter for $SummaryLine, and then immediatly replacing it with "37 issues found". That variable only exists in the scope the called script is running in. As soon as that script finishes, it's gone. If you want to use it later, you need to output it and save it to a variable in your calling script.