Windows TCP Connection Daten

Für die gefühlte Performance einer Anwendung mit Netzwerk-Zugriff ist neben dem Client und dem Server auch das Netzwerk eine relevante Komponente. Ob ein Server oder eine Applikation auf dem Server zu langsam ist, kann der Betreiber in der Regel ganz gut ermitteln. Neben Perfmon und CPU-Last, Disk-IOs gibt es idealerweise auch Application-Counter. Wenn ein Client langsam ist, merken die meisten Firmen das nur über mehr oder minder qualifizierte Anrufe beim Helpdesk, Beschwerden bei Meetings oder bei Kaffeeklatsch in der Kantine. Beim Netzwerk können Administratoren mit aktiven Checks parallel zum produktiven Verkehr zwar die Netzwerkauslastung messen aber was auf dem Client passiert, ist meist unsichtbar.

Ich beschreibe hier einen Zwischenstand meiner Recherche. Ich habe noch kein fertiges Skript, welches z.B. die Office 365 Verbindungen auf dem Client überwacht und die Kennzahlen z.B. an einen Reporting-Service sendet. Die Information wäre aber natürlich für jede Nutzung von Cloud-Diensten sehr interessant

Ressourcenmonitor

Interessanterweise erfasst Windows durchaus solche Daten. Über den Windows Ressourcen Monitor können Sie auf der Karteikarte "Netzwerk" im Bereich der "TCP-Verbindungen" sehr wohl alle aktiven Verbindungen sehen. Interessant sind dabei aber auch die Kennzahlen zu Latenzzeit und Paketverlusten, die hier ebenfalls pro Verbindung ermittelt werden.

Solche Daten sind natürlich wichtig um Probleme mit Servern und dem Netzwerk zu ermitteln. Insbesondere wenn die Server, wie bei Office 365, auch noch weiter entfernt stehen oder die Verbindung (WLAN, UMTS o.ä.) auch nicht zuverlässig ist. Schon ein versierter Anwender kann selbst anhand dieser Daten prüfen, ob das Problem nun bei im oder auf dem Weg zum Ziel ist. Allerdings werden hier natürlich nur TCP-Verbindungen erfasst. UDP-Übertragungen, die bei VoIP (Audio/Video) zum Einsatz kommen oder einfache ICMP-Pings bleiben unentdeckt.

Einfach mit PowerShell?

Wenn der Ressource Monitor mal so eben schnell diese Daten einfach anzeigt, dann hatte ich die Hoffnung auf eine .NET -Klasse. Da gibt es durchaus einige, die auch die aktuellen Verbindungen anzeigen. Das geht per PowerShell Commandlet mittlerweile direkt: Die Liste der aktuellen Verbindungen auf entfernte Webserver über 443 erhalten Sie mit

PS C:\> Get-NetTCPConnection -RemotePort 443

LocalAddress                        LocalPort RemoteAddress                       RemotePort State       AppliedSetting
------------                        --------- -------------                       ---------- -----       --------------
192.168.178.50                      63788     40.67.255.199                       443        Established Internet
192.168.178.50                      63774     54.230.93.82                        443        Established Internet
192.168.178.50                      63773     40.101.124.194                      443        Established Internet
192.168.178.50                      63761     40.79.65.237                        443        Established Internet
192.168.178.50                      63747     92.123.42.37                        443        Established Internet
192.168.178.50                      63746     92.123.42.37                        443        Established Internet
192.168.178.50                      63745     92.123.42.37                        443        Established Internet
192.168.178.50                      63739     13.107.21.200                       443        Established Internet
192.168.178.50                      63731     172.217.23.174                      443        Established Internet
192.168.178.50                      63717     104.20.2.47                         443        Established Internet

Leider sind pro einzelner Verbindung auch keine Details zu erkennen, da das Objekt "TypeName: Microsoft.Management.Infrastructure.CimInstance#ROOT/StandardCimv2/MSFT_NetTCPConnection" ist

PS C:\> (Get-NetTCPConnection -RemotePort 443)[0] | fl *

