Having a little bit of trouble with this segment of code.
I’ve got a script that I’m using to do the following:
remove an azure webapp from the traffic manager
check for the number of requests for that webapp every 60 seconds until requests drop below 300
reboot the web app
get the URL response of the web app every 60 seconds while it returns a status code not equal to 200
re-add the web app to the TM after the URL Response status code is 200 3 time in a row.
I’m having trouble with the 3rd step, where the GetResponse times out and hangs even after the URL is back up and responding.
I’ve marked in the code 2 spots where I’ve tried a couple things I found in searching for a solution but so far nothing has worked.
$url = "http://webapp.azurewebsites.net"
Function GetURL {
$webRequest = [net.WebRequest]::Create($url)
$webRequest.Timeout = [System.Threading.Timeout]::Infinite #Read this on a blog but it didn't work
$Response = $webRequest.GetResponse()
$statusCode = [int]$Response.StatusCode
$Response.close #Read this on a blog but it didn't work either
Return $statusCode
} #Function to get URL Status
###Check the site every 60 seconds until it returns a status code of 200###
While ($statusCode -ne 200) {
Write-verbose "The webpage $url has not come back up.
The current Status Code is $statusCode. Waiting 60 seconds and trying again"
#sleep -Seconds 60
. GetURL
}
Function VerifyUp {
Param ($statusCode)
###Check the site every 60 seconds until it returns a status code of 200###
While ($statusCode -ne 200) {
Write-Host "The webpage $url has not come back up.
The current Status Code is $statusCode. Waiting 60 seconds and trying again"
#sleep -Seconds 60
. GetURL
}
While ($statusCode -eq 200) {
$i = 1
sleep -Seconds 60
. GetURL
$i++
}
for ($statusCode -ne 200) {
VerifyUp
}
for ($i -eq 3) {
Write-host "The Webpage $url has been up for 3 minutes. Readding $app to TM."
break
}
}
###### Start Script ##################
ARMLogin
TMRemove
. Requests
Reboot -RequestCount $RequestCount
. GetURL
VerifyUP -statusCode $statusCode
TMAdd
Unfortunately, this is more a lower-level .NET thing than PowerShell per se. The only workaround I can think of is to try a ping or something instead, since ping is designed more with the idea of failure in mind. Once you get a ping, try the HTTP request. That HttpRequest gets all tied up with DNS caching and all kinds of crazy in this kind of situation.
I’m not a huge fan of the logic approach you’ve taken - having GetURL recursively call itself over and over is not a stellar idea, as you’re loading up the stack heap fairly unnecessarily. If you’re going to do this in a loop like this, it’d make more sense to make it self-contained and synchronous:
Do {
create the request
try the request
set a pass/fail flag or whatever
delete the request
} Until # flag passes
What you’re doing now is holding a crapload of Request objects in memory until it finally works, at which point the CLR has to unwind all the recursive calls and garbage-collect everything. It wouldn’t shock me if you found that was your problem.
unfortunately ping isn’t an option here because azure blocks ICMP.
I believe I’ve resolved this by using invoke-webrequest instead but also found that at least half the problem is our dev environment. still times out 90% of the time but when I run it against UAT and Prod it works everytime.
I also used your logic and came up with this which worked well in our UAT environment.
Also completely cut out the GETURL Function and cleaned up the VerifyUp a bit (I think at least).
DO {
$statuscode = (Invoke-WebRequest -Uri $url -Method Get).statuscode
Try{
$StatusChk = $statuscode -ne 200
}
Catch {
Write-Host "The webpage $url has not come back up. The current Status Code is $statusCode. Waiting 60 seconds and trying again" #Remove before use in PROD
$statusCode = $null
sleep -Seconds 60
if ($i -gt 0) {$i--}
else {}
}
Sleep -Seconds 60
$i++
Write-Host "$URL has been up for $i minute(s)" #Remove before use in PROD
} Until ($statusCode -eq 200 -and $i -eq 3)
for ($i -eq 3) {
Write-host "The Webpage $url has been up for 3 minutes. Readding $app to TM." #Remove before use in PROD
break
}