web-dev-qa-db-fra.com

Comment vérifier l'accès au port réseau et afficher un message utile?

J'essayais de vérifier si le port est ouvert ou non en utilisant PowerShell comme suit.

(new-object Net.Sockets.TcpClient).Connect("10.45.23.109", 443)

Cette méthode fonctionne, mais la sortie n'est pas conviviale. Cela signifie que s'il n'y a pas d'erreur, il y a accès. Existe-t-il un moyen de vérifier le succès et d'afficher un message du type "Le port 443 est opérationnel"?

23
Samselvaprabu

En fait, la réponse de Shay Levy est presque correcte mais j'ai un problème étrange, comme je l'ai mentionné dans sa colonne de commentaires. Donc, je divise la commande en deux lignes et cela fonctionne bien.

$Ipaddress= Read-Host "Enter the IP address:"
$Port= Read-Host "Enter the port number to access:"

$t = New-Object Net.Sockets.TcpClient
$t.Connect($Ipaddress,$Port)
    if($t.Connected)
    {
        "Port $Port is operational"
    }
    else
    {
        "Port $Port is closed, You may need to contact your IT team to open it. "
    }
12
Samselvaprabu

Si vous utilisez Windows 8/Windows Server 2012 ou une version ultérieure, vous pouvez utiliser la commande Test-NetConnection dans PowerShell.

Ex: Test-NetConnection -Port 53 -ComputerName LON-DC1

37
SimonOzturk

J'ai amélioré la réponse de Salselvaprabu de plusieurs manières:

  1. C'est maintenant une fonction - vous pouvez créer votre profil powershell et l'utiliser à tout moment
  2. Il peut accepter l'hôte comme nom d'hôte ou comme adresse ip
  3. Plus d'exceptions si l'hôte ou le port est inutilisable - juste du texte

Appelez ça comme ça: 

Test-Port example.com 999
Test-Port 192.168.0.1 80

function Test-Port($hostname, $port)
{
    # This works no matter in which form we get $Host - hostname or ip address
    try {
        $ip = [System.Net.Dns]::GetHostAddresses($hostname) | 
            select-object IPAddressToString -expandproperty  IPAddressToString
        if($ip.GetType().Name -eq "Object[]")
        {
            #If we have several ip's for that address, let's take first one
            $ip = $ip[0]
        }
    } catch {
        Write-Host "Possibly $hostname is wrong hostname or IP"
        return
    }
    $t = New-Object Net.Sockets.TcpClient
    # We use Try\Catch to remove exception info from console if we can't connect
    try
    {
        $t.Connect($ip,$port)
    } catch {}

    if($t.Connected)
    {
        $t.Close()
        $msg = "Port $port is operational"
    }
    else
    {
        $msg = "Port $port on $ip is closed, "
        $msg += "You may need to contact your IT team to open it. "                                 
    }
    Write-Host $msg
}
35
mshutov

Vous pouvez vérifier si la propriété Connected est définie sur $ true et afficher un message convivial:

    $t = New-Object Net.Sockets.TcpClient "10.45.23.109", 443 

    if($t.Connected)
    {
        "Port 443 is operational"
    }
    else
    {
        "..."
    }
11
Shay Levy

Avec les dernières versions de PowerShell, il existe une nouvelle applet de commande, Test-NetConnection.

Cette applet de commande vous permet, en fait, d’envoyer une requête ping à un port, comme ceci:

Test-NetConnection -ComputerName <remote server> -Port nnnn

Je sais que c'est une vieille question, mais si vous cliquez sur cette page (comme je le faisais) à la recherche de cette information, cet ajout pourrait être utile!

6
Thomas Lee

J'ai essayé d'améliorer la suggestion de mshutov . J'ai ajouté l'option permettant d'utiliser la sortie comme objet.

 function Test-Port($hostname, $port)
    {
    # This works no matter in which form we get $Host - hostname or ip address
    try {
        $ip = [System.Net.Dns]::GetHostAddresses($hostname) | 
            select-object IPAddressToString -expandproperty  IPAddressToString
        if($ip.GetType().Name -eq "Object[]")
        {
            #If we have several ip's for that address, let's take first one
            $ip = $ip[0]
        }
    } catch {
        Write-Host "Possibly $hostname is wrong hostname or IP"
        return
    }
    $t = New-Object Net.Sockets.TcpClient
    # We use Try\Catch to remove exception info from console if we can't connect
    try
    {
        $t.Connect($ip,$port)
    } catch {}

    if($t.Connected)
    {
        $t.Close()
        $object = [pscustomobject] @{
                        Hostname = $hostname
                        IP = $IP
                        TCPPort = $port
                        GetResponse = $True }
        Write-Output $object
    }
    else
    {
        $object = [pscustomobject] @{
                        Computername = $IP
                        TCPPort = $port
                        GetResponse = $False }
        Write-Output $object

    }
    Write-Host $msg
}
4
Hilbert

