Powershell:- Function Invocation Pass Variables By Reference

Background

Quick Refresher on Powershell.

Specifically, how to pass arguments to functions by value and by reference.

Outline

  1. Global Variables
    • Declare
      • functionName
        • [string] $global:functionName = “”;
          • Prefix variable name with $global
  2. Function
    • Get-FunctionName
      • [string]$(Get-PSCallStack)[$StackNumber].FunctionName
  3. Function
    • stringConcatByValueAndReference
      • Function Declaration
        • stringConcatByValueAndReference([string]$str1, [string]$str2, [ref]$result)
          • Input Variables str1 and str2 passed by value
          • Output Variable result passed by reference
      • Set Values
        • Global Variable
          • functionName
            • $global:functionName = Get-FunctionName;
        • Referenced Variable
          • input variables
            • accessed by value
              • $output = $FORMAT_STRING_COMPOSITION -f $str1, $str2;
          •  result
            • $result.value = $output;
    • stringConcatByReferenceIncorrect
      • Function Declaration
        • stringConcatByReferenceIncorrect([ref] $str1, [ref]$str2, [ref]$result)
          • Input Variables ( str1 and str2 ) passed by reference
          • Output Variable ( result ) passed by reference
      • Set Values
        • Global Variable
          • functionName
            • $global:functionName = Get-FunctionName;
        • Referenced Variable
          • input variables
            • accessed by value
              • $output = $FORMAT_STRING_COMPOSITION -f $str1, $str2;
          • result
            • $result.value = $output;
    • stringConcatByReferenceProper
      • Function Declaration
        • stringConcatByReferenceProper([ref]$str1, [ref]$str2, [ref]$result)
          • Input Variables ( str1 and str2 ) passed by reference
          • Output Variable ( result ) passed by reference
      • Set Values
        • Global Variable
          • functionName
            • $global:functionName = Get-FunctionName;
        • Referenced Variable
          • input variables
            • accessed by reference
              • $output = $FORMAT_STRING_COMPOSITION -f $str1.value, $str2.value;
          • result
            • $result.value = $output;

Code


[string] $str1 = "Joe";
[string] $str2 = "Smith";
[string] $result2 = "";
[string] $log = "";

<#
	Setting a global PowerShell variable from a function where the global variable name is a variable passed to the function
	https://stackoverflow.com/questions/12535419/setting-a-global-powershell-variable-from-a-function-where-the-global-variable-n
#>
[string] $global:functionName = "";

Set-Variable FORMAT_STRING_COMPOSITION -option Constant -value "{0} {1}";

Set-Variable FORMAT_OUTPUT -option Constant -value "Function:- {0}`r`n`r`n`t{1} and {2} yields {3}";

<#
	Is there a way to retrieve a PowerShell function name from within a function?

	https://stackoverflow.com/questions/3689543/is-there-a-way-to-retrieve-a-powershell-function-name-from-within-a-function
#>
function Get-FunctionName ([int]$StackNumber = 1) 
{
    return [string]$(Get-PSCallStack)[$StackNumber].FunctionName
}

<#
	functionName stringConcatByValueAndReference
	
	
		a) the input variables (str1 and str2) are passed by value
	
		b) the output variable is passed by reference
		
		c) the content of the result variable is set via the variable value property
#>
function stringConcatByValueAndReference([string]$str1, [string]$str2, [ref]$result)
{
	[string] $output ="";
	
	$global:functionName = Get-FunctionName;
	
	$output = $FORMAT_STRING_COMPOSITION -f $str1, $str2;
	
	$result.value = $output;
	
}

<#
	functionName stringConcatByReferenceIncorrect	
	
		a) all variables are passed by reference
		
		b) missed accessing the "input" variables via the value property
		
		c) the content of the result variable is accessed via the variable value property
		
#>
function stringConcatByReferenceIncorrect([ref] $str1, [ref]$str2, [ref]$result)
{
	[string] $output ="";
	
	$global:functionName = Get-FunctionName;
	
	$output = $FORMAT_STRING_COMPOSITION -f $str1, $str2;
	
	$result.value = $output;
}

<#
	functionName stringConcatByReferenceProper
	
		a) all variables are passed by reference
		b) the content of each variable is accessed via the variables value property
		
#>
function stringConcatByReferenceProper([ref]$str1, [ref]$str2, [ref]$result)
{
	[string] $output ="";
	
	$global:functionName = Get-FunctionName;
	
	$output = $FORMAT_STRING_COMPOSITION -f $str1.value, $str2.value;
	
	$result.value = $output;
	
}

Write-Output "";
Write-Output "";

<#
	Set Variables
#>
$str1 = "Joe";
$str2 = "Smith";
$result2 = "";

<#
	Invoke stringConcatByValueAndReference
#>

stringConcatByValueAndReference -str1 $str1   -str2 $str2  -result ( [ref] $result2 ) 

$log = $FORMAT_OUTPUT -f $functionName, $str1, $str2, $result2;

Write-Output $log;

Write-Output "";
Write-Output "";


<#
	Invoke stringConcatByReferenceIncorrect
#>

stringConcatByReferenceIncorrect -str1 ( [ref] $str1 )  -str2 ( [ref] $str2 )  -result ( [ref] $result2 ) 

