Public/network/Start-NetworkStatisticMonitor.ps1
|
#Requires -Version 5.1 function Start-NetworkStatisticMonitor { <# .SYNOPSIS Monitors network connections in real time with auto-refresh display .DESCRIPTION Provides a live, auto-refreshing console view of TCP and UDP network connections. Internally calls Get-NetworkConnection at each refresh interval and displays the results in a formatted table using Write-Host. Output goes to the console only, not the pipeline, to support the interactive monitoring experience. Press Ctrl+C to stop the monitor. All filtering parameters from Get-NetworkConnection are available (Protocol, State, LocalPort, etc.). .PARAMETER ComputerName One or more computer names to monitor. Accepts pipeline input by value and by property name. Defaults to the local machine ($env:COMPUTERNAME). .PARAMETER Credential Optional PSCredential for authenticating to remote machines via WinRM. Ignored for local machine queries. .PARAMETER Protocol Filter by protocol. Valid values: TCP, UDP. By default both are shown. .PARAMETER State Filter TCP connections by state (e.g. Established, Listen, TimeWait). Ignored for UDP endpoints (UDP is stateless). .PARAMETER LocalAddress Filter by local IP address. Supports wildcards. .PARAMETER LocalPort Filter by local port number. .PARAMETER RemoteAddress Filter by remote IP address. Supports wildcards. .PARAMETER RemotePort Filter by remote port number. .PARAMETER ProcessName Filter by owning process name. Supports wildcards. .PARAMETER RefreshInterval Refresh interval in seconds. Default: 2. Valid range: 1-300 seconds. .PARAMETER NoClear Suppresses the initial Clear-Host call. Useful when embedding the monitor output in a transcript, ISE, or non-interactive host where clearing the console is undesirable. .EXAMPLE Start-NetworkStatisticMonitor Starts real-time monitoring of all network connections on the local machine, refreshing every 2 seconds. Press Ctrl+C to stop. .EXAMPLE Start-NetworkStatisticMonitor -Protocol TCP -State Established -RefreshInterval 5 Monitors only established TCP connections with a 5-second refresh interval. .EXAMPLE Start-NetworkStatisticMonitor -ComputerName 'SRV01', 'SRV02' -Protocol TCP Monitors TCP connections on two remote servers in real time. .OUTPUTS None This function writes directly to the host for interactive display. It does not produce pipeline output. .NOTES Author: Franck SALLET Version: 1.3.0 Last Modified: 2026-04-02 Requires: PowerShell 5.1+ / Windows only Permissions: No admin required for basic queries Remote: Requires WinRM / WS-Man enabled on target machines .LINK https://github.com/k9fr4n/PSWinOps .LINK https://learn.microsoft.com/en-us/powershell/module/nettcpip/get-nettcpconnection #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is intentional for interactive console monitoring display')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'This function is read-only (monitoring); it does not modify system state')] [CmdletBinding()] [OutputType([void])] param( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Alias('CN', 'Name', 'DNSHostName')] [string[]]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [PSCredential]$Credential, [Parameter(Mandatory = $false)] [ValidateSet('TCP', 'UDP')] [string[]]$Protocol = @('TCP', 'UDP'), [Parameter(Mandatory = $false)] [ValidateSet('Bound', 'Closed', 'CloseWait', 'Closing', 'DeleteTCB', 'Established', 'FinWait1', 'FinWait2', 'LastAck', 'Listen', 'SynReceived', 'SynSent', 'TimeWait')] [string[]]$State, [Parameter(Mandatory = $false)] [SupportsWildcards()] [string]$LocalAddress, [Parameter(Mandatory = $false)] [ValidateRange(1, 65535)] [int]$LocalPort, [Parameter(Mandatory = $false)] [SupportsWildcards()] [string]$RemoteAddress, [Parameter(Mandatory = $false)] [ValidateRange(1, 65535)] [int]$RemotePort, [Parameter(Mandatory = $false)] [SupportsWildcards()] [string]$ProcessName, [Parameter(Mandatory = $false)] [ValidateRange(1, 300)] [int]$RefreshInterval = 2, [Parameter(Mandatory = $false)] [switch]$NoClear ) begin { Write-Verbose "[$($MyInvocation.MyCommand)] Starting network statistics monitor" # Collect all computer names from pipeline before starting the loop $allComputers = [System.Collections.Generic.List[string]]::new() # Build the splat for Get-NetworkConnection (all filter params except ComputerName) $getStatParams = @{} if ($PSBoundParameters.ContainsKey('Credential')) { $getStatParams['Credential'] = $Credential } if ($PSBoundParameters.ContainsKey('Protocol')) { $getStatParams['Protocol'] = $Protocol } if ($PSBoundParameters.ContainsKey('State')) { $getStatParams['State'] = $State } if ($PSBoundParameters.ContainsKey('LocalAddress')) { $getStatParams['LocalAddress'] = $LocalAddress } if ($PSBoundParameters.ContainsKey('LocalPort')) { $getStatParams['LocalPort'] = $LocalPort } if ($PSBoundParameters.ContainsKey('RemoteAddress')) { $getStatParams['RemoteAddress'] = $RemoteAddress } if ($PSBoundParameters.ContainsKey('RemotePort')) { $getStatParams['RemotePort'] = $RemotePort } if ($PSBoundParameters.ContainsKey('ProcessName')) { $getStatParams['ProcessName'] = $ProcessName } } process { foreach ($computer in $ComputerName) { $allComputers.Add($computer) } } end { $computerList = $allComputers -join ', ' Write-Host "Network Statistics Monitor - Refresh every ${RefreshInterval}s - Press Ctrl+C to stop" -ForegroundColor Cyan $isFirstRender = $true $previousLineCount = 0 try { while ($true) { $allResults = @(Get-NetworkConnection -ComputerName $allComputers.ToArray() @getStatParams -ErrorAction SilentlyContinue) # Use cursor repositioning to avoid flicker (Clear-Host on first render only) if ($isFirstRender) { if (-not $NoClear) { Clear-Host } $isFirstRender = $false } else { try { [Console]::SetCursorPosition(0, 0) } catch { Clear-Host } } $now = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' Write-Host "=== Network Statistics on $computerList - $now - ${RefreshInterval}s refresh - Ctrl+C to stop ===" -ForegroundColor Cyan Write-Host "Total connections: $($allResults.Count)" -ForegroundColor DarkGray Write-Host '' if ($allResults.Count -gt 0) { $tableOutput = $allResults | Sort-Object ComputerName, ProcessName, Protocol, RemoteAddress | Format-Table -AutoSize | Out-String Write-Host $tableOutput -NoNewline $currentLineCount = ($tableOutput -split "`n").Count + 3 } else { Write-Host '(No matching connections found)' -ForegroundColor Yellow $currentLineCount = 4 } # Clear stale lines from previous render when content shrinks if ($currentLineCount -lt $previousLineCount) { $padWidth = try { [Console]::WindowWidth } catch { 120 } $blankLine = ' ' * $padWidth for ($i = $currentLineCount; $i -lt $previousLineCount; $i++) { Write-Host $blankLine } } $previousLineCount = $currentLineCount Start-Sleep -Seconds $RefreshInterval } } catch { Write-Verbose "[$($MyInvocation.MyCommand)] Monitoring interrupted: $_" } finally { Write-Host '' Write-Host 'Network Statistics Monitor stopped.' -ForegroundColor Cyan } } } |