Si vous utilisez des versions plus anciennes de Powershell où Test-NetConnection n'est pas disponible, voici un one-liner pour le nom d'hôte "my.hostname" et le port "123":

$t = New-Object System.Net.Sockets.TcpClient 'my.hostname', 123; if($t.Connected) {"OK"}

Retourne OK ou un message d'erreur.

3
David I.

Grande réponse de Mshutov & Salselvaprabu. J'avais besoin de quelque chose d'un peu plus robuste, qui vérifie toutes les adresses IP fournies au lieu de ne vérifier que la première.

Je souhaitais également reproduire certains noms de paramètres et fonctionnalités par rapport à la fonction Test-Connection.

Cette nouvelle fonction vous permet de définir un nombre pour le nombre de tentatives et le délai entre chaque tentative. Prendre plaisir!

function Test-Port {

    [CmdletBinding()]
    Param (
        [string] $ComputerName,
        [int] $Port,
        [int] $Delay = 1,
        [int] $Count = 3
    )

    function Test-TcpClient ($IPAddress, $Port) {

        $TcpClient = New-Object Net.Sockets.TcpClient
        Try { $TcpClient.Connect($IPAddress, $Port) } Catch {}

        If ($TcpClient.Connected) { $TcpClient.Close(); Return $True }
        Return $False

    }

    function Invoke-Test ($ComputerName, $Port) {

        Try   { [array]$IPAddress = [System.Net.Dns]::GetHostAddresses($ComputerName) | Select-Object -Expand IPAddressToString } 
        Catch { Return $False }

        [array]$Results = $IPAddress | % { Test-TcpClient -IPAddress $_ -Port $Port }
        If ($Results -contains $True) { Return $True } Else { Return $False }

    }

    for ($i = 1; ((Invoke-Test -ComputerName $ComputerName -Port $Port) -ne $True); $i++)
    {
        if ($i -ge $Count) {
            Write-Warning "Timed out while waiting for port $Port to be open on $ComputerName!"
            Return $false
        }

        Write-Warning "Port $Port not open, retrying..."
        Sleep $Delay
    }

    Return $true

}
0
Marc Kellerman

réduit cela à une ligne, la variable "$ port389Open" est définie sur True ou false - il est rapide et facile à reproduire pour une liste de ports

try{$socket = New-Object Net.Sockets.TcpClient($ipAddress,389);if($socket -eq $null){$Port389Open = $false}else{Port389Open = $true;$socket.close()}}catch{Port389Open = $false}

Si vous voulez vraiment devenir fou, vous pouvez retourner le tableau entier- 

Function StdPorts($ip){
    $rst = "" |  select IP,Port547Open,Port135Open,Port3389Open,Port389Open,Port53Open
    $rst.IP = $Ip
    try{$socket = New-Object Net.Sockets.TcpClient($ip,389);if($socket -eq $null){$rst.Port389Open = $false}else{$rst.Port389Open = $true;$socket.close();$ipscore++}}catch{$rst.Port389Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,53);if($socket -eq $null){$rst.Port53Open = $false}else{$rst.Port53Open = $true;$socket.close();$ipscore++}}catch{$rst.Port53Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,3389);if($socket -eq $null){$rst.Port3389Open = $false}else{$rst.Port3389Open = $true;$socket.close();$ipscore++}}catch{$rst.Port3389Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,547);if($socket -eq $null){$rst.Port547Open = $false}else{$rst.Port547Open = $true;$socket.close();$ipscore++}}catch{$rst.Port547Open = $false}
    try{$socket = New-Object Net.Sockets.TcpClient($ip,135);if($socket -eq $null){$rst.Port135Open = $false}else{$rst.Port135Open = $true;$socket.close();$SkipWMI = $False;$ipscore++}}catch{$rst.Port135Open = $false}
    Return $rst
}
0
jdelpheki

Lors de la numérisation d'un port fermé, il ne répond plus pendant longtemps. Cela semble être plus rapide lors de la résolution de fqdn en ip comme:

0
uzjsme