State                    : Established
AppliedSetting           : Internet
OffloadState             : InHost
Caption                  :
Description              :
ElementName              :
InstanceID               : 192.168.178.50++63834++52.97.151.98++443
CommunicationStatus      :
DetailedStatus           :
HealthState              :
InstallDate              :
Name                     :
OperatingStatus          :
OperationalStatus        :
PrimaryStatus            :
Status                   :
StatusDescriptions       :
AvailableRequestedStates :
EnabledDefault           : 2
EnabledState             :
OtherEnabledState        :
RequestedState           : 5
TimeOfLastStateChange    :
TransitioningToState     : 12
AggregationBehavior      :
Directionality           :
CreationTime             : 05.05.2019 22:40:38
LocalAddress             : 192.168.178.50
LocalPort                : 63834
OwningProcess            : 26816
RemoteAddress            : 52.97.151.98
RemotePort               : 443
PSComputerName           :
CimClass                 : ROOT/StandardCimv2:MSFT_NetTCPConnection
CimInstanceProperties    : {Caption, Description, ElementName, InstanceID...}
CimSystemProperties      : Microsoft.Management.Infrastructure.CimSystemProperties

Vor allem keine Informationen über die Latenzzeit und Packetloss o.a. Das ist dann wohl auch eine Sackgasse.

PowerShell Klasse "System.Net.NetworkInformation"

Ich habe dann noch etwas weiter gesucht und bin auf die Klasse "System.Net.NetworkInformation" gestoßen. Diese Klasse gab es vermutlich früher noch nicht, weswegen viele Blogs noch auf die WMI-Methode zugrückgreifen und selbst "Get-NETTCPConnection" nutzt ja wohl WMI. Aber auch über diese .NET-Klasse bekommen wir zumindest schnell heraus, welche aktiven Verbindung es gibt

$Connections = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties().GetActiveTcpConnections()

$Connections[1] | fl *

State          : Established
LocalEndPoint  : 192.168.178.50:64497
RemoteEndPoint : 92.123.41.93:80


$Connections[1] | gm *

   TypeName: System.Net.NetworkInformation.SystemTcpConnectionInformation

Name           MemberType Definition
----           ---------- ----------
Equals         Method     bool Equals(System.Object obj)
GetHashCode    Method     int GetHashCode()
GetType        Method     type GetType()
ToString       Method     string ToString()
LocalEndPoint  Property   IPEndpoint LocalEndPoint {get;}
RemoteEndPoint Property   IPEndpoint RemoteEndPoint {get;}
State          Property   System.Net.NetworkInformation.TcpState State {get;}

Die Informationen sind hier doch sehr spärlich und es ist unwahrscheinlich, dass der Ressource Monitoring diese Datenquelle nutzt.

ETW-Traces

Wenn ich die Quellen richtig deute, dann kommt man an die Daten vermutlich über ETW-Tracing. Durch ein anderes Blog habe ich bestätigen können, dass in meinem Perfmon ein neuer Eintrag erscheint, wenn ich den Ressource Monitor starte und in den Eigenschaften auch "Microsoft-Windows-Kernel-Network" addiert wird.

Danach konnte ich dann über Suchmaschinen weiter gehen und habe einige interessante Artikel gefunden

Zum Thema ETL-Tracing scheint es auch in PowerShell etwas zu geben

get-command *-etw*

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           Remove-EtwTraceSession                             1.0.0.0    EventTracingManagement
Alias           Set-EtwTraceSession                                1.0.0.0    EventTracingManagement
Function        Add-EtwTraceProvider                               1.0.0.0    EventTracingManagement
Function        Flush-EtwTraceSession                              1.0.0.0    EventTracingManagement
Function        Get-EtwTraceProvider                               1.0.0.0    EventTracingManagement
Function        Get-EtwTraceSession                                1.0.0.0    EventTracingManagement
Function        New-EtwTraceSession                                1.0.0.0    EventTracingManagement
Function        Remove-EtwTraceProvider                            1.0.0.0    EventTracingManagement
Function        Save-EtwTraceSession                               1.0.0.0    EventTracingManagement
Function        Send-EtwTraceSession                               1.0.0.0    EventTracingManagement
Function        Set-EtwTraceProvider                               1.0.0.0    EventTracingManagement
Function        Start-EtwTraceSession                              1.0.0.0    EventTracingManagement
Function        Stop-EtwTraceSession                               1.0.0.0    EventTracingManagement
Function        Update-EtwTraceSession                             1.0.0.0    EventTracingManagement

Allerdings sind das wohl eher Befehle um einen Trace im Rahmen eines Troubleshooting in eine Datei zu speichern.

Ich suche aber einen Weg zur Erfassung der Echtzeit-Daten

Hier habe ich erst einmal abgebrochen, da das doch eher für ambitioniertere Entwickler ist. Vielleicht finde ich später noch mal etwas Zeit den Weg hier weiter zu gehen

Weitere Links