UDP Verbindung mit PowerShell prüfen
Bei der Analyse von Netzwerkproblemen ist ein einfacher ICMP Ping nie ausreichend um zu verifizieren, ob die Verbindung zwischen zwei Geräten funktioniert. Im Normalfall wird eine TCP Verbindung zu einer Serverkomponente benötigt und PowerShell bringt mit Test-NetConnection
ein entsprechendes cmdlet mit.
Von Haus aus unterstützt Test-NetConnection
jedoch ausschließlich TCP Verbindungen und testet außerdem jedes Mal noch einen ICMP Ping.
Und was ist mit UDP?
Für die Analyse von stateless UDP Paketen gibt es kein Boardmittel, weshalb ich die folgenden zwei Funktionen geschrieben habe.
Start-UDPServer
übernimmt die Rolle des Servers und kann nur eingsetzt werden wenn der eigentliche Dienst nicht läuft.Test-NetConnectionUDP
sendet das aktuelle Datum inkl. Uhrzeit an den Server.
Start-UDPServer
Die Funktion kennt nur einen Parameter und das ist -Port
. Sobald sie gestartet wurde werden alle eingehenden UDP Pakete angenommen und zusammen mit der lokalen Uhrzeit, der gesendeten Uhrzeit sowie der Quell IP-Adresse und dem Quell Port angezeigt.
function Start-UDPServer {
[CmdletBinding()]
param (
# Parameter help description
[Parameter(Mandatory = $false)]
$Port = 10000
)
# Create a endpoint that represents the remote host from which the data was sent.
$RemoteComputer = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 0)
Write-Host "Server is waiting for connections - $($UdpObject.Client.LocalEndPoint)"
Write-Host "Stop with CRTL + C"
# Loop de Loop
do {
# Create a UDP listender on Port $Port
$UdpObject = New-Object System.Net.Sockets.UdpClient($Port)
# Return the UDP datagram that was sent by the remote host
$ReceiveBytes = $UdpObject.Receive([ref]$RemoteComputer)
# Close UDP connection
$UdpObject.Close()
# Convert received UDP datagram from Bytes to String
$ASCIIEncoding = New-Object System.Text.ASCIIEncoding
[string]$ReturnString = $ASCIIEncoding.GetString($ReceiveBytes)
# Output information
[PSCustomObject]@{
LocalDateTime = $(Get-Date -UFormat "%Y-%m-%d %T")
SourceIP = $RemoteComputer.address.ToString()
SourcePort = $RemoteComputer.Port.ToString()
Payload = $ReturnString
}
} while (1)
}
Test-NetConnectionUDP
Auf dem Client müssen mindestens der Ziel -Port
und Server -ComputerName
angegeben werden. Mittels -SourcePort
kann auch noch der absendende Port beeinflusst werden, was beim Test von Firewallregeln hilft.
function Test-NetConnectionUDP {
[CmdletBinding()]
param (
# Desit
[Parameter(Mandatory = $true)]
[int32]$Port,
# Parameter help description
[Parameter(Mandatory = $true)]
[string]$ComputerName,
# Parameter help description
[Parameter(Mandatory = $false)]
[int32]$SourcePort = 50000
)
begin {
# Create a UDP client object
$UdpObject = New-Object system.Net.Sockets.Udpclient($SourcePort)
# Define connect parameters
$UdpObject.Connect($ComputerName, $Port)
}
process {
# Convert current time string to byte array
$ASCIIEncoding = New-Object System.Text.ASCIIEncoding
$Bytes = $ASCIIEncoding.GetBytes("$(Get-Date -UFormat "%Y-%m-%d %T")")
# Send data to server
[void]$UdpObject.Send($Bytes, $Bytes.length)
}
end {
# Cleanup
$UdpObject.Close()
}
}
Known Issues
- Das erste Paket wird nicht sofort angezeigt, sondern erst mit Erhalt des zweiten Pakets.
- Der Server muss nachdem er mittels CTRL+C beendet wurde noch ein Paket beenden und die Schleife zu verlassen.
- Die genutzten Ports dürfen nicht durch eine andere Applikation genutzt werden.
Update 11.02.2021: Start-TCPServer
Während der aktuellen Hamburg PowerShell User Group haben wir einen TCP Listener gebaut der vom nativen Test-NetConnection
angesprochen werden kann.
function Start-TCPServer {
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
$Port = 10000
)
do {
# Create a TCP listender on Port $Port
$TcpObject = New-Object System.Net.Sockets.TcpListener($port)
# Start TCP listener
$ReceiveBytes = $TcpObject.Start()
# Accept TCP client connection
$ReceiveBytes = $TcpObject.AcceptTcpClient()
# Stop TCP Client listener
$TcpObject.Stop()
# Output information about remote client
$ReceiveBytes.Client.RemoteEndPoint
} while (1)
}