In Powershell, how to set variable values within a function and have that value available in the parent scope?

49,642

Solution 1

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"
        }
  }
}

Solution 2

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"
Share:
49,642
Dbloom
Author by

Dbloom

By day I do Windows programming in the government sector. At night I play videogames and work on house projects.

Updated on July 12, 2022

Comments

  • Dbloom
    Dbloom almost 2 years

    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-OsToBuild 
    {
      switch ($OsToBuild)
      {
        "Win7x64"
            { 
                $BackupFile = "Win7x64-SP1.wim"
                $TaskSequenceID = "WIN7X64BC"
                $OSDComputerName = "Ref-Win7x64"
                $capturedWimPath = "$($PathToMdtShare)\Captures\$BackupFile"
            }
      }
    }
    

    The problem is that these values for $BackupFile, $TaskSequenceID, $OSDComputerName and $capturedWimPath are blank/null outside of this function.

    What is the proper way to do this? I want to set these values within this function and have those values available later on in the script, in the parent scope.