Offene Ports anzeigen mit PowerShell


    Tags: ,

    Port-ScannerOffene Ports auf einem Host abzufragen, kann aus unterschiedlichen Gründen notwendig sein. Dazu zählen etwa Security-Checks, das Troubleshooting bei Verbindungs­problemen oder die Prüfung eines Ports, bevor sich ein Script mit einem Host verbindet. Diese Aufgabe kann PowerShell am besten über die .NET-Klasse TcpClient erledigen.

    Für einen großflächigen Port-Scan wird man in der Regel zu Programmen greifen, die auf diesen Zweck spezialisiert sind. Dazu gehören unter anderem einige kostenlose Netzwerk-Scanner.

    In PowerShell bieten sich dafür zwei Varianten an:

    Test-NetConnection für einzelne Ports

    Wenn man jedoch innerhalb eines Scripts herausfinden muss, ob ein Port offen ist, dann wird man eher zu den Bordmitteln von PowerShell greifen. Viele Anleitungen empfehlen dafür den Einsatz von Test-NetConnection.

    Damit könnte man zum Beispiel prüfen, ob auf dem Host mit der IP 192.168.0.55 der Port 80 geöffnet ist:

    Test-NetConnection 192.168.0.55 -Port 80

    Die Eigenschaft TcpTestSucceeded des zurückgegebenen Objekts zeigt dann mit True oder False den Status des Ports.

    Port-Scan mit dem Cmdlet Test-NetConnection

    Innerhalb eines Scripts kann man den Aufruf in ein if-Statement einbetten:

    if((Test-NetConnection 192.168.0.55 -Port 80).TcpTestSucceeded){
    "Port 80 offen"
    }

    Der große Nachteil von Test-NetConnection besteht darin, dass man keinen Timeout angeben kann und es somit lange hängt, wenn ein Port auf eine Anfrage nicht reagiert. Das Prüfen eines ganzen Bereichs ist damit praktisch nicht möglich.

    ConnectAsync-Methode

    Als Alternative bietet sich an, ein Objekt auf Basis der .NET-Klasse Net.Sockets.TcpClient zu erzeugen. Diese umfasst mehrere Methoden zum Aufbau einer Verbindung, darunter Connect() und ConnectAsync(). Erstere hängt wie Test-NetConnection lange fest, wenn ein Port geschlossen ist.

    Hingegen kann man ConnectAsync() mit der Wait()-Methode kombinieren, um ein Zeitlimit in Millisekunden für die Task festzulegen. Ein Wert von 5 reicht in der Regel aus, so dass man etwa den Bereich von 1 bis 1024 in einigen Sekunden scannen kann, während Test-NetConnection dafür eine halbe Ewigkeit braucht:

    1 .. 1024 |
    foreach{ if((New-Object Net.Sockets.TcpClient).ConnectAsync("192.168.0.55", $_).Wait(5))
    { "Port $_ offen" }}

    Port-Scan mit der ConnectAsync-Methode aus der TcpClient-Klasse

    Anstatt einen Bereich auf einem Host zu untersuchen, könnte man etwa in einem Subnetz alle Rechner darauf prüfen, ob der Standard-Port für RDP (3389) offen ist. Auch das lässt sich mit dieser Methode bewerkstelligen:

    1 .. 254 |
    foreach{ if((New-Object Net.Sockets.TcpClient).ConnectAsync("192.168.0.$_", 3389).Wait(5))
    { "Port 3389 auf 192.168.0.$_ offen" }}

    Zusammenfassung

    Wenn man auf einem Host nur einen bestimmten Port prüfen möchte, dann kann man dafür Test-NetConnection verwenden. Dieses Cmdlet hat jedoch einen langen Timeout, so dass ein Scan schnell zur Geduldsprobe wird.

    Als wesentlich flinker erweist sich die Methode ConnectAsync() der .NET-Klasse TcpClient. Die Task lässt sich dort mit Wait() auf eine bestimmte Dauer begrenzen.

    Täglich Know-how für IT-Pros mit unserem Newsletter

    Wir ver­wenden Ihre Mail-Adresse nur für den Ver­sand der News­letter.
    Es erfolgt keine per­sonen­be­zogene Auswertung.

    Bild von Wolfgang Sommergut
    Wolfgang Sommergut hat lang­jährige Erfahrung als Fach­autor, Berater und Kon­ferenz­sprecher zu ver­schie­denen Themen der IT. Da­ne­ben war er als System­ad­mi­ni­stra­tor und Con­sultant tätig.
    // Kontakt: E-Mail, XING, LinkedIn //

    Verwandte Beiträge

    Weitere Links