title: Use PowerShell jobs to ping many from many with log
date: 2016-02-06 14:14:00 +0200 +0200
draft: false
author: John

Once in a while you want to check how stable a connection is between computers. You might want to ping one or two machines from several others to find out if there is some issues with the network somewhere. You could use the built-in cmdlet Test-Connection and log the results to a log file but then you will not be able to log timeouts since the cmdlet returns an error when timeouts occur. A few lines of code is all you need to get around that.

Use PowerShell jobs for ping

I wrote a small script for this which can come in handy. You can use this script to ping several machines from multiple machines and store the results to logfiles in csv format. If a ping gets a timeout then the response time will be set to 9999.

$sources = 'server1', 'server2', 'server3'
$targets = 'server4', 'server5'
$logpath = 'C:\Ping_logs\'
$pingscript = { 
    while ($true) {
        $pingdate = Get-Date -Format u
        $logpath = "$($args[2])$($args[0])_$($args[1])_$(Get-Date -f yyyy-MM-dd).log"
        Try {
            Test-Connection -Count 1 -ErrorAction Stop -Source $($args[0]) -ComputerName $($args[1]) `
                | Select-Object {$pingdate}, __SERVER, Address, ResponseTime `
                | ConvertTo-Csv `
                | Select-Object -Skip 2 `
                | Out-File -FilePath $logpath -Append
        } catch {
            $responseprops = [ordered]@{
                'datetime' = $pingdate
                '__SERVER' = $args[0]
                'Address' = $args[1]
                'ResponseTime' = '9999'
            $response  = New-Object psobject -Property $responseprops
            ConvertTo-Csv -InputObject $response `
                | Select-Object -Skip 2 `
                | Out-File -FilePath $logpath -Append
        Start-Sleep -Seconds 1
foreach ($source in $sources){
    foreach ($target in $targets){
        Start-Job -Name "$source ping $target" `
                  -ScriptBlock $pingscript `
                  -ArgumentList $source, $target, $logpath

There will be one logfile for each source-target combination. In the example above there will be six logfiles per day. The script creates powershell jobs which runs in the background as long as the session is active or until you stop the jobs. You can easily stop and remove the jobs with the following command line:

Get-Job | Stop-Job -PassThru | Remove-Job

Store log files in database

If you want the jobs to run for a long time (I had this running for a couple if weeks at one point) you will end up with a large amount of data. In this case its really helpful to put all the results into a database, whuch you can do with Write-ObjectToSQL which I have written about in the past. This is how you can import the csv files into a database.

$csv = Import-Csv -Path C:\Ping_logs\Server1_Server2_2016-02-06.log
Write-ObjectToSQL $csv -Server localhost -Database PingDB -TableName PingLog