I have folder c:\test where I have three files: “file1”, “file2”, “file3”
Following script:
$remoteSession = New-PSSession -ComputerName localhost
$folder = "c:\test"
$exclude =@("c:\test\file1","c:\test\file2")
Invoke-Command -Session $remoteSession -ScriptBlock {
#$Using:exclude
Get-ChildItem -Path $Using:folder -recurse | Where {$Using:exclude -notcontains $_.FullName}
}
Remove-PSSession $remoteSession
Gives the result:
However, if I uncomment “$Using:exclude” I get the result:
Suddenly exclude list starts working properly
PowerShell scope protects variables and other artifacts by limiting where they can be read and modified. Scope levels protect items that should not be changed. PowerShell has the following scopes available: Global: This scope is available when you open a PowerShell console or create a new runspace or session.
One way to pass local variables to a remote scriptblock is to use the Invoke-Command ArgumentList parameter. This parameter allows you to pass local variables to the parameter and replace local variable references in the scriptblock with placeholders. Passing the local variables to the ArgumentList parameter is easy.
The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.
Thus, a PowerShell global variable is one that is available throughout the program and can be accessed anywhere. You can set its value in many ways and can create it with many characteristics such as a private global variable, read-only, constant, and more.
Just specifying $Using:exclude
in the Where-Object cmdlet doesn't work because it is in a nested scriptblock.
In your case , the Using:folder
works because it is a local variable directly passed to the Invoke-Command
scriptblock.
But "Using:exclude
is passed to a scriptblock for Where-Object
, which is itself nested inside the scriptblock for Invoke-Command
.
$Using
allows to pass local variables to scriptblocks only one level deep, not to scriptblocks nested any further.
This behaviour is not specific to the Where-Object
scriptblock, any cmdlet which has a parameter taking a scriptblock behaves like this when it is inside a Invoke-Command
scriptblock.
Unfortunately, I don't think this behaviour is documented.
By uncommenting $Using:exclude
at the beginning of the Invoke-Command
scriptblock, you are effectively declaring the variable $exclude
inside the remote session.
So, in this case, $exclude
becomes a local variable inside the Invoke-Command
scriptblock and can be passed one level further, to the nested Where-Object
scriptblock.
That's why it works when you uncomment $Using:exclude
at the beginning of the Invoke-Command
scriptblock, it's a workaround for the behaviour of $Using
.
For the official help information about this run :
Get-Help about_remote_variables -Full
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With