как проверить, открыт ли порт на удаленном сервере с пакетным файлом и без стороннего программного обеспечения?

<p>поскольку <a href="https://stackoverflow.com/questions/1168317/check-status-of-one-port-on-remote-host"><strong><em>этот вопрос</em></strong></a> закрыто (там, где я собирался ответить первым), я открываю этот.</p><p>на некоторых машинах запрещено устанавливать/загружать двоичные файлы, поэтому я хочу знать, как я могу проверить, открыт ли порт на удаленном компьютере, используя только собственные возможности сценариев windows.</p>

<p>к сожалению, windows не предлагает простых инструментов для проверки, открыт ли порт на удаленном сервере.</p><p>одним из вариантов является telnet, но он не может быть записан в сценарии, поскольку он закрывается, когда его вывод перенаправляется или захватывается. когда-то давно на компьютерах с windows был установлен com-объект <strong>mswinsock.winsock.1</strong>, который можно было использовать в сценарии, но не более того. <a href="https://www.microsoft.com/en-us/download/details.aspx?id=9964"><strong>portqry</strong></a> и <a href="https://technet.microsoft.com/en-us/sysinternals/psping.aspx"><strong>psping</strong></a> - замечательные инструменты, но вам все равно придется их загружать (несмотря на то, что они предоставляются microsoft).</p><p>таким образом, самый простой способ - использовать powershell . <br>вот код для простого скрипта <strong>.bat</strong>, внутренне использующий powershell для выполнения работы:</p><pre><code>@echo off ::must be without quotes. if you intend to use command line arguments use %~1 set "host=google.com" set /a port=443 for /f %%a in ('powershell "$t = new-object net.sockets.tcpclient;try{$t.connect("""%host%""", %port%)}catch{};$t.connected"') do set "open=%%a" :: or simply :: powershell "$t = new-object net.sockets.tcpclient;try{$t.connect("""%host%""", %port%)}catch{};$t.connected" echo open: %open% </code></pre><p>на некоторых машинах есть .net framework без установленного powershell, поэтому в этом случае код c # может быть встроен в пакетный скрипт с помощью <a href="https://github.com/npocmaka/batch.scripts/blob/master/hybrids/.net/msbuild/checkport.bat">msbuild</a> :</p><pre><code><!-- : @echo off :: checks if a port on a remote server is open :: returns errorlevel 1 if it's closed setlocal for %%h in (/h /help -help -h "") do ( if /i "%~1" equ "%%~h" ( goto :printhelp ) ) if "%~2" equ "" goto :printhelp set "host=%~1" set /a port=%~2 :::::: starting c# code ::::::: :: searching for msbuild location for /r "%systemroot%\microsoft.net\framework\" %%# in ("*msbuild.exe") do set "msb=%%#" if not defined msb ( echo no .net framework installed endlocal & exit /b 10 ) rem :::::::::: calling msbuid ::::::::: call %msb% /nologo /noconsolelogger "%~dpsfnx0" rem :::::::::::::::::::::::::::::::::::: endlocal & exit /b %errorlevel% :printhelp echo checks if port is open on a remote server echo( echo usage: echo %~nx0 host port echo( echo if the port is not accessible an errorlevel 1 is set endlocal & exit /b 0 --> <project toolsversion="$(msbuildtoolsversion)" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <target name="_"><_/></target> <usingtask taskname="_" taskfactory="codetaskfactory" assemblyfile="$(msbuildtoolspath)\microsoft.build.tasks.v$(msbuildtoolsversion).dll" > <task> <using namespace="system" /> <using namespace="system.net.sockets" /> <code type="method" language="cs"><![cdata[ public override bool execute(){ string host=environment.getenvironmentvariable("host").tolower(); int port=int32.parse(environment.getenvironmentvariable("port")); console.writeline("checking host {0} and port {1}",host,port); using(tcpclient client = new tcpclient()) { try { client.connect(host, port); } catch(exception) { console.writeline("closed"); return false; } client.close(); console.writeline("open"); return true; } } ]]> </code> </task> </usingtask> </project> </code></pre><p>что касается машин без .net framework, я не знаю ни одного собственного метода проверки удаленных портов.</p>

<p>если вы хотите проверить только порты tcp, вы можете использовать <a href="https://technet.microsoft.com/en-us/library/dn372891(v=wps.630).aspx">test-netconnection</a> . if предлагает параметр <code>-port</code> для определения порта tcp. </p>

<p>эти команды могут быть использованы в powershell:</p><pre><code>new-object system.net.sockets.tcpclient("123.12.12.123", 22) new-object system.net.sockets.udpclient("123.12.12.123", 22) </code></pre>