首页 > 解决方案 > Powershell Test-NetConnection 在循环脚本中返回 False

问题描述

Test-NetConnection 在手动运行时返回 TRUE,但在循环脚本中时,只有部分端口返回 TRUE。


我编写了一个 powershell 脚本,它循环通过端口号来执行 Test-NetConnection:

$machine = '[targetmachinename]'
$this_machine = $env:COMPUTERNAME
$port_arr = @(8331, 8332, 8333, 8334, 8335, 8310, 8311)

foreach ($port in $port_arr) {
    Test-NetConnection $machine.domain.name.com -port $port -InformationLevel Quiet
}

当我运行脚本时,它总是在相同的两个端口号上返回 TRUE,而在其他端口上返回 FALSE。

当我为每个端口手动运行代码时,它们对于所有端口都返回为 TRUE。

我尝试通过删除、添加和移动它们来弄乱端口号,但它总是给出相同的结果,只有相同的两个端口号返回 TRUE。

我怀疑变量、数组、foreach 循环或其他东西可能不好,但如果是这样的话,为什么即使我改变了数组,它也适用于相同的两个端口而不适用于其他端口?
我正在考虑在循环之间设置延迟或等待,但尚未对其进行测试。

从目标机器本地运行时,此脚本工作正常。从另一台机器运行脚本时出现此问题。


更新:查看 powershell 日志:

Command start time: 20191111121539
**********************
PS>TerminatingError(New-Object): "Exception calling ".ctor" with "2" argument(s): "No connection could be made because the target machine actively refused it [IPADDRESS]:[PORT]""

我注意到 IPADDRESS 与目标机器名称不匹配,而是与源机器匹配。


我将 $machine.domain.name.com 替换为机器的实际 IP 地址,这使脚本按预期工作。

为什么 $machine.domain.name.com 会解析到源机器?即使我错误地连接它,那通常不会成为未解决的地址和错误吗?那时不是所有的端口检查都失败了吗?

标签: powershell

解决方案


tl;博士

替换参数

$machine.domain.name.com

"$machine.domain.name.com"

虽然PowerShell 中不带引号的命令参数通常被视为可扩展字符串- 即,好像它们被隐式包含在 中"...",但如果您的参数以变量引用(例如$machine.

在这种情况下,PowerShell 尝试将参数评估为表达式,并且由于[string]变量$machine没有.domain属性(以及后续的嵌套属性),因此整个参数有效地计算为$null[1] - 导致本地计算机无意中被Test-NetConnection.

PowerShell 如何解析未引用的命令参数的微妙之处:

相反,要了解可扩展字符串(字符串插值)——嵌入的变量引用和表达式"..."——如何在 PowerShell 中工作,


此外,BACON观察到以下关于 with 的-InformationLevel Quiet使用
Test-NetConnection

我认为-InformationLevel Quiet在这种情况下,通过正在积极地损害调试。给定$machine = 'foo',比较以下的输出(尤其是ComputerName属性):
Test-NetConnection $machine.domain.name.com -InformationLevel Quiet
vs.
Test-NetConnection $machine.domain.name.com
vs.
Test-NetConnection "$machine.domain.name.com"

换句话说,[最好] 确保 cmdlet(及其参数)在传递“我不关心所有这些信息。只要告诉我它是通过还是失败”的参数之前的行为符合预期。


[1]为默认$null有效结果或如果有效;或更高,你实际上会得到一个错误Set-StrictMode -Version 1Set-StrictMode -Version 2


推荐阅读