function Invoke-TCPScan {
[CmdletBinding()]
param (
[string]$Subnet = "10.18.254", # /24 base
[int]$Port = 22,
[int]$Timeout = 1000
)
Clear-Host
$results = @()
$total = 254
$count = 0
$rowIndex = 3 # Output starts at line 3
# Reserve lines: 0 = Progress, 1 = blank, 2 = header
Write-Host " " # Line 0: progress (will be overwritten)
Write-Host " " # Line 1: spacing
Write-Host "Scanning $Subnet.0/24 for TCP servers on port $Port..." -ForegroundColor Cyan
function Show-Progress($percent) {
if ($Host.Name -eq "ConsoleHost") {
[Console]::SetCursorPosition(0, 0)
$msg = ("Progress: {0,3}% complete" -f $percent).PadRight([console]::WindowWidth)
Write-Host $msg -NoNewline
} else {
Write-Host ("Progress: {0,3}% complete" -f $percent)
}
}
# Main scan loop
1..254 | ForEach-Object {
$ip = "$Subnet.$_"
$count++
$percent = [math]::Round(($count / $total) * 100)
Show-Progress $percent
$client = New-Object System.Net.Sockets.TcpClient
try {
$async = $client.BeginConnect($ip, $Port, $null, $null)
$success = $async.AsyncWaitHandle.WaitOne($Timeout, $false)
if ($success -and $client.Connected) {
$client.EndConnect($async)
if ($Host.Name -eq "ConsoleHost") {
[Console]::SetCursorPosition(0, $rowIndex)
}
Write-Host "SSH server found: $ip" -ForegroundColor Green
$results += $ip
$rowIndex++
}
} catch {
# Silent error handling
} finally {
$client.Close()
}
}
# Final progress update
Show-Progress 100
# Summary below results
if ($Host.Name -eq "ConsoleHost") {
[Console]::SetCursorPosition(0, $rowIndex + 1)
}
Write-Host "`nScan complete. Found $($results.Count) TCP server(s) on port $Port." -ForegroundColor Yellow
if ($results.Count -gt 0) {
$results | ForEach-Object { Write-Host $_ }
}
}