Two scripts in two days? Am I out of my mind?! Yes, no, yes, maybe… Yesterday’s SharePoint Diagnostic Log Monitor + Email Alert PowerShell Script worked so well that I was getting bombarded with too many emails! Yes, they were all critical as far as SharePoint was concerned and I was able to resolve a great majority of them. But some of them just seemed to be inherent to SharePoint and didn’t really affect the end-user experience therefore the criticality of these alerts became less of a priority.
So today I went about bootlegging a different type of monitoring system that would be more indicative of an end user’s experience with the site. With this script, I wanted to connect to the SharePoint sites and see if I get a valid response or valid content back from the server. If I can’t download the page with the System.Net.WebClient.DownloadString() method, then it’ll throw an exception and that’s how I’ll know whether the site is accessible by an end-user or not. If it’s not accessible, then an email will be generated and sent to me. Pretty cool eh?
This is extra useful when used in an environment with load balanced front ends and you want to know exactly which server is having issues. If you want to use this script in this manner, then make sure you create the scheduled tasks for each server.
Sample Email Output:
URL: https://url1
Server: ALW01
Exception: System.Net.WebException: The remote server returned an error: (500) Internal Server Error. at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request) at System.Net.WebClient.DownloadString(Uri address) at DownloadString(Object , Object[] ) at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments)
===================================
URL: https://url2
Server: ALW02
Exception: System.Net.WebException: The remote server returned an error: (500) Internal Server Error. at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request) at System.Net.WebClient.DownloadString(Uri address) at DownloadString(Object , Object[] ) at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments)
===================================
You may need to highlight and copy the script below into notepad to be able to read all of the characters that were chopped off by this blog’s layout.
############# Start Variables ################ $urls = @("https://url1", "https://url2") $emailFrom = "SharePoint.Automation@email.com" $emailTo = @("email1","email2") $subject = "SharePoint Down!" $smtpserver = "SMTPServer" $server = "ALW01" # When used in a load-balanced environment where # each server has host entries to itself, this can help you # identify which server is having issues. ############# End Variables ################## [System.Reflection.Assembly]::LoadWithPartialName("System.Net") $wc = New-Object System.Net.WebClient $wc.UseDefaultCredentials = $true $body = "" foreach($url in $urls) { try { $page = $wc.DownloadString($url); if($page.Contains("An unexpected error has occurred.") -or $page.Contains("Cannot connect to the configuration database")) { $body += "<b>URL:</b> " + $url + "<br><br>" $body += "<b>Server:</b> " + $server + "<br><br>" $body += "<b>Exception:</b> " + "Getting a nasty error. Please help me." + "<br><br>" $body += "===================================<br><br>" } } catch [Exception] { $body += "<b>URL:</b> " + $url + "<br><br>" $body += "<b>Server:</b> " + $server + "<br><br>" $body += "<b>Exception:</b> " + $_.Exception + "<br><br>" $body += "===================================<br><br>" } } if($body -ne "") { Send-MailMessage -To $emailTo -Subject $subject -Body $body -SmtpServer $smtpserver -From $emailFrom -BodyAsHtml }
It’s becomming a bit of a diagnostic studio this 😉
I’m dreaming of a dashboard where this all comes together – in SP of course – Health rules are cool but they should be part of a larger dashboard and alerting system … Sort of a Sharepoint Systems Center for .. welll … why not .. Free. But as I said it is a dream …
That’s not a bad idea, it’d be pretty easy to write some outputs to a SharePoint list and then create some visuals based off of that list data. Maybe next week. 🙂
This looks really cool, thanks for the share! I am running into this problem when running the script though:
“A positional parameter cannot be found that accepts argument ‘=’ . At C:\….\monitor.ps1:13 char 17 + $wc = New-Object <<<< System.Net.WebClient $wc.UseDefaultCredentials = $true + CategoryInfo : InvalidArgument: (:) [New-Object], ParameterBindingException"
I am still learning powershell; any advice on this one? Thanks!
Hey Philip, I noticed that $wc.UseDefaultCredentials was on the same line as the previous so that may have caused the error. I’ve moved it down 1-line, hope that helps.
Hi Henry,
I am trying to use your script, but I get an exception:
Exception: System.Net.WebException: The remote server returned an error: (401) Unauthorized. at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request) at System.Net.WebClient.DownloadString(Uri address) at DownloadString(Object , Object[] ) at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments)
I have also tried to change the script and use this:
$cred = New-Object System.Net.NetworkCredential(“myusername”,”mypassword”,”mydomain”)
$wc.Credentials = $cred
#$wc.UseDefaultCredentials = $true
but I get the same exception. I am trying to run this on the WFE server. Any ideas?
Hey Sid, perhaps it may be related to the loopbackcheck needing to be disabled?
Very nice article. I definitely appreciate this website.
Stick with it!