120 lines
4.1 KiB
PowerShell
120 lines
4.1 KiB
PowerShell
param(
|
|
[string]$Scanner1Host = "192.168.1.13",
|
|
[int]$Scanner1Port = 2001,
|
|
[string]$Scanner2Host = "192.168.1.14",
|
|
[int]$Scanner2Port = 2001,
|
|
[int]$TimeoutMs = 5000,
|
|
[switch]$Parallel
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function Test-TcpClientConnection {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Name,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$HostName,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[int]$Port,
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
[int]$ConnectTimeoutMs
|
|
)
|
|
|
|
$client = [System.Net.Sockets.TcpClient]::new()
|
|
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
|
try {
|
|
Write-Host "[$Name] Connecting to $HostName`:$Port, TimeoutMs=$ConnectTimeoutMs ..."
|
|
$connectTask = $client.ConnectAsync($HostName, $Port)
|
|
$timeoutTask = [System.Threading.Tasks.Task]::Delay($ConnectTimeoutMs)
|
|
$completedTask = [System.Threading.Tasks.Task]::WhenAny($connectTask, $timeoutTask).GetAwaiter().GetResult()
|
|
$stopwatch.Stop()
|
|
|
|
if ($completedTask -ne $connectTask) {
|
|
return [pscustomobject]@{
|
|
Name = $Name
|
|
Target = "$HostName`:$Port"
|
|
Succeeded = $false
|
|
ElapsedMs = $stopwatch.ElapsedMilliseconds
|
|
LocalEndPoint = ""
|
|
RemoteEndPoint = ""
|
|
ErrorType = "Timeout"
|
|
ErrorMessage = "ConnectAsync did not complete within $ConnectTimeoutMs ms."
|
|
}
|
|
}
|
|
|
|
if ($connectTask.IsFaulted) {
|
|
$exception = $connectTask.Exception.GetBaseException()
|
|
return [pscustomobject]@{
|
|
Name = $Name
|
|
Target = "$HostName`:$Port"
|
|
Succeeded = $false
|
|
ElapsedMs = $stopwatch.ElapsedMilliseconds
|
|
LocalEndPoint = ""
|
|
RemoteEndPoint = ""
|
|
ErrorType = $exception.GetType().FullName
|
|
ErrorMessage = $exception.Message
|
|
}
|
|
}
|
|
|
|
return [pscustomobject]@{
|
|
Name = $Name
|
|
Target = "$HostName`:$Port"
|
|
Succeeded = $client.Connected
|
|
ElapsedMs = $stopwatch.ElapsedMilliseconds
|
|
LocalEndPoint = $client.Client.LocalEndPoint.ToString()
|
|
RemoteEndPoint = $client.Client.RemoteEndPoint.ToString()
|
|
ErrorType = ""
|
|
ErrorMessage = ""
|
|
}
|
|
}
|
|
catch {
|
|
$stopwatch.Stop()
|
|
return [pscustomobject]@{
|
|
Name = $Name
|
|
Target = "$HostName`:$Port"
|
|
Succeeded = $false
|
|
ElapsedMs = $stopwatch.ElapsedMilliseconds
|
|
LocalEndPoint = ""
|
|
RemoteEndPoint = ""
|
|
ErrorType = $_.Exception.GetType().FullName
|
|
ErrorMessage = $_.Exception.Message
|
|
}
|
|
}
|
|
finally {
|
|
$client.Dispose()
|
|
}
|
|
}
|
|
|
|
Write-Host "=== Scanner TCP Client Diagnostic ==="
|
|
Write-Host "Machine: $env:COMPUTERNAME"
|
|
Write-Host "User: $env:USERNAME"
|
|
Write-Host "Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff')"
|
|
Write-Host "Mode: $(if ($Parallel) { 'Parallel' } else { 'Sequential' })"
|
|
Write-Host ""
|
|
|
|
if ($Parallel) {
|
|
$job1 = Start-Job -ScriptBlock ${function:Test-TcpClientConnection} -ArgumentList "Scanner1", $Scanner1Host, $Scanner1Port, $TimeoutMs
|
|
$job2 = Start-Job -ScriptBlock ${function:Test-TcpClientConnection} -ArgumentList "Scanner2", $Scanner2Host, $Scanner2Port, $TimeoutMs
|
|
$results = Receive-Job -Job $job1, $job2 -Wait
|
|
Remove-Job -Job $job1, $job2
|
|
}
|
|
else {
|
|
$results = @(
|
|
Test-TcpClientConnection -Name "Scanner1" -HostName $Scanner1Host -Port $Scanner1Port -ConnectTimeoutMs $TimeoutMs
|
|
Test-TcpClientConnection -Name "Scanner2" -HostName $Scanner2Host -Port $Scanner2Port -ConnectTimeoutMs $TimeoutMs
|
|
)
|
|
}
|
|
|
|
foreach ($result in $results) {
|
|
Write-Host "--- $($result.Name) ---"
|
|
$result | Format-List
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Tip: if Sequential succeeds but Parallel times out, the device or network may reject concurrent short connections."
|
|
Write-Host "Tip: close TCP debugging tools before running this script, because some scanners allow only one client connection."
|