Windows batch script pour voir si une séquence de serveur / ports est ouverte?

Je peux exécuter une seule commande pour voir si un port est ouvert:

portqry -n servername -e 80 

Je veux lancer ceci contre une liste de serveurs:

  1. DEV1 80
  2. DEV2 80
  3. DEV3 80
  4. TEST1 80
  5. TEST2 80
  6. PROD 80

Je veux tous les tester en utilisant un seul script de lot Windows et voir quels ports sont ouverts et lesquels sont fermés. (Et je ne veux pas que ça tombe sur le premier port fermé).

Ma question est la suivante: existe-t-il un script de lot Windows pour voir si une séquence de serveurs / ports est ouverte?

Supplémentaire: Je suis conscient qu’il existe d’autres questions demandant comment vérifier si un port est ouvert. Aucun d’entre eux ne concerne le script pour une séquence de ports de manière fiable.

Voici. Payez-le en avant. 🙂 Pour répondre directement à votre question, utilisez simplement une boucle for pour parcourir vos serveurs et effectuez un portqry sur chacun. Edit: Cet extrait de PowerShell trouvé est utile pour se débarrasser de la dépendance PortQry.

 @echo off setlocal set "servers=dev1 dev2 dev3 test1 test2 test2:8080 prod prod:443" for %%I in (%servers%) do ( for /f "tokens=1,2 delims=:" %%a in ("%%I") do ( set "port=%%~b" if not defined port set "port=80" setlocal enabledelayedexpansion call :handshake "%%~a" "!port!" && ( echo %%a port !port!: OK ) || ( echo %%a port !port!: Error ) endlocal ) ) goto :EOF :handshake   powershell "$t=new-object Net.Sockets.TcpClient;$c=$t.BeginConnect('%~1',%~2,{},{});if($c.AsyncWaitHandle.WaitOne(1000)){$t.EndConnect($c);exit 0};exit 1" exit /b %ERRORLEVEL% 

Voici la solution originale utilisant PortQry 2.0 :

 @echo off setlocal set "servers=dev1 dev2 dev3 test1 test2 test2:8080 prod prod:443" for %%I in (%servers%) do ( for /f "tokens=1,2 delims=:" %%a in ("%%I") do ( set "port=%%~b" if not defined port set "port=80" setlocal enabledelayedexpansion portqry -n "%%~a" -e "!port!" >NUL 2>NUL && ( echo %%a port !port!: OK ) || ( echo %%a port !port!: Error ) endlocal ) ) 

Si vous testez uniquement des services Web, il serait plus judicieux de procéder de manière différente. Vous pouvez utiliser l’object Microsoft.XMLHTTP COM pour se débarrasser de cette dépendance de portqry ; Les réponses acquises seront plus pertinentes pour les services HTTP. (Par exemple, si vous avez un serveur VNC exécuté sur le port 8080 où vous attendez qu’un service Web écoute à la place, portqry renverra probablement un succès lorsque vous en aurez besoin pour retourner en échec.)

Quoi qu’il en soit, enregistrez-le en tant que script .bat et salez au goût.

 @if (@CodeSection == @Batch) @then @echo off setlocal set "servers=dev1 dev2 dev3 test1 test2 test2:8080 prod prod:443" for %%I in (%servers%) do ( for /f "tokens=1,2 delims=:" %%a in ("%%I") do ( set "port=%%~b" if not defined port set "port=80" setlocal enabledelayedexpansion cscript /nologo /e:JScript "%~f0" "%%~a" "!port!" && ( echo %%a port !port!: OK ) || ( echo %%a port !port!: Error ) endlocal ) ) goto :EOF @end // end batch / begin JScript chimera var server = WSH.Arguments(0), port = WSH.Arguments(1), protocol = port == 443 ? 'https' : 'http', URL = protocol + '://' + server + ':' + port + '/', XHR = WSH.CreateObject('Microsoft.XMLHTTP'); XHR.open('GET', URL); XHR.setRequestHeader('User-Agent','XMLHTTP/1.0'); XHR.send(''); while (XHR.readyState != 4) WSH.Sleep(25); WSH.Quit(XHR.status - 200); 

C’est ce que j’ai fini par remplacer le VBScript ci-dessus par – un fichier appelé porttest.ps1 qui est exécuté avec powershell -f porttest.ps1

 param( [ssortingng] $remoteHost = "arbitrary-remote-hostname", [int] $port = 23 ) # Open the socket, and connect to the computer on the specified port write-host "Connecting to $remoteHost on port $port" $tcpobject = new-Object system.Net.Sockets.TcpClient $connect = $tcpobject.BeginConnect($remoteHost,$port,$null,$null) #Configure a timeout before quitting - time in milliseconds $wait = $connect.AsyncWaitHandle.WaitOne(1000,$false) If (-Not $Wait) { 'Timeout' exit 1 } Else { $error.clear() $tcpobject.EndConnect($connect) | out-Null If ($Error[0]) { Write-warning ("{0}" -f $error[0].Exception.Message) exit 1 } Else { 'Port open!' exit 0 } }