0

I need a way to determine from a PS script if any web page is up or down, regardless of whether it first prompts for credentials. Even if the page requires that java is installedd or whatever other reason. The goal here is to determine that the page is there and it shouldn't matter whether it works properly or if it can be displayed. After all is said and done it should just tell me that site/page is UP or DOWN after executing the script with .\sitecheck.ps1 'https://trac.edgewall.org/login'

It'd also be nice if we could print why the page is down (like when you get a 401 error) and print the error message and status code (integer).

I'm trying to work off of this script which obviously doesn't work properly because I'm trying to find a solution:

# First we create the request.
$url = $args[0]
$HTTP_Request = [System.Net.WebRequest]::Create($url)

# We then get a response from the site.

$HTTP_Response = $HTTP_Request.GetResponse()

# We then get the HTTP code as an integer.
$HTTP_Status = [int]$HTTP_Response.StatusCode

If ($HTTP_Status -eq 200) {
    Write-Host "Site is OK!"
}
Else {
    Write-Host "The Site may be down, please check!"
}

# Finally, we clean up the http request by closing it.
If ($HTTP_Response -eq $null) { } Else { $HTTP_Response.Close()}

Someone responded with this answer to a similar question on this site:

"If the URL needs credentials, you need to add $HTTP_Request.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials. You need a Try..Catch around the $HTTP_Response = $HTTP_Request.GetResponse() line, and if that fails, $HTTP_Response will be null and so can't be closed because it's already null - like when you get a (404) Not Found, you will have no response and error will be You cannot call a method on a null-valued expression if you try to do .Close() on it."

Unfortunately I don't exactly know how to do that. Currently I'm getting the error below. Most of the actual error message is accurate since I haven't entered the correct credentials hence a 401 error code:

Exception calling "GetResponse" with "0" argument(s): "The remote server returned an error: (401) Unauthorized." At C:\Users\test\sitecheck.ps1:11 char:1 + $HTTP_Response = $HTTP_Request.GetResponse() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : WebException

yorkman
  • 119
  • 2
  • 16
  • You will only receive a 200 after login. Don't expect a 200 if you haven't login. But you can check if http://svn.edgewall.com is up. That I believe is the service that provides the login – Francesco Mantovani Dec 05 '19 at 21:44

1 Answers1

2

Don't expect to receive a 200 because you haven't accessed the page yet. Look, I can even click on the hyperlink you posted here on StackOverflow: before accessing the page the banner ask for login (I haven't accessed the page yet)

enter image description here

Then, because I don't have the credentials what I receive is a 401 Unauthorized.

So what I suggest you to do is to check if Apache Subversion is up and running instead:

# First we create the request.
$url = $args[0]
$HTTP_Request = [System.Net.WebRequest]::Create('https://svn.edgewall.org')

# We then get a response from the site.
$HTTP_Response = $HTTP_Request.GetResponse()

# We then get the HTTP code as an integer.
$HTTP_Status = [int]$HTTP_Response.StatusCode

If ($HTTP_Status -eq 200) {
    Write-Host "Site is OK!"
}
Else {
    Write-Host "The Site may be down, please check!"
}

# Finally, we clean up the http request by closing it.
If ($HTTP_Response -eq $null) { } Else { $HTTP_Response.Close()}

**

EDIT:

**

After your comment I've found a solution for you here:

Paste this code in a .ps1 file and execute it like in picture:

$url = $args[0]

try {
  $HttpWebResponse = $null;
  $HttpWebRequest = [System.Net.HttpWebRequest]::Create($url);
  $HttpWebResponse = $HttpWebRequest.GetResponse();
  if ($HttpWebResponse) {
    Write-Host -Object $HttpWebResponse.StatusCode.value__;
    Write-Host -Object $HttpWebResponse.GetResponseHeader("X-Detailed-Error");
  }
}
catch {
  $ErrorMessage = $Error[0].Exception.ErrorRecord.Exception.Message;
  $Matched = ($ErrorMessage -match '[0-9]{3}')
  if ($Matched) {
    Write-Host -Object ('HTTP status code was {0} ({1})' -f $HttpStatusCode, $matches.0);
  }
  else {
    Write-Host -Object $ErrorMessage;
  }

  $HttpWebResponse = $Error[0].Exception.InnerException.Response;
  $HttpWebResponse.GetResponseHeader("X-Detailed-Error");
}

enter image description here

This script will always print you the status code of the page. So now when you target https://trac.edgewall.org/login it will return you 401 which is the right status code.

You can see a list of all the error codes here: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Community
  • 1
  • 1
Francesco Mantovani
  • 10,216
  • 13
  • 73
  • 113
  • Yes I know that's part of the problem and you're right that I'd only receive 200 after login. But I don't know how to make it work regardless of whether I login or not. Sorry but I'd need to see the code because I don't know how to write it to make it work with any page. I've no idea what you mean by Apache Subversion and even if I did I probably wouldn't know how to code for it because I don't know how to program in PS. – yorkman Dec 06 '19 at 22:24
  • Also, the script should not only work with apache sites but any site. I think the script basically just needs to confirm that as long as the page responds with anything but internal errors then the site is up but if it can't connect or the page is down because of some internal error then it should say that the site is down. So how would I put in all these checks? – yorkman Dec 06 '19 at 22:30
  • Thank you Francesco. That works great! Good find. The only issue I'm having is how to exit the script with say a 0 for success (site produced the 200 code) and a 1 for a failure (website didn't produce a 200). It'd be great if you could help me with adding this. – yorkman Dec 09 '19 at 17:12
  • @yorkman, if you want to print "200 = OK" and "whatever = Not OK" you will end up having the same script that you posted at the beginning. That script in fact prints "Site is OK!" when it finds a 200 and "The Site may be down, please check!" for everything else. So you already have a code for that. Just substitute "Site is OK!" with a "0" and "The Site may be down, please check!" with a "1". Done. – Francesco Mantovani Dec 09 '19 at 20:59
  • No, I don't want to print a 200 = OK. I want to keep the script as is because it works well, the only thing is that I need to add to the script an exit with a 0 or a 1 depending on whether it determined if the site is up (200) or down. Another words I'd like the script to just exit with a Write-Host "0" if it was a 200 or write-host "1" if the site is not up. I'm just not sure where to put this. Do I just add to the end of the script something like: if $HttpStatusCode = 200 {Write-Host "0"} else {Write-Host "1"}? – yorkman Dec 10 '19 at 17:08
  • One issue with this script. When I run it in PS 3-4 times in a row, subsequent tries force me to wait about a min before it times out with: You cannot call a method on a null-valued expression. + $HttpWebResponse.GetResponseHeader("X-Detailed-Error"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull I have to close PS and restart it to check more url's. Do we need a Close() somewhere perhaps? – yorkman Dec 12 '19 at 16:05
  • I haven't faced this problem. Please open a new question with the code example, the error example, the URLs examples and steps to reproduce. Becaues this is another topic – Francesco Mantovani Dec 12 '19 at 20:15