我的脚本下面有以下代码片段,它使用WebRequest来ping一个Web / app服务器列表,我根据服务器列表中列出的好/坏服务器的顺序得到随机结果。
例如,如果列表中首先列出了错误的服务器(我收回404或503的代码),那么我的脚本似乎准确报告。但是,如果首先列出好的服务器(返回状态=“OK”),那么我的结果就不准确了。
这是我的代码段:
$ServerList = gc "$pwd\servers\test_servers.lst"
ForEach ($_ in $ServerList)
{
# Ping web server test
$url = "http://$_.domain.net/logon"
Write-Host "Pinging web address for server: $url ..."
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
If ($response.StatusCode -eq "OK")
{
#$True
Write-Host "Web Ping on $_ Succeeded."
}
Else
{
#$False
Write-Host "Web Ping on $_ FAILED!!!"
}
}
以下是示例服务器列表:
server1 (reports back a 404)
server2 (reports back a 503)
server3 (gets a status = "OK")
运行脚本时,这是“准确的”cmd输出:
C:\TFS\Sandbox>powershell ./temp.ps1
Pinging web address for server: http://server1.domain.net/wfc/logon ...
Exception calling "GetResponse" with "0" argument(s): "The remote server return
ed an error: (404) Not Found."
At C:\TFS\Sandbox\temp.ps1:8 char:34
+ $response = $request.GetResponse <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Web Ping on server1 FAILED!!!
Pinging web address for server: http://server2.domain.net/wfc/logon ...
Exception calling "GetResponse" with "0" argument(s): "The remote server return
ed an error: (503) Server Unavailable."
At C:\TFS\Sandbox\temp.ps1:8 char:34
+ $response = $request.GetResponse <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Web Ping on server2 FAILED!!!
Pinging web address for server: http://server3.domain.net/wfc/logon ...
Web Ping on server3 Succeeded.
现在,当我重新订购首先列出好服务器的服务器列表时,就像这样:
server3 (gets a status = "OK")
server1 (reports back a 404)
server2 (reports back a 503)
我得到的结果不准确,服务器1和服务器2报告为OK:
Pinging web address for server: http://server3.domain.net/wfc/logon ...
Web Ping on server3 Succeeded.
Pinging web address for server: http://server1.domain.net/wfc/logon ...
Exception calling "GetResponse" with "0" argument(s): "The remote server return
ed an error: (404) Not Found."
At C:\TFS\Sandbox\temp.ps1:8 char:34
+ $response = $request.GetResponse <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Web Ping on server1 Succeeded.
Pinging web address for server: http://server2.domain.net/wfc/logon ...
Exception calling "GetResponse" with "0" argument(s): "The remote server return
ed an error: (503) Server Unavailable."
At C:\TFS\Sandbox\temp.ps1:8 char:34
+ $response = $request.GetResponse <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Web Ping on server2 Succeeded.
为什么我根据服务器的列表方式得到混合结果?
提前致谢!
答案 0 :(得分:9)
您可能需要关闭连接:
$response.Close()
http://msdn.microsoft.com/en-us/library/system.net.webresponse.close(v=vs.90).aspx
我会这样写:
foreach ($server in $ServerList) {
try {
$url = "http://${server}.domain.net/logon"
Write-Host "Pinging web address for server: $url ..."
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
Write-Host "Web Ping on $server Succeeded."
} catch {
Write-Host ("Web Ping on $server FAILED!!! The error was '{0}'." -f $_)
} finally {
if ($response) {
$response.Close()
Remove-Variable response
}
}
}
答案 1 :(得分:3)
这是因为WebRequest
引发了不成功尝试的异常,而$response
在您获得503
,404
等情况下并未真正设置。你确实获得了成功,响应被设置为响应(状态代码正常),但是如果下一个服务器引发404,那么响应仍然是OK状态,因为WebRequest只引发异常并且没有不给$ response分配任何东西。您可能希望trap
(或try catch
)异常并在那里处理成功或失败,或者在循环的每次迭代中将$response
设置为null:
foreach($server in $serverlist){
$response=$null
...
另外,不要使用$_
作为迭代变量,它是自动变量,并且不是在这里使用它的好形式。
请注意,您所写的内容也可能会耗尽系统资源(它暂停一次),因此请妥善处理相应的响应。 $response = $null
可能就足够了,但您可能仍需要在循环结束时正确关闭响应。