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?
PowerShell arguments may be passed by reference using the Ref keyword. By default, PowerShell arguments are passed by position. Parameter names may be used to identify parameters, bypassing position. The $args array variable may be used to access a variable length parameter list.
Parameters can be created for scripts and functions and are always enclosed in a param block defined with the param keyword, followed by opening and closing parentheses. param() Inside of that param block contains one or more parameters defined by -- at their most basic -- a single variable as shown below.
The name of the parameter is preceded by a hyphen ( - ), which signals to PowerShell that the word following the hyphen is a parameter name. The parameter name and value can be separated by a space or a colon character. Some parameters do not require or accept a parameter value.
The return keyword exits a function, script, or script block. It can be used to exit a scope at a specific point, to return a value, or to indicate that the end of the scope has been reached.
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
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.
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