I was informed in a comment on another post that:
As for Invoke-Command
: unfortunately, the docs are incorrect: by
default, local invocation happens in a child scope, but you can opt
into same-scope execution with -NoNewScope
. – mklement0
However, according to the help documentation(emphasis added):
You can also use Invoke-Command on a local computer to evaluate or run
a string in a script block as a command. Windows PowerShell converts
the script block to a command and runs the command immediately in the
current scope, instead of just echoing the string at the command line.
This appears to work as expected:
PS C:\> $TestVar = 99
PS C:\> Invoke-Command { Get-Variable TestVar }
Name Value
---- -----
TestVar 99
If the documentation was wrong, I would expect that to cause the variable to be unavailable to the Invoke-Command
. Is the documentation correct after all?
The documentation gives mixed information and the quoted section in the question is definitely outdated/incorrect.
The section of help that gives the correct info is under -NoNewScope
which states:
Indicates that this cmdlet runs the specified command in the current
scope. By default, Invoke-Command runs commands in their own scope.
This parameter is valid only in commands that are run in the current
session, that is, commands that omit both the ComputerName and Session
parameters.
This parameter was introduced in Windows PowerShell 3.0.
The following shows the scope information from -NoNewScope
is correct(demonstrated with numbered scopes):
$TestVar = 99
Invoke-Command { Get-Variable TestVar -Scope 0 } #Scope 0, current scope
Invoke-Command { Get-Variable TestVar -Scope 1 } #Scope 1, parent scope
Invoke-Command { Get-Variable TestVar -Scope 0 } -NoNewScope #Scope 0, current scope
Results from the first command will return an error saying the variable can't be found:
PS C:\> Invoke-Command { Get-Variable TestVar -Scope 0 } #Scope 0, current scope
Get-Variable : Cannot find a variable with the name 'TestVar'.
The other commands will return the variable information as expected. However, as mentioned in the comment on the other post, -NoNewScope
has to be used to explicitly tell Invoke-Command
to use the current scope or else it will run in a child scope by default.
The only reason the command in the question worked is because variables are available to child scopes by default and no scope needed to be declared since neither the -ComputerName
or -Session
parameter were used.