Agar123
Agar123

Reputation: 85

How to ping continuously in the background in powershell?

This is my first program in powershell, Im trying to get from the user input and then pinging the IP address or the hostname, Creating text file on the desktop. But if the user wants the add more than one IP I get into infinite loop. Here Im asking for IP address.

   $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)
    }

}




Then I creating the file for each IP address:

function createFile($ip)
{

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

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

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

}

}

And now you can see the problem, Because I want the write with TIME format, I have problem with the ForEach loop, When I start to ping, And I cant reach the next element in the array until I stop the cmd.exe.

function startPing($ip)
{

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

} >> $dirPath\$ip.txt

}

Maybe I should create other files ForEach IP address and pass params?

Upvotes: 1

Views: 2681

Answers (2)

js2010
js2010

Reputation: 27473

Here's a old script I have. You can watch a list of computers in a 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

Upvotes: 3

marsze
marsze

Reputation: 17064

Have a look at PowerShell Jobs. Note that there are better and faster alternatives (like thread jobs, runspaces, etc), but for a beginner, this would be the easiest way. Basically, it starts a new PowerShell process.

A very simple example:

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
}

This simplified example does not take care of stopping the jobs. So depending on what behavior you want, you should look that up.

Also, note there there is also PowerShell's equivalent to ping, Test-Connection

Upvotes: 1

Related Questions