npo*_*aka 8 c# windows powershell cmd batch-file
由于这个问题 已经结束(我打算先回答)我正在打开这个问题.
在某些机器上禁止安装/下载二进制文件,因此我想知道如何使用本机Windows脚本功能检查远程计算机上的端口是否打开.
npo*_*aka 17
令人沮丧的是,Windows不提供简单的工具来检查端口是否在远程服务器上打开.
一个选项是telnet,但它不能编写脚本,因为它在重定向或捕获输出时关闭.曾几何时,Windows机器上安装了一个可以在脚本中使用的MSWinsock.Winsock.1 COM对象,但不多了.PortQry和PsPing是一个很棒的工具,但你仍然需要下载它们(尽管它是由微软提供的).
所以最简单的方法就是依赖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%
Run Code Online (Sandbox Code Playgroud)
有些机器没有安装PowerShell的.NET框架,因此在这种情况下,可以使用msbuild将C#代码嵌入到批处理脚本中:
<!-- :
@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>
Run Code Online (Sandbox Code Playgroud)
对于没有.NET框架的机器,我不知道检查远程端口的任何本机方法.
如果您只想检查TCP端口,可以使用Test-NetConnection.如果提供了一个-Port
参数来定义TCP端口.
这些命令可以在 Powershell 中使用:
New-Object System.Net.Sockets.TcpClient("123.12.12.123", "22")
New-Object System.Net.Sockets.UdpClient("123.12.12.123", "22")
Run Code Online (Sandbox Code Playgroud)