قالب وردپرس درنا توس
Home / Tips and Tricks / Reach in PowerShell – CloudSavvy IT

Reach in PowerShell – CloudSavvy IT



Powershell logo

In many programming languages ​​there is the concept of scope. Defined as which variables and functions are available in which context. An example is when a variable is available for every function within a PowerShell script, or only for a single defined function. PowerShell scopes include several scopes that can be used, such as global, local, or script scopes.

What are the PowerShell Scopes?

As mentioned in the introduction, there are several primary scopes. These are global, local and script and tell PowerShell which variables and functions are available in which context. When referring to ranges, you usually use range prefixes to reach variables outside the current, local range. This is easiest to understand with examples.

Global reach

Global scope means that a variable is available for all functions and commands regardless of location, such as $MyVar = $True or $Global:MyVar = $True. When starting PowerShell, all initial variables have a global scope. If there are no child scopes, global is the same as local and script scope until child scopes exist.

# This is in the Global scope
$MyVar = $True

Function Test-VariableScope {
	# When a variable is not found in the current scope, look up till it is found
	Write-Host "Global Scope: $MyVar"
	# Redefine the variable in the Local scope
	$MyVar = $False
	Write-Host "Local Scope: $MyVar"
	Write-Host "Global Scope: $($Global:MyVar)"
}

Test-VariableScope

# Since the Locally scoped variable does not exist anymore, return the Global scope
Write-Host "Global Scope: $MyVar"

Local reach

The current scope is always local and therefore also the default scope. If no range modifier is used for a variable, the range is local, such as $MyVar = $True. The local range can be difficult to understand as this range is relative to the current location and a local variable can be in different ranges at the same time.

# This is in the Local scope (and Global scope since at root of script)
$MyVar = $True
Write-Host "Local Scope: $MyVar"
Write-Host "Local Scope Explicit: $($Local:MyVar)"
Function Test-VariableScope {
	# This variable is in the Local scope relative to Test-VariableScope
	$MyVar = $False
	Write-Host "Local Scope: $MyVar"
	Write-Host "Local Scope (Explicit): $($Local:MyVar)"
}

Test-VariableScope
# This variable is back to the local scope initially defined
Write-Host "Local Scope: $MyVar"
Write-Host "Local Scope Explicit: $($Local:MyVar)"

When you dot a script, such as . my-script.ps1, add the entire output of that script to the local scope!

Script scope

Finally, the script scope is a bit more complicated. It is either the closest ancestor script file range or the global range if not executed in a script file such as $script:var = $true. Global, Script and Local Scope are the same for it $MyVar = $True variable when used in a single script, and even functions.

# This is in the Script scope including Script and Local scope
$MyVar = $True
Write-Host "Script Scope: $($Script:MyVar)"

Function Test-VariableScope {
	# This variable is in the Local scope relative to Test-VariableScope
  $MyVar = $False
  # The Script scope references the same as $MyVar variable initially defined
	Write-Host "Script Scope: $($Script:MyVar)"
}

Test-VariableScope
# This variable is back to the Script scope initially defined
Write-Host "Script Scope: $($Script:MyVar)"

Unlike dot sourcing a script that adds everything to the local scope, using the & call operator executes the script, but leaves everything in the script scope relative to the script itself.

What are the options Private, Usage, Workflow and AllScope?

In addition to the general scopes, there are several options that can change the visibility or availability of variables. So what are these different options with scopes?

The Private Scope Modifier

If you define a variable or alias as private, the variable or alias is only visible and modifiable from that context. As you can see in the example below, the private version of the

Remove-Variable TestVar
Remove-Variable TestVar2
Remove-Variable TestVar3

# Two ways to create a private variable, note that this is an Option and not a Scope (applied to a scoped variable)
New-Variable -Name 'TestVar' -Value $True -Scope 'Global' -Option 'Private'
$Private:TestVar2 = $True

Write-Host "Global Scope (TestVar): $TestVar"
Write-Host "Global Scope (TestVar2): $TestVar"

$TestVar3 = $True

Function Test-Function {
  # Since the first two variables are private they are not seen
  Write-Host "Local Scope (TestVar): $TestVar"
  Write-Host "Local Scope (TestVar2): $TestVar2"
  # TestVar3 does not exist locally so PowerShell looks up and finds a non-Private variable in Global
  Write-Host "Local Scope (TestVar3): $TestVar3"
}

Test-Function

What is the usage modifier?

This is a special variable used by the cmdlets and constructs Invoke-Command, Start-Job, Start-ThreadJob, or ForEach-Object -Parallel. This only works with Invoke-Command when running on a remote computer, such as with the ComputerName parameter.

# Normally the LocalCSVData variable will not be available to the scriptblock running on the remote computer without the Using modifier.
$LocalCSVData = Import-CSV -Path 'mydata.csv'

Invoke-Command -ComputerName 'RemoteComputer' -ScriptBlock {
	$Using:LocalCSVData | ForEach-Object {
		...do something...
	}
}

Workflow and AllScope

Although much less used, there are two additional modifiers. The Workflow modifier is used to refer to variables in a PowerShell workflow (not available in PowerShell Core / 7). The AllScope modifier makes a variable available in all scopes. This also means that if the variable is changed to a child scope, it will be reflected in the root scopes. This is a way to avoid having to prefix a variable with global when you try to reference it in child ranges.

Conclusion

Scopes are useful for limiting the visibility and availability of variables, functions, and aliases. Scopes can also be tricky when it is not clear which scope a variable is in. Hopefully this article will shed some light on how scopes are used in PowerShell and what you can do with them!


Source link