web-dev-qa-db-ja.com

バッチファイルがあり、サードパーティのソフトウェアがないリモートサーバーでポートが開いているかどうかを確認する方法

this question が閉じているため(最初に回答するつもりでした)、これを開きます。

一部のマシンでは、バイナリのインストール/ダウンロードが禁止されているため、ネイティブのWindowsスクリプト機能のみを使用してリモートマシンのポートが開いているかどうかを確認する方法を知りたいです。

9
npocmaka

困ったことに、Windowsには、リモートサーバーでポートが開いているかどうかを確認する簡単なツールがありません。

1つのオプションはtelnetですが、出力がリダイレクトまたはキャプチャされると終了するため、スクリプト化できません。昔々、スクリプトで使用できるMSWinsock.Winsock.1COMオブジェクトがWindowsマシンにインストールされていましたが、それ以上はありませんでした。 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%

一部のマシンには、PowerShellがインストールされていない.NETフレームワークがあるため、この場合、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フレームワークのないマシンについては、リモートポートをチェックするためのネイティブな方法を知りません。

17
npocmaka

TCPポートのみを確認したい場合は Test-NetConnection を使用できます。もし-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)
2
Erdem KAYA