我有一个执行服务器维护的脚本。部分工作是停止并重新启动主机服务器上的服务。判断服务何时完全重新联机的最简单方法是尝试连接到管理端口。一旦您能够连接到管理端口,服务就会启动并为业务做好准备。很简单。这段代码将循环,直到它重新联机:
function test-port {
$PortProbe = New-Object Net.Sockets.TcpClient
$ErrorActionPreference = "SilentlyContinue"
while ($PortProbe.Connected -eq 0){
$PortProbe.Connect("localhost",3041)
write-host "Server is off line... waiting for it to come online."
sleep 1
}
write-host "Server is back online!"
$ErrorActionPreference = "Continue"
$PortProbe.Close()
}
test-port
所以在我的脚本中,我做我的工作,重新启动服务,然后调用“test-port”让脚本等待服务重新联机,然后继续。
我遇到的问题是如果我在脚本中有一个通用陷阱,它会在端口尚未就绪时捕获连接错误。
Exception calling "Connect" with "2" argument(s): "No connection could be made because the target machine actively refused it 127.0.0.1:3041"
At line:6 char:27
+ $PortProbe.Connect <<<< ("localhost",3041)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
我最后有一个陷阱声明,以防发生一些非常奇怪的错误,它会启动电子邮件警报。但它打破了测试端口功能的功能。
理论上,我可以捕获这个特定的TCP / IP连接错误并告诉它继续,就像没有发生任何事情,但我无法弄清楚如何判断错误消息的类是什么。我认为会是这样的:
trap [Net.Sockets.TcpClient] { #Don't Panic
}
但那不对。
有什么建议吗?我是否需要完全不同地处理这个问题?
答案 0 :(得分:0)
为什么不在循环中使用Get-Service
cmdlet来检查服务的状态,而不是放到套接字上,例如:
do {
$svc = Get-Service -ComputerName Localhost w3svc
$connected = $false
if ($svc -and $svc.Status -eq 'Running') {
$connected = $true
}
Start-Sleep -Milliseconds 500
} while (!$connected)