此代码似乎返回所有DHCP租约,而不是我要查找的特定计算机。如果我删除了 Read-Host 行,而是手动插入搜索字符串,例如:Where-Object {$_.HostName -like "*sdub*"
,那么我将与一台计算机匹配。
$HOSTNAME = Read-Host 'Input part of the computer name'
$HOSTLIST = Invoke-Command -ComputerName services02 -ArgumentList $HOSTNAME -Scriptblock {
Get-DHCPServerv4scope | Get-DHCPServerv4Lease | Where-Object {
$_.HostName -like "*$($Args[0])*"
}
}
foreach($HOSTINLIST in $HOSTLIST) {
$HOSTINLIST | Format-Table -Property HostName, IPAddress,
@{Label="Online"; Expression={Test-Connection $HOSTINLIST.IPAddress -Count 1 -Quiet}}
}
答案 0 :(得分:2)
如your own answer所示, PSv3 +使用了特殊的$using:
范围-允许合并来自调用方范围的变量值放入远程执行的脚本块-解决您的问题。如果您需要解决PowerShell v2中的问题,请参见底部。
关于为什么您基于-ArgumentList
的原始方法不起作用:
虽然传递给Invoke-Command
的脚本块 看到了通过-ArgumentList
在其立即范围内传递的内容,但通过脚本块({ ... }
) 运行的代码-即使它们在技术上在相同范围内运行,就像{{ 1}}和Where-Object
-不要不看到相同的ForEach-Object
数组,除非它被明确中继 -是 not 的选项,但脚本块已传递给cmdlet,例如$Args
和Where-Object
。
一个简化的示例(甚至不使用远程处理,这是原始问题附带的):
ForEach-Object
以上结果:
Invoke-Command {
# OK - sees 'foo', because $Args reflects what was passed via -ArgumentList
"0: $($Args[0])"
# !! Does NOT see foo', because the script block executed by ForEach-Object
# !! - even though it runs in the same scope - has its own $Args definition
# !! and given that NO arguments were passed to *it*, the $Args that it
# !! sees is *empty* (an empty array).
'bar' | ForEach-Object { "1: $($Args[0])" }
} -ArgumentList 'foo'
这表明传递给0: foo
1:
的脚本块不再具有与传递给ForEach-Object
的脚本块的顶级范围相同的$Args
值。
您可以使原始方法正常工作,如下所示(如果您坚持使用PowerShell v2,则必须这样做):
Invoke-Command
答案 1 :(得分:1)
问题由 $ using:HostName 解决,而不是通过-ArgumentList
传递变量:
$HostName = Read-Host 'Input part of the computer name'
$HostList = Invoke-Command -ComputerName services02 -Scriptblock { Get-DHCPServerv4scope | Get-DHCPServerv4Lease | Where-Object {$_.HostName -like "*$using:HostName*" } }
foreach($HostInList in $HostList) {
$HostInList | Format-Table -Property HostName, IPAddress, @{Label="Online"; Expression={Test-Connection $HostInList.IPAddress -Count 1 -Quiet}}
}