# IP123 local TCP report. Windows PowerShell 5.1 / PowerShell 7. # Only IPv4/IPv6 loopback, no application data, no elevation or policy changes. # Results do not establish public exposure or identify running software. # Embedded ports are checked against port-catalog.json by repository tests. [CmdletBinding()] param([string]$OutputPath = (Join-Path (Get-Location) 'ip123-local-ports.json')) $ErrorActionPreference = 'Stop' $ports = @(22, 80, 443, 445, 1080, 1433, 1521, 2375, 3000, 3306, 3389, 5432, 5900, 6379, 8000, 8080, 8081, 8443, 8888, 9000, 9090, 9200, 11211, 27017) $targets = @('127.0.0.1', '::1') $worker = { param([string]$Target, [int]$Port) $watch = [System.Diagnostics.Stopwatch]::StartNew() $client = $null $status = 'connected' $reason = $null try { $family = [System.Net.Sockets.AddressFamily]::InterNetwork if ($Target -eq '::1') { $family = [System.Net.Sockets.AddressFamily]::InterNetworkV6 } $client = [System.Net.Sockets.TcpClient]::new($family) $task = $client.ConnectAsync([System.Net.IPAddress]::Parse($Target), $Port) if (-not $task.Wait(1500)) { $status = 'timeout'; $reason = 'deadline-exceeded' } } catch { $exception = $_.Exception while ($null -ne $exception.InnerException) { $exception = $exception.InnerException } $status = 'failed' $reason = 'socket-error' if ($exception -is [System.Net.Sockets.SocketException]) { switch ($exception.SocketErrorCode.ToString()) { 'ConnectionRefused' { $status = 'refused'; $reason = 'connection-refused' } 'TimedOut' { $status = 'timeout'; $reason = 'deadline-exceeded' } 'AddressFamilyNotSupported' { $reason = 'address-family-unavailable' } 'AddressNotAvailable' { $reason = 'address-family-unavailable' } 'AccessDenied' { $reason = 'access-denied' } 'NetworkUnreachable' { $reason = 'network-unreachable' } 'HostUnreachable' { $reason = 'network-unreachable' } } } } finally { if ($null -ne $client) { $client.Dispose() } $watch.Stop() } [pscustomobject]@{ target = $Target; port = $Port; status = $status; elapsedMs = [Math]::Round($watch.Elapsed.TotalMilliseconds, 3); reason = $reason } } $pool = [RunspaceFactory]::CreateRunspacePool(1, 4) $jobs = [System.Collections.Generic.List[object]]::new() $results = [System.Collections.Generic.List[object]]::new() try { $pool.Open() foreach ($port in $ports) { foreach ($target in $targets) { $shell = [PowerShell]::Create() $shell.RunspacePool = $pool $null = $shell.AddScript($worker.ToString()).AddArgument($target).AddArgument($port) $job = [pscustomobject]@{ shell = $shell; handle = $null } $jobs.Add($job) $job.handle = $shell.BeginInvoke() } } foreach ($job in $jobs) { $items = $job.shell.EndInvoke($job.handle) if ($job.shell.HadErrors -or $items.Count -ne 1) { throw 'Local check failed; no incomplete report was written.' } $results.Add($items[0]) } } finally { foreach ($job in $jobs) { $job.shell.Dispose() } $pool.Dispose() } $report = [ordered]@{ version = 1; collectedAt = [DateTime]::UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'"); platform = 'Windows'; results = $results.ToArray() } $json = $report | ConvertTo-Json -Depth 5 $requested = [System.IO.Path]::GetFullPath($OutputPath) $directory = [System.IO.Path]::GetDirectoryName($requested) $stem = [System.IO.Path]::GetFileNameWithoutExtension($requested) $extension = [System.IO.Path]::GetExtension($requested) $index = 0 while ($true) { $destination = $requested if ($index -gt 0) { $destination = Join-Path $directory ($stem + '-' + $index + $extension) } $stream = $null try { $stream = [System.IO.File]::Open($destination, [System.IO.FileMode]::CreateNew, [System.IO.FileAccess]::Write) } catch [System.IO.IOException] { if ([System.IO.File]::Exists($destination)) { $index++; continue } throw } try { $bytes = [System.Text.UTF8Encoding]::new($false).GetBytes($json + [Environment]::NewLine) $stream.Write($bytes, 0, $bytes.Length) } finally { $stream.Dispose() } break } Write-Output "Completed 48 local TCP checks. Import this file into IP123:" Write-Output $destination