类似问题: 如何判断远程桌面服务是否正在运行且可用?
我搜索了“如何 ping 特定端口?”这个问题的答案,找到了几个解决方案。在搜索之前,我很清楚“ping”根本不是适合这项工作的工具,但就功能而言,它是最接近我想要完成的工作的工具。
大多数“ping 端口”问题的解决方案都依赖于 nmap 或其他非原生工具,而且通常这些工具的编写方式只适用于一次性检查。我想要做的是能够持续监控远程主机上的端口,这样当该端口上的服务可用时,我就可以收到警报。与上面的问题一样,我对此最常见的用例是在重启后检查计算机的 RDP 可用性(仅 ping 并不能可靠地指示系统是否已完成启动并启动了所有服务)。
这里的关键区别在于,我希望使用 Windows 原生的工具来执行此操作。我从来不知道何时何地需要监控远程系统的服务可用性,而且当需要监控时,我并不总是随身携带便携式工具,因此,如果有一个相对简单的单行命令,使用内置的 CMD 或 PowerShell 实用程序可以完成这项工作,那就太理想了。
我确实有一些装有 Windows 8 或 Server 2012 和 PowerShell 4.0 的系统,但向后兼容 Windows 7 和 Server 2008 并使用 PowerShell 2.0 的解决方案才是理想的。(注意:PowerShell 版本仅供参考 - 任何可以在给定 Windows 版本的全新安装上运行且不需要其他软件的命令或短脚本都可以。)
答案1
如果您要以交互方式进行检查,可以使用 TELNET 客户端输入“telnet 主机端口”,例如“telnet 10.23.43.12 80”来访问 HTTP 端口。
请注意,自 Windows 7/Windows 2008 起,telnet 客户端未默认安装,因此您需要在控制面板->添加/删除软件->Windows 组件中激活该工具。
答案2
在 Windows 8 中,您可以使用Test-NetConnection
来获得与经典ping
和tracert
工具类似的功能,以及检查远程系统端口的状态。不幸的是,Test-NetConnection
与它所取代的工具相比, 的选项相对有限。因此,它本身无法很好地用于连续监控。幸运的是,PowerShell 非常适合编写脚本。这里有一个单行代码(从技术上讲,几行代码浓缩为一行),它将连续测试端口的可用性,并将带有时间戳的结果打印到控制台。
cls;1..8|%{""};for(){$x=tnc 192.168.0.1 -Po 80;"$(Get-Date) $($x.TcpTestSucceeded)"}
这是脚本运行时的屏幕截图。您可以在这里看到为什么我启动脚本时使用了此选项,cls;1..8|%{""};
尽管从技术上讲这并非必需。此外,您可以看到,Test-NetConnection
即使使用 LAN 连接,每次运行也需要大约 9-10 秒。
这是脚本的注释多行版本。这是相同的代码,只是展开并附带了演练。
# CLS is a built-in alias for Clear-Host.
# This clears any pre-existing output from the console so we can start ours from the top.
cls;
# This takes the integers from 1 through 8 and pipes them to a ForEach-Object loop.
# (The percent symbol, "%", is a built-in alias for ForEach-Object.)
# Putting just a pair of double-quotes in the script block outputs a single blank line.
# Effectively, this line of script just outputs 8 blank lines.
# While Test-NetConnection runs, it puts a status display on the top 8 lines of the console.
# So, we're using this to make our output start below that level in order to be visible.
1..8|%{""};
# This begins an infinite for loop. It will run until aborted by the user.
# (e.g.: With CTRL+C)
# Note: Due to the way Test-NetConnection operates, the abort may take a few seconds to process.
for(){
# TNC is a built-in alias for Test-NetConnection.
# -Po is a shorthand for the -Port parameter name.
# PowerShell allows shortening of parameter names down to as few characters are needed to uniquely identify the parameter.
# This tests for connectivity to port 80 at 192.168.0.1 and puts the results in $x.
$x=tnc 192.168.0.1 -Po 80;
# The last step here is to output a timestamp, and the results.
# Double-quotes allow for per-processing certain elements before including them in an output string.
# Encapsulating script blocks with $(), within the double-quotes, lets us put their results directly in the output string.
# So, the first part gets the date and time for the start of the output.
# Then, with a space to separate it, the TcpTestSucceeded property of $x is retrieved and put at the end.
"$(Get-Date) $($x.TcpTestSucceeded)"
}
它不像我希望的那样简洁,但它确实能完成工作。我绝对不指望很快就能记住它,但一旦你理解了使它工作的命令和 PowerShell 基础知识,它就相对地易于即时重建。
对于一些更简单的事情,只需继续检查端口并停下来让你知道它何时启动,你可以使用以下命令:
while((tnc 192.168.0.1 -Po 80).TcpTestSucceeded -eq $False){};Get-Date
在这里,我们使用 while 循环在端口关闭期间不断重新测试端口。一旦成功连接到端口,while 循环就会退出,Get-Date 将报告时间。只要循环正在Test-NetConnection
运行,您还会看到一些警告消息 - 这是因为它使用警告输出通道来报告 ping 或端口连接何时失败,然后再实际将完整结果作为正常输出发送。
不幸的是,Test-NetConnection
在运行 Windows 8 之前的系统上不可用。因此,这也缺乏我所希望的交叉兼容性。不过,现在总比没有好。