PowerShell Remoting $使用变量范围

use*_*425 7 powershell powershell-remoting powershell-3.0

我有文件夹c:\ test我有三个文件:"file1","file2","file3"

以下脚本:

$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 
Run Code Online (Sandbox Code Playgroud)

给出结果: 图片1

但是,如果我取消注释"$ Using:exclude",我会得到结果: 在此输入图像描述

突然排除列表开始正常工作

小智 14

$Using:exclude在Where-Object cmdlet中指定不起作用,因为它位于嵌套的scriptblock中.

在你的情况下,Using:folder作品因为它是一个直接传递给Invoke-Command scriptblock的局部变量.

但" Using:exclude传递给脚本块Where-Object,本身嵌套其内部脚本块Invoke-Command.

$Using允许将局部变量传递给只有一级深度的脚本块,而不是嵌套到任何进一步的脚本块.此行为并非特定于Where-Objectscriptblock,任何带有参数的cmdlet在脚本块内部时都会表现得像这样Invoke-Command.

不幸的是,我不认为这种行为是有记录的.

通过$Using:excludeInvoke-Command scriptblock开头取消注释,您可以有效地声明$exclude远程会话中的变量.因此,在这种情况下,$exclude成为Invoke-Command scriptblock内的局部变量,并且可以进一步传递给嵌套的Where-Object scriptblock.

这就是为什么当你$Using:excludeInvoke-Commandscriptblock 的开头取消注释时它可以工作,这是一个解决方法的行为$Using.

有关此运行的官方帮助信息:

Get-Help about_remote_variables -Full
Run Code Online (Sandbox Code Playgroud)