Random WebRequest results with PowerShell

♀尐吖头ヾ 提交于 2019-12-23 16:43:48

问题


I have the following snippet below from my script that's using a WebRequest to ping a list of web/app servers and I'm getting random results based on the order the good/bad servers are listed in the server list.

For example, if the bad servers (where I get back a code of 404 or 503) are listed first in the list then my script seems to report accurately. However, if the good server (which gets back a status = "OK") is listed first then my results are inaccurate.

Here is my code snippet:

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

Here is the example server list:

server1 (reports back a 404)
server2 (reports back a 503)
server3 (gets a status = "OK")

And here is the "accurate" cmd output when I run the script:

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.

Now when I re-order the server list where the good server is listed first, like so:

server3 (gets a status = "OK")    
server1 (reports back a 404)
server2 (reports back a 503)

I get inaccurate results where server 1 and server 2 are getting reported as 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.

Why am I getting mixed results based on how the servers are listed?

Thanks in advance!


回答1:


It is because the the WebRequest raises exception on unsuccessful attempts and $response doesn't really get set in the cases where you get 503, 404 etc. When you do get a success, response is set to, well, the response ( with status code being OK), but if the next server raises a 404, say, response would still be the OK state because the WebRequest only raises an exception and doesn't assign anything to $response. You might want to trap (or try catch) the exception and handle the success or failure there or set $response to null in each iteration of the loop:

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

...

Also, don't use $_ as the iteration variable, it is automatic variable and is not good form using it here.

Note that what yo have written also might use up system resources, ( it hung once for me), so dispose off the response appropriately. $response = $null might be enough, but you may still have to close the response properly at end of loop.




回答2:


You might need to close your connection:

$response.Close()

http://msdn.microsoft.com/en-us/library/system.net.webresponse.close(v=vs.90).aspx

I would write it like this:

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


来源:https://stackoverflow.com/questions/9090849/random-webrequest-results-with-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!