it-swarm.com.ru

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

Поскольку этот вопрос закрыто (там, где я собирался ответить первым), я открываю этот.

На некоторых машинах запрещено устанавливать/загружать двоичные файлы, поэтому я хочу знать, как я могу проверить, открыт ли порт на удаленном компьютере, используя только собственные возможности сценариев Windows.

6
npocmaka

К сожалению, Windows не предлагает простых инструментов для проверки, открыт ли порт на удаленном сервере.

Одним из вариантов является telnet, но он не может быть записан в сценарии, поскольку он закрывается, когда его вывод перенаправляется или захватывается. Когда-то давно на компьютерах с Windows был установлен COM-объект MSWinsock.Winsock.1, который можно было использовать в сценарии, но не более того. PortQry и PsPing - замечательные инструменты, но вам все равно придется их загружать (несмотря на то, что они предоставляются Microsoft).

Таким образом, самый простой способ - использовать PowerShell .
Вот код для простого скрипта .bat, внутренне использующий Powershell для выполнения работы:

@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%

На некоторых машинах есть .NET Framework без установленного PowerShell, поэтому в этом случае код C # может быть встроен в пакетный скрипт с помощью msbuild :

<!-- :
    @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>

Что касается машин без .NET Framework, я не знаю ни одного собственного метода проверки удаленных портов.

16
npocmaka

Если вы хотите проверить только порты TCP, вы можете использовать Test-NetConnection . If предлагает параметр -Port для определения порта TCP. 

5
Moerwald

Эти команды могут быть использованы в Powershell:

New-Object System.Net.Sockets.TcpClient("123.12.12.123", 22)
New-Object System.Net.Sockets.UdpClient("123.12.12.123", 22)
0
Erdem KAYA