Reputation: 21418
Is there a programmatic way to determine the scope of a variable in Powershell? After reading the about_scopes page it states to use Get-Variable
, but in testing it seems the variable objects look the same, excepting the Name
and Value
:
# Script variable
$cool = 'nice'
Get-Variable cool | Select * # => Options : None
# Value : nice
# Name : nice
# Description :
# Visibility : Public
# Module :
# ModuleName :
# Attributes : {}
# Child variable
function Test-Function {
$dude = 'sweet'
Get-Variable dude | Select-Object *
}
Test-Function # => Options : None
# Value : sweet
# Name : dude
# Description :
# Visibility : Public
# Module :
# ModuleName :
# Attributes : {}
What I was thinking of doing was doing Get-Variable -Scope 0
(or 1
) to check if a variable is declared in the current or parent scope, or against the Global
, Local
, or Script
scopes, then finding the variable name in each scope starting with the lowest possible scope first, but I'm hoping there is a more graceful method of finding out where a variable was declared in a Powershell session.
Upvotes: 5
Views: 2061
Reputation: 156
We can not see how many scope we have straight. Main idea is that we have scope count no more then Get-PSCallStack count plus 3.
Function Get-VariableScope {
[CmdletBinding()]
param(
[Parameter( Mandatory = $True, Position = 0, HelpMessage = "Variable name." )]
[string] $VariableName,
[Parameter( Mandatory = $false, Position = 1, HelpMessage = "Variable value.", ParameterSetName = 'Variable' )]
$VariableValue,
[Parameter( Mandatory = $false, Position = 2, HelpMessage = "Scope list.", ParameterSetName = 'Scope array' )]
[switch] $ScopeArray
)
$Result = $null
$ScopeList = (0..( ( Get-PSCallStack ).count + 2 ))
$VariableScopeArray = @()
foreach ( $Scope in $ScopeList ){
try{
$Res = Get-Variable -Name $VariableName -Scope $Scope -ErrorAction 'SilentlyContinue'
if ( $Res ){
$Res | Add-Member -NotePropertyName 'Scope' -NotePropertyValue $Scope
$VariableScopeArray += $Res
}
}
Catch{ }
}
if ( $ScopeArray ){
$Result = $VariableScopeArray
}
else {
$Result = ( $VariableScopeArray | Where-Object { $_.value -eq $VariableValue } ).scope
}
return $Result
}
To see the variable $Name scope number call Get-VariableScope -VariableName 'name' -VariableValue $Name
To see all scopes variable in, call Get-VariableScope -VariableName 'name' -ScopeArray
Upvotes: 3