# encoding: utf-8
# api: powershell
# title: Web Health Check
# description: Web-Health-Check.ps1 is a PowerShell script to monitor a website and automatically take remedial action if the site is not functioning properly. It works by retrieving a web page from a specified URL and checking the page for the presence of a specific piece of text.
# version: 0.1
# type: script
# license: CC0
# function: Send-SMTPmail
# x-poshcode-id: 1381
# x-archived: 2009-10-26T15:27:45
#
#
# PowerShell script to check if a specific web page contains a specific text string. If not, restart the VM
#
# By Roger Howorth
# Documentation and change log http://www.thehypervisor.com/web-health-check/
# Thanks to Pablote at stackoverflow
#
param( $VISRV,
$url,
$CHECKVM,
$testpattern)
#
# You can change the following defaults by altering the below settings:
#
if ( !$CHECKVM ) { $CHECKVM = "vm-name" }
if ( !$url ) { $url = "http://www.thehypervisor.com/web-health-check/" }
if ( !$testpattern ) { $testpattern = "©" }
$toFile = "c:\test.html"
#
# Set the SMTP Server address
$SMTPSRV = "my-smtp.example.com"
#
# Set the Email address to receive from
$EmailFrom = "my-server@example.com"
#
# Set the Email address to send the email to
$EmailTo = "me@example.com"
#### Detail Settings ####
# Set the username of the account with permissions to access the VI Server
# for event logs and service details - you will be asked for the same username and password
# only the first time this runs after setting the below username.
# If it is left blank it will use the credentials of the user who runs the script
$SetUsername = "administrator"
#
# Set the location to store the credentials in a secure manner
$CredFile = "c:\mycred.crd"
#######################################
# Start of script
#######################################
if ($VISRV -eq ""){
Write-Host
Write-Host "Please specify a VI Server name eg...."
Write-Host " powershell.exe webserv-healthcheck.ps1 MYVISERVER"
Write-Host
Write-Host
exit
}
function Send-SMTPmail($to, $from, $subject, $smtpserver, $body) {
$mailer = new-object Net.Mail.SMTPclient($smtpserver)
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
$msg.IsBodyHTML = $true
$mailer.send($msg)
}
function Find-Username ($username){
if ($username -ne $null)
{
$root = [ADSI]""
$filter = ("(&(objectCategory=user)(samAccountName=$Username))")
$ds = new-object system.DirectoryServices.DirectorySearcher($root,$filter)
$ds.PageSize = 1000
$ds.FindOne()
}
}
Function Set-Cred ($File) {
$Credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content $File
}
Function Get-Cred ($User,$File) {
$password = Get-Content $File | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($user,$password)
$credential
}
If ($SetUsername -ne ""){
if ((Test-Path -Path $CredFile) -eq $false) {
Set-Cred $CredFile
}
$creds = Get-Cred $SetUsername $CredFile
}
Add-PSSnapin VMware.VimAutomation.Core
$VIServer = Connect-VIServer $VISRV
If ($VIServer.IsConnected -ne $true){
# Fix for scheduled tasks not running.
$USER = $env:username
$APPPATH = "C:\Documents and Settings\" + $USER + "\Application Data"
#SET THE APPDATA ENVIRONMENT WHEN NEEDED
if ($env:appdata -eq $null -or $env:appdata -eq 0)
{
$env:appdata = $APPPATH
}
$VIServer = Connect-VIServer $VISRV
If ($VIServer.IsConnected -ne $true){
send-SMTPmail -to $EmailTo -from $EmailFrom -subject "ERROR: $VISRV Daily Report" -smtpserver $SMTPSRV -body "The Connect-VISERVER Cmdlet did not work, please check you VI Server."
exit
}
}
#
# Download a file from the web
#.Description
# Uses System.Net.Webclient (not the browser) to download data
# from the web.
#.Parameter self
# Uses the default credentials when downloading that page (for downloading intranet pages)
#.Parameter credential
# The credentials to use to download the web data
#.Parameter url
# The page to download (e.g. www.msn.com)
#.Parameter toFile
# The file to save the web data to
#.Parameter bytes
# Download the data as bytes
$webclient = New-Object Net.Webclient
if ($credential) {
$webClient.Credential = $credential
}
if ($self) {
$webClient.UseDefaultCredentials = $true
}
if ($toFile) {
if (-not "$toFile".Contains(":")) {
$toFile = Join-Path $pwd $toFile
}
$webClient.DownloadFile($url, $toFile)
} else {
if ($bytes) {
$webClient.DownloadData($url)
} else {
$webClient.DownloadString($url)
}
}
$testok = Select-String -pattern $testpattern -Path $toFile
if ( $testok -eq $null ) {
Write-host "$testpattern not found at $url"
#Test if VMtools OK
$FullVM = Get-View -ViewType VirtualMachine -Filter @{"Name" = $CHECKVM}
$NoTools = $FullVM | Where {$_.Runtime.Powerstate -eq “poweredOn” -And ($_.Guest.toolsStatus -eq “toolsNotInstalled” -Or $_.Guest.ToolsStatus -eq “toolsNotRunning”) } | Select Name, @{N=”Status”; E={$_.Guest.ToolsStatus}}
if ( $NoTools ) {
Write-host "VMtools not running in $CHECKVM so forcing reboot using power switch."
Stop-VM $CHECKVM -Confirm:$false
# Sleep not needed as PowerShell waits for command to complete
Start-VM $CHECKVM
send-SMTPmail -to $EmailTo -from $EmailFrom -subject "Warning: $CHECKVM Healthcheck Report" -smtpserver $SMTPSRV -body "The webserv-healthcheck PowerShell script did not find $testpattern at $url.<br /><br />VMtools was not running so $CHECKVM brutally rebooted. Please check the website to ensure all is well."
} else {
Write-host "VMtools OK so gracefully restarting $CHECKVM."
Restart-VMGuest $CHECKVM
send-SMTPmail -to $EmailTo -from $EmailFrom -subject "Warning: $CHECKVM Healthcheck Report" -smtpserver $SMTPSRV -body "The webserv-healthcheck PowerShell script did not find $testpattern at $url.<br /><br />VMtools was running so $CHECKVM restarted gracefully. Please check the website to ensure all is well."
}
}
# else All is well so do nothing much
else { Write-host "$testpattern present at $url" }
# Disconnect-VIServer -Confirm:$False