$log = $FORMAT_OUTPUT -f $functionName, $str1, $str2, $result2;

Write-Output $log;

Write-Output "";
Write-Output "";

<#
	Invoke stringConcatByReferenceProper
#>

stringConcatByReferenceProper -str1 ( [ref] $str1 )  -str2 ( [ref] $str2 )  -result ( [ref] $result2 ) 

$log = $FORMAT_OUTPUT -f $functionName, $str1, $str2, $result2;

Write-Output $log;

Write-Output "";
Write-Output "";


<#

	Undeclared variable:- $result1
	
		fails as a avariable needs to be declared and assigned to be used as a reference argument
		
#>
<#

	stringConcatByReferenceIncorrect -str1 ( [ref] $str1 )  -str2 ( [ref] $str2 )  -result ( [ref] $result1 )

#>

Output

Output- Image

Output- Text


>powershell ./string.concat.ps1


Function:- stringConcatByValueAndReference

        Joe and Smith yields Joe Smith


Function:- stringConcatByReferenceIncorrect

        Joe and Smith yields System.Management.Automation.PSReference`1[System.String] System.Management.Automation.PSReference`1[System.String]


Function:- stringConcatByReferenceProper

        Joe and Smith yields Joe Smith



>


 

Issues

Pass a variable by reference, but not access it using the value property

Outline

If you access a variable passed by reference, without using the value property.

Code


<#
	functionName stringConcatByReferenceIncorrect	
	
		a) all variables are passed by reference
		
		b) missed accessing the "input" variables via the value property
		
		c) the content of the result variable is accessed via the variable value property
		
#>
function stringConcatByReferenceIncorrect([ref] $str1, [ref]$str2, [ref]$result)
{
	[string] $output ="";
	
	$global:functionName = Get-FunctionName;
	
	$output = $FORMAT_STRING_COMPOSITION -f $str1, $str2;
	
	$result.value = $output;
}

Output

Output – Image

Output – Textual


Function:- stringConcatByReferenceIncorrect

        Joe and Smith yields System.Management.Automation.PSReference`1[System.String] System.Management.Automation.PSReference`1[System.String]

 

Pass an undeclared variable by reference

Outline

If you attempt to pass along an undeclared variable by reference, you will get a telling error.

Code


[string] $str1 = "Joe";
[string] $str2 = "Smith";
[string] $result2 = "";
[string] $log = "";

<#
	Setting a global PowerShell variable from a function where the global variable name is a variable passed to the function
	https://stackoverflow.com/questions/12535419/setting-a-global-powershell-variable-from-a-function-where-the-global-variable-n
#>
[string] $global:functionName = "";

Set-Variable FORMAT_STRING_COMPOSITION -option Constant -value "{0} {1}";

Set-Variable FORMAT_OUTPUT -option Constant -value "Function:- {0}`r`n`r`n`t{1} and {2} yields {3}";

<#
	Is there a way to retrieve a PowerShell function name from within a function?

	https://stackoverflow.com/questions/3689543/is-there-a-way-to-retrieve-a-powershell-function-name-from-within-a-function
#>
function Get-FunctionName ([int]$StackNumber = 1) 
{
    return [string]$(Get-PSCallStack)[$StackNumber].FunctionName
}


<#
	functionName stringConcatByReferenceIncorrect	
	
		a) all variables are passed by reference
		
		b) missed accessing the "input" variables via the value property
		
		c) the content of the result variable is accessed via the variable value property
		
#>
function stringConcatByReferenceIncorrect([ref] $str1, [ref]$str2, [ref]$result)
{
	[string] $output ="";
	
	$global:functionName = Get-FunctionName;
	
	$output = $FORMAT_STRING_COMPOSITION -f $str1, $str2;
	
	$result.value = $output;
}

<#
	Set Variables
#>
$str1 = "Joe";
$str2 = "Smith";
$result2 = "";



Write-Output "";
Write-Output "";


<#
	Invoke stringConcatByReferenceIncorrect
#>

<#

	Undeclared variable:- $result1
	
		fails as a avariable needs to be declared and assigned to be used as a reference argument
		
#>

stringConcatByReferenceIncorrect -str1 ( [ref] $str1 )  -str2 ( [ref] $str2 )  -result ( [ref] $result1 )



 

Output

Output – Image

Output – Text


>powershell ./string.concat.referencePassAnUndeclaredVariable.ps1


[ref] cannot be applied to a variable that does not exist.
At C:personaldadenijiblogmicrosoftpowershelldatatypestringscenariostring.concatstring.concat.referencePassAnUndeclaredVariable.ps1:73 char:1
+ stringConcatByReferenceIncorrect -str1 ( [ref] $str1 )  -str2 ( [ref] ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (result1:VariablePath) [], RuntimeException
    + FullyQualifiedErrorId : NonExistingVariableReference


>

Explanation

The $result1 variable has yet to be declared.

 

Source Code

GitLab

  1. Powershell – Function Parameters – By Value And By Reference
    https://gitlab.com/-/snippets/2502352 ( Link )

    • Files
      • File Name #1
        • Argument passed by referenced ( variable is undeclared )
          string.concat.referencePassAnUndeclaredVariable.ps1

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s