If you are using multiple web servers and some more advanced DNS configuration like e.g. Round-Robin (and other) to load balance and possibly even GEO divide traffic to those web servers while those are all hosting the same web site you might as well want to monitor if this is all working as expected.
The challenge in this case is – your monitoring system might get just a single IP that might even change every now and then back from DNS when it requests it from DNS. So you would end up needing to use the target IP addresses of the individual web servers instead. But those expect you that your request for the web site goes through the domain name, since the servers aren’t supposed to answer on direct host-name / IP address requests or another web-site might be hosted there.
In order to accomplish this – I wrote the script below. It allows you to request a website directly from an IP address while injecting the DNS host in the header section of the Invoke-WebRequest (IWR) in PowerShell.
If you need to target a specific target site you can inject of just the IP address additional information, for example:
- Standard parameters
- -DomainName “google.com” -IP “8.8.8.8”
- this will request the web-root / default page
- -DomainName “google.com” -IP “8.8.8.8”
- Sub-Page parameters
- -DomainName “google.com” -IP “8.8.8.8/monitoring.html”
- this will request the content of /monitoring.html on the IP 8.8.8.8 with the DNS name google.com
- -DomainName “google.com” -IP “8.8.8.8/monitoring.html”
PS: Please be aware – the above will not work – 8.8.8.8 is a Google-DNS server and not one of their web-servers. The above is only an example to show what is possible.
The below script output was optimized to be used in PRTG.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | param( [string] $DomainName = "", [string] $IP = "", [string] $KeyWord = " ", [int] $MinimumResponseSizeInByte = 1, [bool] $useHTTPS = $true ) add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy If ($useHTTPS -eq $true) { $Prefix = "https://" } Else { $Prefix = "http://" } $IWRResponse = ""; $IWRError = 0; $IWRErrorMessage = ""; $IWRResponse = Try { Invoke-WebRequest -Uri "$Prefix$IP" -Headers @{Host="$DomainName"} -ErrorAction Stop } Catch { $IWRError = $_.Exception.GetHashCode() If ($IWRError -eq 0) { $IWRError = 1 } $IWRErrorMessage = $_.Exception.Message } Try { $IWRResponse = $IWRResponse.ToString() } Catch {} $KeyWordFound = 0 Try { If ($IWRResponse.Contains($KeyWord)) { $KeyWordFound = 1 } } Catch {} $ResponseSufficient = 0 Try { If ($IWRResponse -gt $MinimumResponseSizeInByte) { $ResponseSufficient = 1 } } Catch {} $XML = "<prtg> <result> <channel>Check result</channel> <value>$IWRError</value> <LimitMode>1</LimitMode> <LimitMinError>0</LimitMinError> <LimitMaxError>0</LimitMaxError> <LimitErrorMsg>$IWRErrorMessage</LimitErrorMsg> </result> <result> <channel>Keyword found</channel> <value>$KeyWordFound</value> <LimitMode>1</LimitMode> <LimitMinError>1</LimitMinError> <LimitErrorMsg>Keyword was not found in response</LimitErrorMsg> </result> <result> <channel>Response Length</channel> <value>" + $IWRResponse.Length + "</value> <VolumeSize>Byte</VolumeSize> <NotifyChanged>1</NotifyChanged> </result> <result> <channel>Reponse Length sufficient</channel> <value>$ResponseSufficient</value> <LimitMode>1</LimitMode> <LimitMinError>1</LimitMinError> <LimitErrorMsg>Response size not sufficient</LimitErrorMsg> </result> </prtg>" Function WriteXmlToScreen ([xml]$xml) #just to make it clean XML code... { $StringWriter = New-Object System.IO.StringWriter; $XmlWriter = New-Object System.Xml.XmlTextWriter $StringWriter; $XmlWriter.Formatting = "indented"; $xml.WriteTo($XmlWriter); $XmlWriter.Flush(); $StringWriter.Flush(); Write-Output $StringWriter.ToString(); } WriteXmlToScreen "$XML" |