Windows批处理脚本查看server/ports序列是否打开?
Windows batch script to see if a sequence of server/ports is open?
我可以 运行 一个命令来查看端口是否打开:
portqry -n servername -e 80
我想运行针对服务器列表:
- DEV1 80
- DEV2 80
- DEV3 80
- 测试 1 80
- 测试 2 80
- 产品 80
我想用一个 Windows 批处理脚本测试它们,看看哪些端口是打开的,哪些是关闭的。 (而且我不希望它在第一个关闭的端口上掉下来)。
我的问题是:是否有Windows批处理脚本来查看server/ports序列是否打开?
附加: 我知道还有其他问题询问如何检查端口是否打开。 None 其中是关于以可靠的方式为一系列端口编写脚本。
给你。向前支付。 :) 要直接回答您的问题,只需使用 for
循环遍历您的服务器并在每个服务器上执行 portqry
。 编辑:您找到的那个 PowerShell 片段对于摆脱 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 <server> <port>
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%
这是使用 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
)
)
如果您要测试的只是 Web 服务,那么以不同的方式进行测试可能更有意义。您可以使用 Microsoft.XMLHTTP
COM 对象摆脱 portqry
依赖;这样获得的响应将与 HTTP 服务更相关。 (例如,如果您在端口 8080 上有一个 VNC 服务器 运行,您希望 Web 服务在其中侦听,那么 portqry
可能会 return 在您需要时成功到 return 失败。)
无论如何,将其保存为 .bat 脚本并加盐调味。
@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);
这就是我最终将上面的 VBScript 替换为 - 一个名为 porttest.ps1
的文件,该文件是 运行 和 powershell -f porttest.ps1
param(
[string] $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
}
}
与上面不同的是,这根本不需要 powershell,只要安装了 telnet 客户端 (dism /online /Enable-Feature /FeatureName:TelnetClient
)
,它应该适用于 windows 的所有版本
如果有人知道如何停止 telnet 命令输出任何内容,请添加评论,因为如果我添加重定向,它会拒绝 运行。我相信 telnet 需要一个标准输出并且不能被重定向。
为此,只需将两个 127.0.0.1 IP 地址更改为您要扫描的主机即可。
break>Results.txt & (for /l %a in (1,1,49152) do @taskkill /im telnet.exe /f >NUL 2>&1 & @start /b telnet.exe 127.0.0.1 %a & for /f %i in ('netstat -n ^| findstr /r /c:"TCP[ ][ ]*127.0.0.1:%a[ ][ ]*.*ESTABLISHED" ^| findstr /n ".*" ^| findstr "^1:"') do @echo "TCP Port Open: %a" >> Results.txt) & taskkill /im telnet.exe /f >NUL 2>&1
完成后,要获得结果,您可以键入
type Results.txt
我可以 运行 一个命令来查看端口是否打开:
portqry -n servername -e 80
我想运行针对服务器列表:
- DEV1 80
- DEV2 80
- DEV3 80
- 测试 1 80
- 测试 2 80
- 产品 80
我想用一个 Windows 批处理脚本测试它们,看看哪些端口是打开的,哪些是关闭的。 (而且我不希望它在第一个关闭的端口上掉下来)。
我的问题是:是否有Windows批处理脚本来查看server/ports序列是否打开?
附加: 我知道还有其他问题询问如何检查端口是否打开。 None 其中是关于以可靠的方式为一系列端口编写脚本。
给你。向前支付。 :) 要直接回答您的问题,只需使用 for
循环遍历您的服务器并在每个服务器上执行 portqry
。 编辑:您找到的那个 PowerShell 片段对于摆脱 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 <server> <port>
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%
这是使用 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
)
)
如果您要测试的只是 Web 服务,那么以不同的方式进行测试可能更有意义。您可以使用 Microsoft.XMLHTTP
COM 对象摆脱 portqry
依赖;这样获得的响应将与 HTTP 服务更相关。 (例如,如果您在端口 8080 上有一个 VNC 服务器 运行,您希望 Web 服务在其中侦听,那么 portqry
可能会 return 在您需要时成功到 return 失败。)
无论如何,将其保存为 .bat 脚本并加盐调味。
@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);
这就是我最终将上面的 VBScript 替换为 - 一个名为 porttest.ps1
的文件,该文件是 运行 和 powershell -f porttest.ps1
param(
[string] $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
}
}
与上面不同的是,这根本不需要 powershell,只要安装了 telnet 客户端 (dism /online /Enable-Feature /FeatureName:TelnetClient
)
如果有人知道如何停止 telnet 命令输出任何内容,请添加评论,因为如果我添加重定向,它会拒绝 运行。我相信 telnet 需要一个标准输出并且不能被重定向。
为此,只需将两个 127.0.0.1 IP 地址更改为您要扫描的主机即可。
break>Results.txt & (for /l %a in (1,1,49152) do @taskkill /im telnet.exe /f >NUL 2>&1 & @start /b telnet.exe 127.0.0.1 %a & for /f %i in ('netstat -n ^| findstr /r /c:"TCP[ ][ ]*127.0.0.1:%a[ ][ ]*.*ESTABLISHED" ^| findstr /n ".*" ^| findstr "^1:"') do @echo "TCP Port Open: %a" >> Results.txt) & taskkill /im telnet.exe /f >NUL 2>&1
完成后,要获得结果,您可以键入
type Results.txt