function test() {
    write-Host "Called by: $($MyInvocation.Line)"
}

$a = test

Which outputs

Called by:     $a = test

?

Answer from TessellatingHeckler on serverfault.com
🌐
Microsoft Learn
learn.microsoft.com › en-us › powershell › module › microsoft.powershell.utility › get-variable
Get-Variable (Microsoft.PowerShell.Utility) - PowerShell | Microsoft Learn
The Get-Variable cmdlet gets the PowerShell variables in the current console. You can retrieve just the values of the variables by specifying the ValueOnly parameter, and you can filter the variables returned by name.
🌐
Reddit
reddit.com › r/powershell › passing variables between functions
r/PowerShell on Reddit: Passing Variables Between Functions
January 5, 2020 -

Is there a way to pass variables between functions in PowerShell? I did some googling but was surprised to come up short, all of the information was pretty messy.

Is there a way I could get f2 in the below example to actually output the value of $test ?

Function f1 {
    $test = "Hello world"
}

Function f2 {
    echo $test
}

f2
Discussions

Function return value in PowerShell - Stack Overflow
PowerShell has really wacky return semantics - at least when viewed from a more traditional programming perspective. There are two main ideas to wrap your head around: ... The $a variable in the second example is left as output on the pipeline and, as mentioned, all output is returned. In fact, in the second example you could omit the return entirely and you would get the same behavior (the return would be implied as the function ... More on stackoverflow.com
🌐 stackoverflow.com
powershell - Use values from a function and pass it to another function - Stack Overflow
I have the below two functions and I want the SOURCE and TARGET of the ROBOCOPY function used within the Comparision function. Can anyone tell me how to do this please. Thanks. Write-Host "=======... More on stackoverflow.com
🌐 stackoverflow.com
how get the value from a function outside itself?
Hello, i trying to use a function for a datepicker to be able to re-use it in the same script but i cannot get back the value outside the function. I made a test and added inside the function a string “test”. When i’m outside the function, if i want get back the value, it’s emplty. More on community.spiceworks.com
🌐 community.spiceworks.com
5
4
April 18, 2019
In Powershell, how to set variable values within a function and have that value available in the parent scope? - Stack Overflow
I am trying to set the values for some variables using a function. My code is below: $BackupFile = $null $TaskSequenceID = $null $OSDComputerName = $null $capturedWimPath = $null Function Set-OsT... More on stackoverflow.com
🌐 stackoverflow.com
🌐
PowerShell Forums
forums.powershell.org › powershell help
Passing Variables To/From a Function - PowerShell Help - PowerShell Forums
July 26, 2021 - I cobbled together some things I found on teh interwebs to make sure a directory name is properly formatted for use. I am having trouble getting the corrected variable back from the function. When the script wasn’t “doing right”, I tested it by just adding the " \ " character to the variable in the function.
Top answer
1 of 3
4
function test() {
    write-Host "Called by: $($MyInvocation.Line)"
}

$a = test

Which outputs

Called by:     $a = test

?

2 of 3
1

I don't think this is possible at all, nor would it make much sense.

It's like expecting the integer 42 to know if it has been stored in the variable $answer.


Once a function returns, only its return value (if any) is stored in a variable (if an assignment is actually used). If Get-Answer returns 42 and you issue the command $answer = Get-Answer, then $answer will indeed contain 42, but no record will be kept of the fact that it was stored there by having it returned from a function; for all intents and purposes, the end results of $answer = 42 and $answer = Get-Answer are identical, if Get-Answer does indeed return 42.

Also, the assignement (if any) only happens after a function returns; the function only provides a return value (if it does); it doesn't and shouldn't care what PowerShell is going to do with this value after it returns; and its return value could very well be discarded instead of being assigned to anything. There is no direct link between $answer and Get-Answer: what PowerShell does when faced with a command like $answer = Get-Answer is:

  • Execute Get-Answer
  • Grab the return value from Get-Answer
  • Store this value in $answer

None of the players has any knowledge of this link; the function doesnt know what its return value will be used for, and the variable doesn't know where its assigned value comes from.

And even if some record was kept of this assignment having ever happened, it definitely wouldn't have happened yet while Get-Answer was still being executed.

Top answer
1 of 10
358

PowerShell has really wacky return semantics - at least when viewed from a more traditional programming perspective. There are two main ideas to wrap your head around:

  • All output is captured, and returned
  • The return keyword really just indicates a logical exit point

Thus, the following two script blocks will do effectively the exact same thing:

$a = "Hello, World"
return $a

 

$a = "Hello, World"
$a
return

The $a variable in the second example is left as output on the pipeline and, as mentioned, all output is returned. In fact, in the second example you could omit the return entirely and you would get the same behavior (the return would be implied as the function naturally completes and exits).

Without more of your function definition I can't say why you are getting a PSMethod object. My guess is that you probably have something a few lines up that is not being captured and is being placed on the output pipeline.

It is also worth noting that you probably don't need those semicolons - unless you are nesting multiple expressions on a single line.

You can read more about the return semantics on the about_Return page on TechNet, or by invoking the help return command from PowerShell itself.

2 of 10
77

This part of PowerShell is probably the most stupid aspect. Any extraneous output generated during a function will pollute the result. Sometimes there isn't any output, and then under some conditions there is some other unplanned output, in addition to your planned return value.

So, I remove the assignment from the original function call, so the output ends up on the screen, and then step through until something I didn't plan for pops out in the debugger window (using the PowerShell ISE).

Even things like reserving variables in outer scopes cause output, like [boolean]$isEnabled which will annoyingly spit a False out unless you make it [boolean]$isEnabled = $false.

Another good one is $someCollection.Add("thing") which spits out the new collection count.

🌐
The Lonely Administrator
jdhitsolutions.com › powershell › get my variables
Get My Variables • The Lonely Administrator
March 2, 2011 - The function works by launching a separate PowerShell console session without any profiles to capture all variables. This should be all the variables defined by PowerShell. All I want is an array of the variable names. [cc lang="PowerShell"] $psvariables=powershell -noprofile -COMMAND "& {GET-VARIABLE | select -expandproperty name}" [/cc] Then all I have to do is get variables from the specified scope and filter out those that aren't from PowerShell as well as those defined in the Get-MyVariable function.
Top answer
1 of 3
13

Variables in powershell are context sensitive. If I define a function like:

$bar = "Hi"
function foo {
   $bar = "Hey!"
}
$bar <-- returns "Hi"

Then the $bar variable is not available to me outside that function. To make variables available outside of functions then you can control the scope of a function. If I set a variable in a function using the script or global prefix then the variable will be available for the whole script or globally in powershell runspace. See here:

function foo {
   $script:fooVar = "world"
}

function bar {
   foo
   $global:barVar = "Hello " + $fooVar
}

The variable $fooVar in the foo function will be available to all other functions within the script due to the scope prefix script of the variable $fooVar. The barVar function will be available globally in the runspace. I.e. when your script has finished the variable is still present back at the command line and even to other scripts.

As you can see in the bar function I first call foo and then use the foovVar variable. When I use the $fooVar variable I don't have to specify the $script:fooVar, I can if I want to but it's not necessary.

These are all valid variable assignments:

script:bbb = 123
$global:ccc = 123 

So in your case use $script:source and $script:target or $global:source and $global:target. For more info run the following command:

Help About_Scope
2 of 3
1

the hackish way is to add this to the top:

$Gobal:source = ""
$Gobal:target = ""

and search and replace $source with $Gobal:source and $target with $Gobal:target - then you can use these new global variables at any point in the script.

As suggested you could protect them in another function but for a simple job\automated task that might be overkill. Depends what it's for.

🌐
Microsoft
devblogs.microsoft.com › dev blogs › scripting blog [archived] › hey, scripting guy! how do i get data out of a function?
Hey, Scripting Guy! How Do I Get Data Out of a Function? - Scripting Blog [archived]
July 8, 2009 - Hey, Scripting Guy! I have been having problems with trying to understand functions in Windows PowerShell. I get that you use the Function keyword to create the function, but I do not know how to get information from the function back to the script. I have been able to make the functions work by using […]
Find elsewhere
🌐
4sysops
4sysops.com › home › blog › popular › the powershell function – parameters, data types, return values
The PowerShell function – Parameters, data types, return values
July 28, 2023 - This means that any output produced in the function will be stored in the variable together with the return parameter. function rTest{ $a = 5 $b = "This is a test." $a return $b } If you call the function rTest with the command $r = rTest, the values of $a and $b would be stored in the array as separate elements. Thus, you don’t have to use return to return values from a PowerShell function.
🌐
PDQ
pdq.com › powershell › get-variable
Get-Variable - PowerShell Command | PDQ
The Get-Variable cmdlet gets the Windows PowerShell variables in the current console. You can retrieve just the values of the variables by specifying the ValueOnly parameter, and you can filter the variables returned by name. ... Specifies an array of items that this cmdlet excludes from the ...
🌐
Spiceworks
community.spiceworks.com › programming & development
how get the value from a function outside itself? - Programming & Development - Spiceworks Community
April 18, 2019 - Hello, i trying to use a function for a datepicker to be able to re-use it in the same script but i cannot get back the value outside the function. I made a test and added inside the function a string “test”. When i’m outside the function, if i want get back the value, it’s emplty.
🌐
Varonis
varonis.com › blog › powershell-variable-scope
PowerShell Variable Scope Guide: Using Scope in Scripts and Modules
October 13, 2022 - After calling the Set-GreetingName function, the Get-Greeting now displays a different value based on the name I passed. This behavior is expected as both functions are now referencing the same variable. While the example module is simple, you can see how this can be useful. I use this functionality to set API credentials that multiple functions use in modules I write. Check out an example in my twilio-powershell-module GitHub repository.
🌐
Netwrix
netwrix.com › en › resources › blog › powershell-variables-and-arrays
How to Use PowerShell Variables
August 26, 2025 - Public variables are accessible from any scope. You can list all current variables in a PowerShell session by using the Get-Variable cmdlet, which retrieves all variables in the current scope.
Top answer
1 of 3
24

The variables are created in your function's local-scope. Those variables are deleted when your function is done.

Global: 
    The scope that is in effect when Windows PowerShell
    starts. Variables and functions that are present when
    Windows PowerShell starts have been created in the
    global scope. This includes automatic variables and
    preference variables. This also includes the variables, aliases,
    and functions that are in your Windows PowerShell
    profiles.

Local:  
    The current scope. The local scope can be the global 
    scope or any other scope. 

Script: 
    The scope that is created while a script file runs. Only
    the commands in the script run in the script scope. To
    the commands in a script, the script scope is the local
    scope.

Source: about_Scopes

If you need the variables to be available for the script, then write them to the script scope.

$BackupFile = $null
$TaskSequenceID = $null
$OSDComputerName = $null
$capturedWimPath = $null

Function Set-OsToBuild 
{
  switch ($OsToBuild)
  {
    "Win7x64"
        { 
            $script:BackupFile = "Win7x64-SP1.wim"
            $script:TaskSequenceID = "WIN7X64BC"
            $script:OSDComputerName = "Ref-Win7x64"
            $script:capturedWimPath = "$($PathToMdtShare)\Captures\$BackupFile"
        }
  }
}

If you would like to keep the values for whole sessions (until you close the powershell-process), then you should use the global scope.

$global:BackupFile = $null
$global:TaskSequenceID = $null
$global:OSDComputerName = $null
$global:capturedWimPath = $null

Function Set-OsToBuild 
{
  switch ($OsToBuild)
  {
    "Win7x64"
        { 
            $global:BackupFile = "Win7x64-SP1.wim"
            $global:TaskSequenceID = "WIN7X64BC"
            $global:OSDComputerName = "Ref-Win7x64"
            $global:capturedWimPath = "$($PathToMdtShare)\Captures\$BackupFile"
        }
  }
}
2 of 3
7

The powershell about_scope help document is what you want to read for this.

Specifically this section:

Windows PowerShell Scopes

Scopes in Windows PowerShell have both names and numbers. The named
scopes specify an absolute scope. The numbers are relative and reflect
the relationship between scopes.


Global: 
    The scope that is in effect when Windows PowerShell
    starts. Variables and functions that are present when
    Windows PowerShell starts have been created in the
    global scope. This includes automatic variables and
    preference variables. This also includes the variables, aliases,
    and functions that are in your Windows PowerShell
    profiles. 

Local:  
    The current scope. The local scope can be the global 
    scope or any other scope. 

Script: 
    The scope that is created while a script file runs. Only
    the commands in the script run in the script scope. To
    the commands in a script, the script scope is the local
    scope.

Private:
    Items in private scope cannot be seen outside of the current
    scope. You can use private scope to create a private version
    of an item with the same name in another scope.        


Numbered Scopes:
    You can refer to scopes by name or by a number that
    describes the relative position of one scope to another.
    Scope 0 represents the current, or local, scope. Scope 1
    indicates the immediate parent scope. Scope 2 indicates the
    parent of the parent scope, and so on. Numbered scopes
    are useful if you have created many recursive
    scopes.

So depending on your exact needs you could use any one of the following I believe.

  1. $global:BackupFile = "Win7x64-SP1.wim"
  2. $script:BackupFile = "Win7x64-SP1.wim"
  3. $1:BackupFile = "Win7x64-SP1.wim"
🌐
4sysops
4sysops.com › home › blog › articles › display and search all variables of a powershell script with get-variable
Display and search all variables of a PowerShell script with Get-Variable – 4sysops
July 28, 2023 - With the following command, you can search for a certain term in all variables: Get-Variable | Select Name,Value | Select-String "search term" ... The result is an array because Get-Variable produces an array of variable objects.
🌐
Reddit
reddit.com › r/powershell › how do you pass variables from one function to another within a module?
r/PowerShell on Reddit: How do you pass variables from one function to another within a module?
March 23, 2016 -

I created a PowerShell module to make RESTful API calls to an application. For simplicity, let's say that this module has three functions:

  • Function getProperty($name)

  • Function createProperty($name, $value, $description)

  • Function updateProperty($name, $value, $description)

Whenever createProperty or updateProperty functions are called, those functions in their current form will call getProperty before and after execution. I basically want to verify a property exists before attempting to update or verify it doesn't exist before attempting to create a new one. In order to do that, I've created a boolean variable in the script scope, so it would do something like this:

  1. Call createProperty

  2. createProperty calls getProperty and sets $Exist to $true or $false, depending on whether the property is found.

  3. createProperty checks value of $Exist

  4. createProperty creates if $Exists -eq $false, else error out and log it

All that stuff outlined above works great when using just the script. Inside the module, I cannot get the boolean variable to pass from function to function. How do I do that in the module? Am I missing a fundamental best practice here?

I wanted to share my code, but don't want to go through the hassle of sanitizing it just now, but will do it if it becomes necessary. Thanks in advance for any insight.

Top answer
1 of 2
7

Mathias R. Jessen's helpful answer explains why the originating variable cannot be reliably determined if you only pass its value.

The only robust solution to your problem is to pass a variable object rather than its value as an argument:

function Set-ToReadOnly {
  param([psvariable] $inputVar) # note the parameter type
  $inputVar.Options += 'ReadOnly'
}

$testVar = 'foo'
Set-ToReadOnly (Get-Variable testVar) # pass the variable *object*

If your function is defined in the same scope as the calling code - which is not true if you the function is defined in a (different) module - you can more simply pass just the variable name and retrieve the variable from the parent / an ancestral scope:

# Works ONLY when called from the SAME SCOPE / MODULE
function Set-ToReadOnly {
  param([string] $inputVarName)
  # Retrieve the variable object via Get-Variable.
  # This will implicitly look up the chain of ancestral scopes until
  # a variable by that name is found.
  $inputVar = Get-Variable $inputVarName
  $inputVar.Options += 'ReadOnly'
}

$testVar = 'foo'
Set-ToReadOnly testVar # pass the variable *name*
2 of 2
3

As noted in this answer to a similar question, what you're asking (resolving the identity of a variable based on its value) can not be done reliably:

The simple reason being that contextual information about a variable being referenced as a parameter argument will have been stripped away by the time you can actually inspect the parameter value inside the function.

Long before the function is actually called, the parser will have evaluated the value of every single parameter argument, and (optionally) coerced the type of said value to whatever type is expected by the parameter it's bound to.

So the thing that is ultimately passed as an argument to the function is not the variable $myVariable, but the (potentially coerced) value of $myVariable.

What you could do for reference types is simply go through all variables in the calling scope and check if they have the same value:

function Set-ReadOnlyVariable {
  param(
    [Parameter(Mandatory=$true)]
    [ValidateScript({ -not $_.GetType().IsValueType })]
    $value
  )

  foreach($variable in Get-Variable -Scope 1 |Where-Object {$_.Value -ne $null -and $_.Value.Equals($value)}){
    $variable.Options = $variable.Options -bor [System.Management.Automation.ScopedItemOptions]::ReadOnly
  }
}

But this will set every single variable in the callers scope with that value to readonly, not just the variable you referenced, and I'd strongly recommend against this kind of thing - you're most likely doing something horribly wrong if you need to do this

🌐
TechTarget
techtarget.com › searchwindowsserver › tutorial › Cut-coding-corners-with-return-values-in-PowerShell-functions
Cut coding corners with return values in PowerShell functions | TechTarget
March 29, 2021 - The easiest way to return a value from a PowerShell function is to simply output the value. The following example looks for the File Explorer process. Instead of typing the whole Where-Object expression, you can shorten it with a function: Function ...
🌐
SPGuides
spguides.com › powershell-global-variable
How to Use PowerShell Global Variables?
March 26, 2025 - Global Scope: Variables defined ... scripts, functions, or cmdlets within the current PowerShell session. To create a global variable in PowerShell, simply prefix the variable name with $global:. Here’s an example: ... Now, the $userCount variable is accessible from anywhere within ...