如何在(管道后)ForEach-Object cmdlet 中实现 if 语句?

How to implement if statement inside a (after pipeline) ForEach-Object cmdlet?

这里有人帮我写了一些代码并写了这个脚本(我原来的脚本有一些问题)。

现在我需要在这个 ForEach-Object 中实现一个 if 语句(做这样的事情 "if one of the servers is not alive Write-Host "blah blah"")而不停止所以 try/catch 不适合这里。

这是代码(我试过用它玩,但没有成功)。

$computers = "localhost"
foreach ($pc in $computers) {
    $test_netconnection = Test-NetConnection $pc -Port 1433
    Test-Connection -ComputerName $pc -Count 2 -Quiet | ForEach-Object {
        [PSCustomObject]@{
            LocalPC          = $_.PSComputerName
            'Tested-Server'  = $test_netconnection.ComputerName
            Bytes            = $_.buffersize
            Time             = $_.ResponseTime
            RemotePort       = $test_netconnection.RemotePort
            TcpTestSucceeded = $test_netconnection.TcpTestSucceeded
        }
    }
}

这是网络上计算机的正确输出

LocalPC Tested-Server Bytes Time RemotePort TcpTestSucceeded
------- ------------- ----- ---- ---------- ----------------
LEVL-01 localhost        32    0       1433            False
LEVL-01 localhost        32    0       1433            False

这是不在网络上的计算机的输出

    test-Connection : Testing connection to computer 'localh0st' failed: No such host is known
   servers\Foreach-object.ps1:9 char:5
    +     test-Connection -ComputerName $pc -Count 2 |
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ResourceUnavailable: (localh0st:String) [Test-Connection], PingException
        + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand

我需要让它显示类似 "the computer is not online" 的内容而不是红色错误,而第一个输出保持原样 - 这就是为什么我尝试实现 "IF" 循环

非常感谢您的帮助

据我所知,try/catch完全满足您的要求:

try {
    Test-Connection -Computer $pc -Count 2 -EA Stop | ForEach-Object {
        [PSCustomObject]@{
            LocalPC          = $env:COMPUTERNAME
            'Tested-Server'  = $pc
            Bytes            = $_.buffersize
            Time             = $_.ResponseTime
            RemotePort       = $test_netconnection.RemotePort
            TcpTestSucceeded = $test_netconnection.TcpTestSucceeded
        }
    }
} catch {
    "The computer $pc is not online."
}

但是,就我个人而言,我更喜欢保持可 ping 和 non-pingable 主机的输出格式相同("online" 状态有一个额外的列)。为此,使用 -ErrorAction SilentlyContinue 来抑制错误,将 Test-Connection 的结果收集到一个变量中,然后根据该变量是否为空来构建您的自定义对象。

$test_connection = Test-Connection -Computer $pc -Count 2 -EA SilentlyContinue
if ($test_connection) {
    $test_connection | ForEach-Object {
        [PSCustomObject]@{
            LocalPC          = $env:COMPUTERNAME
            'Tested-Server'  = $pc
            Online           = $true
            Bytes            = $_.buffersize
            Time             = $_.ResponseTime
            RemotePort       = $test_netconnection.RemotePort
            TcpTestSucceeded = $test_netconnection.TcpTestSucceeded
        }
    }
} else {
    [PSCustomObject]@{
        LocalPC          = $env:COMPUTERNAME
        'Tested-Server'  = $pc
        Online           = $false
        Bytes            = $null
        Time             = $null
        RemotePort       = $test_netconnection.RemotePort
        TcpTestSucceeded = $test_netconnection.TcpTestSucceeded
    }
}

作为 side-note,我不建议在原始信息可用 ($env:COMPUTERNAME、$pc`) 的情况下使用派生信息 ($_.PSComputerName$test_netconnection.ComputerName)。