如何在powershell后台连续ping?

How to ping continuously in the background in powershell?

这是我在 powershell 中的第一个程序,我试图从用户输入中获取然后 ping IP 地址或主机名,在桌面上创建文本文件。 但是如果用户想要添加多个 IP,我就会陷入无限循环。 这里我要的是 IP 地址。

   $dirPath = "C:\Users$env:UserName\Desktop"

 function getUserInput()
{
    $ipsArray = @()
    $response = 'y'

    while($response -ne 'n')
    {
      $choice = Read-Host '
      ======================================================================
      ======================================================================
      Please enter HOSTNAME or IP Address, enter n to stop adding'

      $ipsArray += $choice
      $response = Read-Host 'Do you want to add more? (y\n)'


    }

    ForEach($ip in $ipsArray)
    {
    createFile($ip)
    startPing($ip)
    }

}




然后我为每个 IP 地址创建文件:

function createFile($ip)
{

$textPath = "$($dirPath)$($ip).txt"

if(!(Test-Path -Path $textPath))
{

New-Item -Path $dirPath -Name "$ip.txt" -ItemType "file"

}

}

现在你可以看到问题了,因为我想用 TIME 格式写入,我的 ForEach 循环有问题,当我开始 ping 时,我无法到达数组中的下一个元素,直到我停止 cmd.exe.

function startPing($ip)
{

ping.exe $ip    -t     |    foreach {"{0}  -   {1}"    -f (Get-Date),      $_

} >> $dirPath$ip.txt

}

也许我应该为每个 IP 地址创建其他文件并传递参数?

看看 PowerShell Jobs。请注意,有更好更快的替代方法(如线程作业、运行空间等),但对于初学者来说,这是最简单的方法。基本上,它会启动一个新的 PowerShell 进程。

一个非常简单的例子:

function startPing($ip) {
    Start-Job -ScriptBlock {
        param ($Address, $Path)
        ping.exe $Address -t | foreach {"{0}  -   {1}" -f (Get-Date), $_ } >> $Path
    } -ArgumentList $ip, $dirPath$ip.txt
}

这个简化的示例不负责停止作业。所以根据你想要的行为,你应该查一下。

此外,请注意还有 PowerShell 的等同于 ping,Test-Connection

这是我的旧脚本。您可以在 window.

中查看计算机列表
# pinger.ps1

# example:  pinger yahoo.com
# pinger c001,c002,c003
# $list = cat list.txt; pinger $list

param ($hostnames)

#$pingcmd = 'test-netconnection -port 515'
$pingcmd = 'test-connection'

$sleeptime = 1

$sawup = @{}
$sawdown = @{}

foreach ($hostname in $hostnames) { 
  $sawup[$hostname] = $false
  $sawdown[$hostname] = $false
}

#$sawup = 0
#$sawdown = 0

while ($true) {
  # if (invoke-expression "$pingcmd $($hostname)") {

  foreach ($hostname in $hostnames) {
    if (& $pingcmd -count 1 $hostname -ea 0) {
      if (! $sawup[$hostname]) {
        echo "$([console]::beep(500,300))$hostname is up $(get-date)"
        $sawup[$hostname] = $true
        $sawdown[$hostname] = $false
      }
    } else {
      if (! $sawdown[$hostname]) {
        echo "$([console]::beep(500,300))$hostname is down $(get-date)"
        $sawdown[$hostname] = $true
        $sawup[$hostname] = $false
      }
    }
  }
  
  sleep $sleeptime
}
pinger microsoft.com,yahoo.com

microsoft.com is down 11/08/2020 17:54:54
yahoo.com is up 11/08/2020 17:54:55