PingLogger.ps1

Language: Powershell
Tags: Networking
Download Script File

Description

This script prompts the user for an IP address or domain name to ping.

It then continuously pings the target at a specified interval (defaulting to 1 second) and logs detailed ping results, including a timestamp, to a CSV file.

The CSV file is named 'PingLog_<TargetIPorDomain>_<Timestamp>.csv' and is saved in the same directory as the script.

A quick, simple and reliable way (albeit basic) of logging network connectivity.

Code

#region --- Script Configuration ---

# Default ping interval in seconds
$PingIntervalSeconds = 1

#endregion

#region --- Function Definitions ---

function Get-Timestamp {
    # Returns a formatted timestamp string for logging
    (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")
}

function Get-FileNameTimestamp {
    # Returns a formatted timestamp string suitable for file names
    (Get-Date).ToString("yyyyMMdd_HHmmss")
}

#endregion

#region --- Main Script Logic ---

Write-Host "--- PowerShell Ping Logger ---" -ForegroundColor Cyan

# 1. Request user input for the IP/domain name
$Target = Read-Host "Please enter the IP address or domain name to ping (e.g., 8.8.8.8 or google.com)"

# Validate input
if ([string]::IsNullOrWhiteSpace($Target)) {
    Write-Error "No target IP or domain provided. Exiting script."
    exit 1
}

Write-Host "`nTarget for ping: $($Target)" -ForegroundColor Green

# 2. Define the output CSV file path
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
$FileNameTimestamp = Get-FileNameTimestamp
$LogFileName = "PingLog_$($Target.Replace('.', '_').Replace(':', '_').Replace('/', '_'))_$($FileNameTimestamp).csv"
$LogFilePath = Join-Path -Path $ScriptPath -ChildPath $LogFileName

Write-Host "Log file will be saved to: $($LogFilePath)" -ForegroundColor Green
Write-Host "Press Ctrl+C to stop the logging process." -ForegroundColor Yellow
Write-Host "Starting ping logging in 3 seconds..." -ForegroundColor White
Start-Sleep -Seconds 3

# Create a custom object to define the CSV header initially
# This ensures all columns are present even if the first ping fails
$InitialHeader = [PSCustomObject]@{
    Timestamp = ""
    Address = ""
    IPV4Address = ""
    IPV6Address = ""
    Bytes = ""
    Time = ""
    TTL = ""
    Status = ""
    Source = ""
    PingSucceeded = "" # Custom field for easy filtering
    ErrorMessage = ""  # Custom field for error details
}
# Write the header to the CSV file
$InitialHeader | Export-Csv -Path $LogFilePath -NoTypeInformation -Force

# 3. Start a continuous loop for repeated pings
while ($true) {
    $CurrentTimestamp = Get-Timestamp
    Write-Host "$($CurrentTimestamp) - Pinging $($Target)..." -NoNewline

    try {
        # Perform Test-Connection
        # -Count 1: Sends a single ping request
        # -ErrorAction SilentlyContinue: Prevents errors from stopping the script, allowing custom handling
        $PingResult = Test-Connection -TargetName $Target -Count 1 -ErrorAction SilentlyContinue

        if ($PingResult) {
            # If ping was successful (or returned an object even with a failure status)
            $PingSucceeded = ($PingResult.Status -eq "Success")
            $ErrorMessage = ""

            # Select specific properties and add custom ones
            $LogEntry = [PSCustomObject]@{
                Timestamp = $CurrentTimestamp
                Address = $PingResult.Address
                IPV4Address = $PingResult.IPV4Address
                IPV6Address = $PingResult.IPV6Address
                Bytes = $PingResult.Bytes
                Time = $PingResult.Time # This is the round-trip time in milliseconds
                TTL = $PingResult.TTL
                Status = $PingResult.Status # e.g., "Success", "DestinationHostUnreachable", "TimedOut"
                Source = $PingResult.Source
                PingSucceeded = $PingSucceeded
                ErrorMessage = $ErrorMessage
            }
            Write-Host " Status: $($PingResult.Status), Time: $($PingResult.Time)ms" -ForegroundColor Green
        } else {
            # Test-Connection might return $null if the host is completely unreachable or name resolution fails
            $PingSucceeded = $false
            $ErrorMessage = "Ping command returned no results (host unreachable or name resolution failed)."
            $LogEntry = [PSCustomObject]@{
                Timestamp = $CurrentTimestamp
                Address = $Target # Log the target even if no address was resolved
                IPV4Address = ""
                IPV6Address = ""
                Bytes = ""
                Time = ""
                TTL = ""
                Status = "Failed"
                Source = ""
                PingSucceeded = $PingSucceeded
                ErrorMessage = $ErrorMessage
            }
            Write-Host " Status: Failed - No response from Test-Connection." -ForegroundColor Red
        }
    }
    catch {
        # Catch any unexpected errors during Test-Connection
        $PingSucceeded = $false
        $ErrorMessage = $_.Exception.Message
        $LogEntry = [PSCustomObject]@{
            Timestamp = $CurrentTimestamp
            Address = $Target
            IPV4Address = ""
            IPV6Address = ""
            Bytes = ""
            Time = ""
            TTL = ""
            Status = "Error"
            Source = ""
            PingSucceeded = $PingSucceeded
            ErrorMessage = $ErrorMessage
        }
        Write-Host " Status: Error - $($ErrorMessage)" -ForegroundColor Red
    }

    # Export the log entry to the CSV file
    $LogEntry | Export-Csv -Path $LogFilePath -Append -NoTypeInformation

    # Wait for the next ping
    Start-Sleep -Seconds $PingIntervalSeconds
}

#endregion