-
-
Save kiwi-cam/076acb39aa2dadc28ce873c5ecbf6df5 to your computer and use it in GitHub Desktop.
| <# | |
| .SYNOPSIS | |
| Tests the connection to the supplied host or IP and reports back on changes to its status. | |
| .DESCRIPTION | |
| This script will check the connection to the supplied hostname or IP address every 5 second's to | |
| monitor its status. If the status changes, a message is recorded, the Eventlog is update (optional), and an email is sent | |
| to a supplied email address (optional). | |
| If a TCPPort parameter is suppied the script will attempt to connect to this port. Otherwise a simple ICMP Ping is used. | |
| To end monitoring, press CTRL-C | |
| .PARAMETER RemoteHost | |
| A String specifying host or IP address you'd like to monitor. You can also specify a TCPport here using host:port syntax. | |
| .PARAMETER EmailAddress | |
| A String specifying the email address to notify of status changes. If not supplied, or empty, emails are not sent. | |
| In order to use this, first edit the script to supply a valid SMTP server, port, and from address. | |
| .PARAMETER EventLog | |
| If true, status changes are also recorded in the Windows Application EventLog. | |
| In order to use this, first run this command at an Administrator Powershell Prompt: | |
| > New-EventLog -LogName Application -Source MonitoringConnection | |
| .PARAMETER NoNotify | |
| If true, status changes will not show up as Windows notifications. | |
| .PARAMETER Silent | |
| If true, the script will not create any beeps as the status changes. | |
| .PARAMETER Pause | |
| The number of seconds to wait between tests. Default 5 seconds. | |
| .PARAMETER TCPPort | |
| If supplied, the script will test a connection to the supplied TCP port. If not supplied a ICMP Ping test is used. | |
| .PARAMETER Namespace | |
| If supplied, the script will run a query on this WMI Namespace on the supplied Host | |
| .PARAMETER Class | |
| If supplied, the script will run a query on this WMI Class of the supplied namespace on the supplied Host | |
| .PARAMETER WMIProperty | |
| The WMI Property to monitor. Any changes in value will be reported | |
| .PARAMETER WMIFilter | |
| The Filter used to identify the correct result in the WMI query. | |
| .EXAMPLE | |
| ./Start-Monitoring google.com | |
| .EXAMPLE | |
| ./Start-Monitoring -RemoteHost 8.8.8.8 -EmailAddress [email protected] | |
| .EXAMPLE | |
| ./Start-Monitoring -RemoteHost 8.8.8.8 -EmailAddress [email protected] -EventLog $true | |
| .EXAMPLE | |
| ./Start-Monitoring -RemoteHost 8.8.8.8 -TCPPort 53 | |
| .EXAMPLE | |
| ./Start-Monitoring -RemoteHost 8.8.8.8:53 | |
| .EXAMPLE | |
| ./Start-Monitoring -RemoteHost @("www.google.com:443","8.8.8.8:53") | |
| .EXAMPLE | |
| ./Start-Monitoring -RemoteHost WebServer1 -Namespace "root\cimv2" -Class Win32_PerfRawData_APPPOOLCountersProvider_APPPOOLWAS -WMIProperty CurrentApplicationPoolState -WMIFilter "{$_.Name -like 'SLSS'}" | |
| .NOTES | |
| Version: 1.7 | |
| Author: Cameron McConnochie | |
| Creation Date: 12 June 2020 | |
| Purpose/Change: Added support for host:port format to allow multiple host and port combos to monitor | |
| Version: 1.6 | |
| Author: Cameron McConnochie | |
| Creation Date: 16 Sept 2019 | |
| Purpose/Change: Added support for an array of hosts to monitor | |
| Version: 1.5 | |
| Author: Cameron McConnochie | |
| Creation Date: 17 June 2019 | |
| Purpose/Change: Added Core compatibility | |
| Version: 1.4 | |
| Author: Cameron McConnochie | |
| Creation Date: 22 March 2019 | |
| Purpose/Change: Added WMI monitoring | |
| Version: 1.3 | |
| Author: Cameron McConnochie | |
| Creation Date: 26 Feb 2019 | |
| Purpose/Change: Added Validation of the supplied hostname/IP | |
| Version: 1.2 | |
| Author: Cameron McConnochie | |
| Creation Date: 8 Oct 2018 | |
| Purpose/Change: Added Notifications | |
| Version: 1.1 | |
| Author: Cameron McConnochie | |
| Creation Date: 10 Aug 2018 | |
| Purpose/Change: Added TCP Port monitoring | |
| Version: 1.0 | |
| Author: Cameron McConnochie | |
| Creation Date: 26 July 2018 | |
| Purpose/Change: Initial script development | |
| #> | |
| [CmdletBinding()] | |
| Param( | |
| [Parameter(Mandatory=$True,Position=1)] | |
| [ValidateScript({ | |
| if ($_ -like "*:*") { | |
| if($_.Split(":")[0] -As [IPAddress] -and $_.Split(":")[1] -As [Int]){ | |
| $True | |
| }else { | |
| if(([System.Net.Dns]::GetHostEntry($_.Split(":")[0])) -and $_.Split(":")[1] -As [Int]){ | |
| $True | |
| }else{ | |
| Throw "$($_) is not a valid IP or hostname. Try again." | |
| } | |
| } | |
| } elseif($_ -As [IPAddress]){ | |
| $True | |
| } else { | |
| if([System.Net.Dns]::GetHostEntry($_)){ | |
| $True | |
| }else{ | |
| Throw "$($_) is not a valid IP or hostname. Try again." | |
| } | |
| } | |
| })] | |
| [string[]]$RemoteHost, | |
| [Parameter(Mandatory=$False)] | |
| [ValidateScript({ | |
| if($_ -Match "\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b" -or $_ -eq $null){ | |
| $True | |
| } else { | |
| Throw "$($_) is not a valid email address. Try again, or remove this parameter to skip email alerts." | |
| } | |
| })] | |
| [mailaddress]$EmailAddress = $null, | |
| [Parameter(Mandatory=$False)] | |
| [switch]$EventLog, | |
| [Parameter(Mandatory=$False)] | |
| [switch]$NoNotify, | |
| [Parameter(Mandatory=$False)] | |
| [switch]$Silent, | |
| [Parameter(Mandatory=$False)] | |
| [int32]$Pause = 5, | |
| [Parameter(Mandatory=$False, | |
| ParameterSetName = 'Port')] | |
| [int32]$TCPPort, | |
| [Parameter(Mandatory=$true, | |
| ParameterSetName = 'WMI')] | |
| [string]$Namespace, | |
| [Parameter(Mandatory=$true, | |
| ParameterSetName = 'WMI')] | |
| [string]$Class, | |
| [Parameter(Mandatory=$true, | |
| ParameterSetName = 'WMI')] | |
| [string]$WMIProperty, | |
| [Parameter(Mandatory=$False, | |
| ParameterSetName = 'WMI')] | |
| [scriptblock]$WMIFilter | |
| ) | |
| ###### | |
| # | |
| # SMTP Mail Server Settings, edit these values in order to use email alerts | |
| # | |
| ###### | |
| $SMTPServer = "smtp.someopenmailserver.com" | |
| $SMTPPort = 25 | |
| $SMTPFromAddress = "[email protected]" | |
| #Script Starts here... | |
| $RemoteHostStatus = 99 #1 = online, 2 = offline, 3 = undefined | |
| [string]$WMIPrevious = "99" #Used to identify changes | |
| #Error Check | |
| #Confirm EventLog Source is configured if required | |
| if($EventLog){ | |
| try{ | |
| [System.Diagnostics.EventLog]::SourceExists("MonitoringConnection") | Out-Null | |
| }catch{ | |
| throw "In order to record to the EventLog, first run this command at an Administrator Powershell Prompt: `n` | |
| > New-EventLog -LogName Application -Source MonitoringConnection" | |
| } | |
| } | |
| if($EmailAddress -ne $null){ | |
| if(-not ((Test-NetConnection -ComputerName $SMTPServer -Port $SMTPPort).TcpTestSucceeded)){ | |
| throw "Unable to connect to the specified SMTP server. Confirm the settings in this script and retry `n` | |
| $($SMTPServer) unreachable on port $($SMTPPort)" | |
| } | |
| #Clear the progress bar | |
| Write-Progress -Activity "Test-NetConnection - $($SMTPServer):$($SMTPPort)" -Completed | |
| } | |
| #Deal with an Array first | |
| If($RemoteHost.Count -gt 1){ | |
| Write-Host "Monitoring the connection status of $($RemoteHost)" -ForegroundColor Blue | |
| Write-Host " press CTRL-C to stop" -ForegroundColor Blue | |
| Write-Host "" | |
| Write-Progress -Activity "Monitoring connection status of $($RemoteHost)" -id $PID -Status "..." | |
| # Change the default behavior of CTRL-C so that the script can intercept and use it versus just terminating the script. | |
| [Console]::TreatControlCAsInput = $True | |
| # Sleep for 1 second and then flush the key buffer so any previously pressed keys are discarded and the loop can monitor for the use of | |
| # CTRL-C. The sleep command ensures the buffer flushes correctly. | |
| Start-Sleep -Seconds 1 | |
| $Host.UI.RawUI.FlushInputBuffer() | |
| $Jobs = @() | |
| $ScriptPath = $MyInvocation.MyCommand.Definition | |
| #Shared | |
| $ScriptArgs = @{ | |
| EventLog = $EventLog | |
| NoNotify = $NoNotify | |
| Silent = $Silent | |
| Pause = $Pause | |
| } | |
| if($EmailAddress){$ScriptArgs.Add("EmailAddress", $EmailAddress)} | |
| #Unique | |
| If($TCPPort){ | |
| # Port Query | |
| if($TCPPort){$ScriptArgs.Add("TCPPort", $TCPPort)} | |
| }elseIf($Namespace){ | |
| # WMI Query | |
| if($Namespace){$ScriptArgs.Add("Namespace",$Namespace)} | |
| if($Class){$ScriptArgs.Add("Class",$Class)} | |
| if($WMIProperty){$ScriptArgs.Add("WMIProperty",$WMIProperty)} | |
| if($WMIFilter){$ScriptArgs.Add("WMIFilter",$WMIFilter)} | |
| }else{ | |
| # Ping Query | |
| } | |
| $RemoteHost | ForEach-Object { | |
| $Jobs += Start-Job -Name "Monitor-$($_)" -ScriptBlock {param($ScriptPath, $RemoteHost, $ScriptArgs) | |
| $ScriptArgs.Add("RemoteHost",$RemoteHost) | |
| &$ScriptPath @ScriptArgs | |
| } -ArgumentList @($ScriptPath, $_, $ScriptArgs) | |
| } | |
| While ((Get-Job | Where-Object {$_.Name -like "Monitor-*"}).Count -gt 0) { | |
| Receive-Job -Job $Jobs | |
| # If a key was pressed during the loop execution, check to see if it was CTRL-C (aka "3"), and if so exit the script after clearing | |
| # out any running jobs and setting CTRL-C back to normal. | |
| If ($Host.UI.RawUI.KeyAvailable -and ($Key = $Host.UI.RawUI.ReadKey("AllowCtrlC,NoEcho,IncludeKeyUp"))) { | |
| If ([Int]$Key.Character -eq 3) { | |
| Write-Host "" | |
| Write-Warning "CTRL-C was used - Shutting down any running jobs before exiting." | |
| Get-Job | Where-Object {$_.Name -like "Monitor-*"} | Remove-Job -Force -Confirm:$False | |
| [Console]::TreatControlCAsInput = $False | |
| Return | |
| } | |
| # Flush the key buffer again for the next loop. | |
| $Host.UI.RawUI.FlushInputBuffer() | |
| } | |
| #Add a small pause to ease CPU load | |
| Start-Sleep -Milliseconds 200 | |
| } | |
| } | |
| #Extract TCP Port if encoded in Host | |
| If ($RemoteHost -like "*:*") { | |
| $TCPPort = [Int32]$RemoteHost.Split(":")[1] | |
| $RemoteHost = $RemoteHost.Split(":")[0] | |
| } | |
| If($Host.Name -ne "ServerRemoteHost"){ | |
| Write-Host "Monitoring the connection status of $($RemoteHost)" -ForegroundColor Blue | |
| Write-Host " press CTRL-C to stop" -ForegroundColor Blue | |
| Write-Host "" | |
| } | |
| #Setup Nofitications | |
| If (-not $NoNotify){ | |
| $AppId = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe' | |
| $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | |
| $null = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | |
| $WarningLogo = "$env:TEMP\ToastWarningLogo.png" | |
| if (-not (Test-Path $WarningLogo)){ | |
| $Logo = "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" | |
| [byte[]]$Bytes = [convert]::FromBase64String($Logo) | |
| [System.IO.File]::WriteAllBytes($WarningLogo,$Bytes) | |
| } | |
| $InfoLogo = "$env:TEMP\ToastInfoLogo.png" | |
| if (-not (Test-Path $InfoLogo)){ | |
| $Logo = "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" | |
| [byte[]]$Bytes = [convert]::FromBase64String($Logo) | |
| [System.IO.File]::WriteAllBytes($InfoLogo,$Bytes) | |
| } | |
| } | |
| While ($true){ | |
| If ($TCPPort){ | |
| #This test is used to reduce the timeout - thanks to Jan Doggen: https://superuser.com/questions/805621/test-network-ports-faster-with-powershell | |
| $tcpclient = new-Object system.Net.Sockets.TcpClient | |
| $iar = $tcpclient.BeginConnect($RemoteHost,$TCPPort,$null,$null) | |
| $wait = $iar.AsyncWaitHandle.WaitOne(2000,$false) | |
| if(!$wait) | |
| { | |
| # Close the connection and report timeout | |
| $tcpclient.Close() | |
| $Result = $null | |
| } | |
| else | |
| { | |
| # Close the connection and report the error if there is one | |
| $error.Clear() | |
| Try{ | |
| $tcpclient.EndConnect($iar) | out-Null | |
| }catch{} | |
| if(!$?){ | |
| $Result = $null | |
| }else{ | |
| $Result = "Success" | |
| } | |
| $tcpclient.Close() | |
| } | |
| $OKStatus = "listening on $($TCPPort)" | |
| $ErStatus = "not listening on $($TCPPort)" | |
| }elseif($WMIProperty){ | |
| if($Pause -lt 30){ | |
| Write-Host "A pause of only $($Pause) between WMI queries will strain the remote host. Adjusting to 30 seconds." | |
| $Pause = 30 | |
| } | |
| $WMIResult = Get-WmiObject -Namespace $Namespace -Class $Class -ComputerName $RemoteHost | |
| if($WMIFilter){ | |
| $WMIResult = $WMIResult.Where($WMIFilter) | |
| } | |
| if($WMIResult.Count -gt "1"){ | |
| throw "Multiple WMI results found, check you're using a valid filter." | |
| }elseif($WMIResult.Count -eq "0"){ | |
| $WMIResult = "NotFound" | |
| }else{ | |
| #If a single result found, update the result to its value | |
| $WMIResult = $WMIResult | Select-Object -ExpandProperty $WMIProperty | |
| } | |
| #Always return a Result of 1, just use the RemoteHostStatus variable to mark it as a different/a change. | |
| $Result = 1 | |
| if($WMIResult -ne $WMIPrevious){ | |
| #No change, Update history value to highlight change | |
| $RemoteHostStatus = 0 | |
| }else{ | |
| #No change, Update history value to highlight change | |
| $RemoteHostStatus = 1 | |
| } | |
| $WMIPrevious = $WMIResult | |
| $ErStatus = $OKStatus = "$($WMIProperty) has status $($WMIResult)" | |
| }else{ | |
| $Result = Test-Connection -Count 1 -ComputerName $RemoteHost -Quiet | |
| $OKStatus = "online" | |
| $ErStatus = "offline" | |
| } | |
| If($Result){ | |
| #Host is online/good | |
| If($RemoteHostStatus -ne 1){ | |
| #New Status | |
| Write-Host " $($RemoteHost) $($OKStatus) at $(Get-Date -Format G)" -ForegroundColor Green | |
| If($Host.Name -ne "ServerRemoteHost"){ $Host.PrivateData.ProgressBackgroundColor='DarkCyan' } | |
| Write-Progress -id $PID -Activity " Monitoring connection status of $($RemoteHost)" -Status (Get-Culture).TextInfo.ToTitleCase($OKStatus.ToLower()) | |
| If(-not $Silent){ | |
| [console]::beep(2000,300) | |
| } | |
| If(-not $NoNotify){ | |
| Write-Debug "Showing notification" | |
| $XmlString = @(" | |
| <toast duration = 'short'> | |
| <visual> | |
| <binding template='ToastGeneric'> | |
| <text>$($RemoteHost) $($OKStatus)</text> | |
| <text>$($RemoteHost) $($OKStatus) at $(Get-Date -Format G)</text> | |
| <image src='$InfoLogo' placement='appLogoOverride' hint-crop='circle' /> | |
| </binding> | |
| </visual> | |
| <audio src='ms-winsoundevent:Notification.Default' /> | |
| </toast> | |
| ") | |
| $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::new() | |
| $ToastXml.LoadXml($XmlString) | |
| $Toast = [Windows.UI.Notifications.ToastNotification]::new($ToastXml) | |
| [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).Show($Toast) | |
| } | |
| If($EmailAddress -ne $null){ | |
| $Message = "$($RemoteHost) $($OKStatus) at $(Get-Date -Format G)" | |
| Send-MailMessage -To $EmailAddress -Body $Message -BodyAsHtml -From $SMTPFromAddress -SmtpServer $SMTPServer -Port $SMTPPort -Subject "$($RemoteHost) $($OKStatus)" | |
| } | |
| If($EventLog){ | |
| Write-EventLog -LogName Application -Source MonitoringConnection -Message "$($RemoteHost) $($OKStatus)" -EventId 8000 -EntryType Information | |
| } | |
| $RemoteHostStatus = 1 | |
| } | |
| }else{ | |
| #Host is offline/changed | |
| If($RemoteHostStatus -ne 0){ | |
| #New Status | |
| Write-Host " $($RemoteHost) $($ErStatus) at $(Get-Date -Format G)" -ForegroundColor Red | |
| If($Host.Name -ne "ServerRemoteHost"){ $Host.PrivateData.ProgressBackgroundColor='Red' } | |
| Write-Progress -id $PID -Activity " Monitoring connection status of $($RemoteHost)" -Status (Get-Culture).TextInfo.ToTitleCase($ErStatus.ToLower()) | |
| If(-not $Silent){ | |
| [console]::beep(500,300) | |
| } | |
| If($EmailAddress -ne $null){ | |
| $Message = "$($RemoteHost) $($ErStatus) at $(Get-Date -Format G)" | |
| Send-MailMessage -To $EmailAddress -Body $Message -BodyAsHtml -From $SMTPFromAddress -SmtpServer $SMTPServer -Port $SMTPPort -Subject "$($RemoteHost) $($ErStatus)" | |
| } | |
| If(-not $NoNotify){ | |
| Write-Debug "Showing notification" | |
| $XmlString = @(" | |
| <toast duration = 'short'> | |
| <visual> | |
| <binding template='ToastGeneric'> | |
| <text>$($RemoteHost) $($ErStatus)</text> | |
| <text>$($RemoteHost) $($ErStatus) at $(Get-Date -Format G)</text> | |
| <image src='$WarningLogo' placement='appLogoOverride' hint-crop='circle' /> | |
| </binding> | |
| </visual> | |
| <audio src='ms-winsoundevent:Notification.Default' /> | |
| </toast> | |
| ") | |
| $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::new() | |
| $ToastXml.LoadXml($XmlString) | |
| $Toast = [Windows.UI.Notifications.ToastNotification]::new($ToastXml) | |
| [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).Show($Toast) | |
| } | |
| If($EventLog){ | |
| Write-EventLog -LogName Application -Source MonitoringConnection -Message "$($RemoteHost) $($ErStatus)" -EventId 8001 -EntryType Warning | |
| } | |
| $RemoteHostStatus = 0 | |
| } | |
| } | |
| #Pause before trying again | |
| Start-Sleep -Seconds $Pause | |
| } |
Hi @Reazin. You can now. I've just updated the script to support the host as a host:port combination, which you can feed into an array. Using your example, this now should work:
./Start-Monitoring -RemoteHost @("something.ddns.net:8001","another.ddns.net:8003")
Thanks @kiwi-cam ,I will test it on the weekend. I'm very excited about this script!
Hi @kiwi-cam!
For some reason I this get error when I try to use more than one domains: Cannot validate argument on parameter 'RemoteHost'. Exception calling "GetHostEntry" with "1" argument(s):
Can you show me how you’re running the script? I’ll try to reproduce the error here.
./Start-Monitoring -RemoteHost @("example2.duckdns.net:8001","example1.duckdns.net:8003")
#I added the last line to see what kind of error it recieves
Read-Host -Prompt "Press Enter to exit"
#I tried to add the parameters while only running the script piece by piece. the same error happens.
Hi @Reazin. What's the full error message you're getting, is it this:
Start-Monitoring: Cannot validate argument on parameter 'RemoteHost'. Exception calling "GetHostEntry" with "1" argument(s): "No such host is known."
This is expected behaviour. The script validates the arguments, including confirming that a hostname can be resolved by DNS. The error "No such host is known" just means that it can't find an IP address for the host name you supplied.
Hey @kiwi-cam.
I have checked again and I made a mistake (by not adding a " at a host).
Just a little bit of help I need more. How can I exactly configure the e-mail for this? (I'm not really familiar with this).
Thanks in advance :)
For that you need to know SMTP server settings. You'll need to put your settings into lines 171-173:
$SMTPServer = "smtp.someopenmailserver.com"
$SMTPPort = 25
$SMTPFromAddress = "[email protected]"
For home, using your ISP's mail server settings are going to be the best/easiest option.
Unable to find type [mailaddress]: make sure that the assembly containing this type is loaded.
At D:\psftpMonitoring\Start-Monitoring.ps1:131 char:22
-
[mailaddress] <<<< $EmailAddress = $null,- CategoryInfo : InvalidOperation: (mailaddress:String) [], ParentContainsErrorRecordException
- FullyQualifiedErrorId : TypeNotFound
Hi Kiwi - I have saved the smtp server details and I am facing above error for $EmailAddress. I gave from email and port 25 as smtp port as inputs
I am running on server 2008 R2
Congrats for the script! Im trying to schedule with params in win10 but it wont work. Is it possible to work?
Hy!
Can i use this script to somehow monitor different hosts with different ports? ex. something.ddns.net 8001 and another.ddns.net.8003
So far I can do different hosts but with the same port.