【问题标题】:Random WebRequest results with PowerShell使用 PowerShell 的随机 WebRequest 结果
【发布时间】:2012-02-01 04:34:26
【问题描述】:

我的脚本中有以下 sn-p,它使用 WebRequest 来 ping Web/应用服务器列表,并且我根据服务器列表中列出的好/坏服务器的顺序获得随机结果。

例如,如果坏服务器(我得到的代码为 404 或 503)列在列表的首位,那么我的脚本似乎报告准确。但是,如果首先列出了好的服务器(返回状态 =“OK”),那么我的结果是不准确的。

这是我的代码 sn-p:

$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 被报告为正常:

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.

为什么我会根据服务器的列出方式得到不同的结果?

提前致谢!

【问题讨论】:

    标签: powershell webrequest


    【解决方案1】:

    您可能需要关闭连接:

    $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
            }
        }
    }
    

    【讨论】:

    • 虽然关闭响应很好,但它并不能解决 OP 的问题,即为失败的响应提供成功。
    • @manojlds 我添加了一个Remove-Variable,以防它在分配时未被取消。
    • @AndyArismendi -- 也感谢您的反馈。我也尝试了您的解决方案,它有效!
    • @Keith 没有问题,我将它更新为我会做的完整方式。
    • 这帮助我解决了另一个问题。非常感谢! +1
    【解决方案2】:

    这是因为WebRequest 会在尝试失败时引发异常,而$response 在您获得503404 等的情况下并没有真正设置。当您获得成功时,响应是设置为响应(状态码为 OK),但如果下一个服务器引发 404,例如,响应仍将是 OK 状态,因为 WebRequest 仅引发异常并且不为 $response 分配任何内容。您可能希望trap(或try catch)异常并在那里处理成功或失败,或者在循环的每次迭代中将$response设置为null:

    foreach($server in $serverlist){
    $response=$null
    
    ...
    

    另外,不要使用$_作为迭代变量,它是自动变量,在这里使用它不是很好的形式。

    请注意,您写的内容也可能会占用系统资源,(对我来说它挂了一次),所以适当地处理掉响应。 $response = $null 可能就足够了,但您可能仍需要在循环结束时正确关闭响应。

    【讨论】:

    • manojlds -- 感谢您的反馈。非常有用,$response=$null 完美运行!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多