【问题标题】:Powershell Test-NetConnection returns False in loop scriptPowershell Test-NetConnection 在循环脚本中返回 False
【发布时间】:2019-11-12 07:49:57
【问题描述】:

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


    【解决方案1】:

    tl;dr

    替换参数

    $machine.domain.name.com
    

    "$machine.domain.name.com"
    

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

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

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

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


    此外,BACON 遵守以下关于 -InformationLevel Quiet
    Test-NetConnection 的使用:

    我认为在这种情况下传递 -InformationLevel Quiet 会严重影响调试。给定$machine = 'foo',比较以下输出(尤其是ComputerName 属性):
    Test-NetConnection $machine.domain.name.com -InformationLevel Quiet

    Test-NetConnection $machine.domain.name.com

    Test-NetConnection "$machine.domain.name.com".

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


    [1] $null 是有效结果默认 或者如果Set-StrictMode -Version 1 有效;使用Set-StrictMode -Version 2 或更高版本,您实际上会得到一个错误

    【讨论】:

      【解决方案2】:

      我看到人们(包括我自己)犯的一个常见错误是您的变量名和在 powershell 中的用法。例如,我一直忘记 $。这只是循环通过我的机器作为示例,但它正确地测试了所有这些端口。

      $port_arr = @(139,3389,5040)
      $mac = @("myComputer")
      
      foreach ($mc in $mac){
          foreach ($i in $port_arr) {
              Test-NetConnection  $mc -port $i
      
          }
      }
      

      您有您的 powershell 代码示例吗?另外,您是否已逐步确定它是否按预期工作?

      【讨论】:

      • @JR87 我的循环脚本与您发布的几乎相同。我还没有逐步完成它,但我尝试了不同的输入,例如一次只做一个端口,等等。
      • 只是为了确定,因为这可能会受到代码之外的事物的影响。您是否在同一台机器上运行“成功”测试?例如,如果您有 test1、test2 和 target。如果 test1 在它和目标之间没有防火墙,那你很好。如果 test2 在它和目标之间有防火墙,你可能会失败。愚蠢,但在某些情况下可能。
      • 我已经从当前机器运行了命令,但我在从(到目标机器)运行脚本时遇到问题,并且工作正常。只是脚本很奇怪
      • 我发现了问题。解析的 IP 地址与源机器匹配,而不是目标机器。知道为什么当我将 $machine.domain.name.com 放在那里时脚本可能会解析到源机器吗?如果我错误地连接了那个变量,它不应该 ping 一个未解析的地址和错误吗?
      • 查看 mklement0 的回答。这是因为您如何构建变量/字符串。
      猜你喜欢
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 2021-09-21
      • 2017-04-17
      • 2020-08-31
      • 2016-12-20
      相关资源
      最近更新 更多