WebRequest random results using PowerShell

I have the following snippet below my script that uses WebRequest to send a list of web application and application servers, and I get random results based on the order in which the good / bad servers are listed in the server list.

For example, if bad servers (where I return the code 404 or 503) are listed first in the list, then my script seems to report accurately. However, if a good server (which returns status = "OK"), then my results are first listed 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 an example server list:

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

And here is the "exact" output of cmd 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 reorder the list of servers, where the first server is listed first, for example:

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

I get inaccurate results when server 1 and server 2 are 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 do I get mixed results depending on how the servers are listed?

Thanks in advance!

+3
source share
2 answers

This is because WebRequest throws an exception on unsuccessful attempts, and $response does not really get set when you get 503 , 404 , etc. When you succeed, the answer is set, well, the answer (with the status code is ok), but if the next server raises 404, let's say the answer will still remain in the OK state, because WebRequest raises an exception and doesn’t assign anything to $ response . You may want to trap (or try catch ) an exception and handle success or failure there or set $response to null in each iteration of the loop:

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

Also, do not use $_ as an iteration variable, it is an automatic variable and is not a good form using it here.

Please note that what you wrote can also use system resources (it once hung for me), so postpone the answer accordingly. $response = $null may be enough, but you still have to close the answer correctly at the end of the loop.

+3
source

You may need to close the connection:

 $response.Close() 

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

I would write this as follows:

 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 } } } 
+9
source

Source: https://habr.com/ru/post/1500317/


All Articles