Powershell – Bound Ports Logging 2 – w/ timeline

This script improves upon the prior logging script in that it helps you map the timeline of when ports are bound.  

  • It runs the Get-NetTCP command to get a list of all bound ports.  It saves each output to a timestamped file (used for debugging, can take up a lot of space over time)
  • It keeps track of all bound ports, sorted low-high, and updates the list in a .txt file
  • It keeps track of when individual ports are added to the list above, and logs it with a timestamp in another .txt file
				
					# Tracks bound ports in multiple ways
# Runs the Get-NetTCP command and saves each output to a separate file with a timestamp.  Used for debugging, can take up a lot of space over time - un-comment line 48 if you want it enabled
# Creates a list of all currently bound ports, sorted lowest-highest
# As ports are bound, it keeps track of when each port is added to the list.  Running the script every 60 seconds allows for granularity in the tracking
# Write-Hosts stats on script run duration and the current number of unique lines in the Get-NetTCP output

# Define directory paths and base file names
$baseDir = "C:\_Logs\GetNetTCP-Logs\"
$tcpOutputBaseName = "tcp_output_"
$logOutputBaseName = "log_output"

# Function to check and create log files if they don't exist
function CheckAndCreateLogFiles {
    $logOutputFilePath = $baseDir + $logOutputBaseName + ".txt"
    $uniqueOutputFilePath = $baseDir + "unique_output.txt"

    if (-not (Test-Path $logOutputFilePath)) {
        New-Item -ItemType File -Path $logOutputFilePath -Force | Out-Null
    }

    if (-not (Test-Path $uniqueOutputFilePath)) {
        New-Item -ItemType File -Path $uniqueOutputFilePath -Force | Out-Null
    }
}

# Function to check and create base directory and subdirectories if they don't exist
function CheckAndCreateBaseDir {
    if (-not (Test-Path $baseDir)) {
        New-Item -ItemType Directory -Path $baseDir -Force | Out-Null
    }
}

# Run directory and file creation checks
CheckAndCreateBaseDir
CheckAndCreateLogFiles

# Initialize empty hash table to keep track of unique lines
$uniqueLines = @{}

while($true) {
    # Generate timestamp for current iteration and create output file paths
    $timestamp = Get-Date -Format 'yyyy-MM-dd HHmmss'
    $tcpOutputFilePath = $baseDir + $tcpOutputBaseName + $timestamp + ".txt"
    $logOutputFilePath = $baseDir + $logOutputBaseName + ".txt"

    # Get current TCP connection information and write to TCP output file
    $tcpOutput = Get-NetTCPConnection | Where-Object {$_.State -eq 'Bound'} | Sort-Object LocalPort | Out-String
    #$tcpOutput | Out-File $tcpOutputFilePath

    # Split the output into individual lines and check for uniqueness
    $lines = $tcpOutput -split '\r?\n'
    foreach ($line in $lines) {
        if (-not $uniqueLines.ContainsKey($line)) {
            # If the line is unique, add it to the hash table and write to the log output file with timestamp
            $uniqueLines[$line] = $timestamp
            #$logOutput = "${timestamp}: $line`n"
            $logOutput = "${timestamp}: $line"
            $logOutput | Out-File $logOutputFilePath -Append
        }
    }

    # Write the current unique lines to the unique output file
    $uniqueOutputFilePath = $baseDir + "unique_output.txt"
    $uniqueOutput = $uniqueLines.Keys -join "`r`n"
    $uniqueOutput | Out-File $uniqueOutputFilePath -Force
    # Does not work, not an integer line - Get-Content $uniqueOutputFilePath | Sort-Object { [int]($_ -split '\s+')[2] } | Set-Content $uniqueOutputFilePath
    #Only in PS 7.1 - Get-Content $uniqueOutputFilePath | Sort-Object -Unique -AsString | Set-Content $uniqueOutputFilePath
    Get-Content $uniqueOutputFilePath | Sort-Object { [string]$_ } -Unique | Set-Content $uniqueOutputFilePath



    Write-Host "The current time is $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
    $numUniqueLines = @(Get-Content $uniqueOutputFilePath).Count
    Write-Host "Number of unique lines: $numUniqueLines"
    
    # Wait for 1min before repeating the loop
    Start-Sleep -Seconds 60
}