Created
November 27, 2018 19:13
-
-
Save pldmgg/a943205afd6499ab20fc2b620ca2b0ae to your computer and use it in GitHub Desktop.
Script to monitor ports 104 and 108 every 30 seconds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #region >> Helper Functions | |
| function TestIsValidIPAddress([string]$IPAddress) { | |
| [boolean]$Octets = (($IPAddress.Split(".") | Measure-Object).Count -eq 4) | |
| [boolean]$Valid = ($IPAddress -as [ipaddress]) -as [boolean] | |
| Return ($Valid -and $Octets) | |
| } | |
| function ResolveHost { | |
| [CmdletBinding()] | |
| Param( | |
| [Parameter(Mandatory=$True)] | |
| [string]$HostNameOrIP | |
| ) | |
| ##### BEGIN Main Body ##### | |
| $RemoteHostNetworkInfoArray = @() | |
| if (!$(TestIsValidIPAddress -IPAddress $HostNameOrIP)) { | |
| try { | |
| $HostNamePrep = $HostNameOrIP | |
| [System.Collections.ArrayList]$RemoteHostArrayOfIPAddresses = @() | |
| $IPv4AddressFamily = "InterNetwork" | |
| $IPv6AddressFamily = "InterNetworkV6" | |
| $ResolutionInfo = [System.Net.Dns]::GetHostEntry($HostNamePrep) | |
| $ResolutionInfo.AddressList | Where-Object { | |
| $_.AddressFamily -eq $IPv4AddressFamily | |
| } | foreach { | |
| if ($RemoteHostArrayOfIPAddresses -notcontains $_.IPAddressToString) { | |
| $null = $RemoteHostArrayOfIPAddresses.Add($_.IPAddressToString) | |
| } | |
| } | |
| } | |
| catch { | |
| Write-Verbose "Unable to resolve $HostNameOrIP when treated as a Host Name (as opposed to IP Address)!" | |
| if ($HostNameOrIP -match "\.") { | |
| try { | |
| $HostNamePrep = $($HostNameOrIP -split "\.")[0] | |
| Write-Verbose "Trying to resolve $HostNameOrIP using only HostName: $HostNamePrep!" | |
| [System.Collections.ArrayList]$RemoteHostArrayOfIPAddresses = @() | |
| $ResolutionInfo = [System.Net.Dns]::GetHostEntry($HostNamePrep) | |
| $ResolutionInfo.AddressList | Where-Object { | |
| $_.AddressFamily -eq $IPv4AddressFamily | |
| } | foreach { | |
| if ($RemoteHostArrayOfIPAddresses -notcontains $_.IPAddressToString) { | |
| $null = $RemoteHostArrayOfIPAddresses.Add($_.IPAddressToString) | |
| } | |
| } | |
| } | |
| catch { | |
| Write-Verbose "Unable to resolve $HostNamePrep!" | |
| } | |
| } | |
| } | |
| } | |
| if (TestIsValidIPAddress -IPAddress $HostNameOrIP) { | |
| try { | |
| $HostIPPrep = $HostNameOrIP | |
| [System.Collections.ArrayList]$RemoteHostArrayOfIPAddresses = @() | |
| $null = $RemoteHostArrayOfIPAddresses.Add($HostIPPrep) | |
| $ResolutionInfo = [System.Net.Dns]::GetHostEntry($HostIPPrep) | |
| [System.Collections.ArrayList]$RemoteHostFQDNs = @() | |
| $null = $RemoteHostFQDNs.Add($ResolutionInfo.HostName) | |
| } | |
| catch { | |
| Write-Verbose "Unable to resolve $HostNameOrIP when treated as an IP Address (as opposed to Host Name)!" | |
| } | |
| } | |
| if ($RemoteHostArrayOfIPAddresses.Count -eq 0) { | |
| Write-Error "Unable to determine IP Address of $HostNameOrIP! Halting!" | |
| $global:FunctionResult = "1" | |
| return | |
| } | |
| # At this point, we have $RemoteHostArrayOfIPAddresses... | |
| [System.Collections.ArrayList]$RemoteHostFQDNs = @() | |
| foreach ($HostIP in $RemoteHostArrayOfIPAddresses) { | |
| try { | |
| $FQDNPrep = [System.Net.Dns]::GetHostEntry($HostIP).HostName | |
| } | |
| catch { | |
| Write-Verbose "Unable to resolve $HostIP. No PTR Record? Please check your DNS config." | |
| continue | |
| } | |
| if ($RemoteHostFQDNs -notcontains $FQDNPrep) { | |
| $null = $RemoteHostFQDNs.Add($FQDNPrep) | |
| } | |
| } | |
| if ($RemoteHostFQDNs.Count -eq 0) { | |
| $null = $RemoteHostFQDNs.Add($ResolutionInfo.HostName) | |
| } | |
| [System.Collections.ArrayList]$HostNameList = @() | |
| [System.Collections.ArrayList]$DomainList = @() | |
| foreach ($fqdn in $RemoteHostFQDNs) { | |
| $PeriodCheck = $($fqdn | Select-String -Pattern "\.").Matches.Success | |
| if ($PeriodCheck) { | |
| $HostName = $($fqdn -split "\.")[0] | |
| $Domain = $($fqdn -split "\.")[1..$($($fqdn -split "\.").Count-1)] -join '.' | |
| } | |
| else { | |
| $HostName = $fqdn | |
| $Domain = "Unknown" | |
| } | |
| $null = $HostNameList.Add($HostName) | |
| $null = $DomainList.Add($Domain) | |
| } | |
| if ($RemoteHostFQDNs[0] -eq $null -and $HostNameList[0] -eq $null -and $DomainList -eq "Unknown" -and $RemoteHostArrayOfIPAddresses) { | |
| [System.Collections.ArrayList]$SuccessfullyPingedIPs = @() | |
| # Test to see if we can reach the IP Addresses | |
| foreach ($ip in $RemoteHostArrayOfIPAddresses) { | |
| try { | |
| $null = [System.Net.NetworkInformation.Ping]::new().Send($ip,1000) | |
| $null = $SuccessfullyPingedIPs.Add($ip) | |
| } | |
| catch { | |
| Write-Verbose "Unable to ping $ip..." | |
| continue | |
| } | |
| } | |
| } | |
| $FQDNPrep = if ($RemoteHostFQDNs) {$RemoteHostFQDNs[0]} else {$null} | |
| if ($FQDNPrep -match ',') { | |
| $FQDN = $($FQDNPrep -split ',')[0] | |
| } | |
| else { | |
| $FQDN = $FQDNPrep | |
| } | |
| $DomainPrep = if ($DomainList) {$DomainList[0]} else {$null} | |
| if ($DomainPrep -match ',') { | |
| $Domain = $($DomainPrep -split ',')[0] | |
| } | |
| else { | |
| $Domain = $DomainPrep | |
| } | |
| $IPAddressList = [System.Collections.ArrayList]@($(if ($SuccessfullyPingedIPs) {$SuccessfullyPingedIPs} else {$RemoteHostArrayOfIPAddresses})) | |
| $HName = if ($HostNameList) {$HostNameList[0].ToLowerInvariant()} else {$null} | |
| if ($SuccessfullyPingedIPs.Count -eq 0 -and !$FQDN -and !$HostName -and !$Domain) { | |
| Write-Error "Unable to resolve $HostNameOrIP! Halting!" | |
| $global:FunctionResult = "1" | |
| return | |
| } | |
| [pscustomobject]@{ | |
| IPAddressList = $IPAddressList | |
| PingSuccess = $($SuccessfullyPingedIPs.Count -gt 0) | |
| FQDN = $FQDN | |
| HostName = $HName | |
| Domain = $Domain | |
| } | |
| ##### END Main Body ##### | |
| } | |
| function Test-Port { | |
| [CmdletBinding()] | |
| Param( | |
| [Parameter(Mandatory=$True)] | |
| [string]$HostNameOrIP, | |
| [Parameter(Mandatory=$True)] | |
| [int]$Port | |
| ) | |
| #region >> Main | |
| if (!$(TestIsValidIPAddress -IPAddress $HostNameOrIP)) { | |
| try { | |
| $HostNameNetworkInfo = ResolveHost -HostNameOrIP $HostNameOrIP -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Error "Unable to resolve $HostName! Halting!" | |
| $global:FunctionResult = "1" | |
| return | |
| } | |
| $RHostIP = $HostNameNetworkInfo.IPAddressList[0] | |
| } | |
| else { | |
| $RHostIP = $HostNameOrIP | |
| } | |
| $tcp = New-Object Net.Sockets.TcpClient | |
| try { | |
| $tcp.Connect($RHostIP, $Port) | |
| } | |
| catch { | |
| Write-Warning $_.Exception.Message | |
| } | |
| if ($tcp.Connected) { | |
| $tcp.Close() | |
| $open = $true | |
| } | |
| else { | |
| $open = $false | |
| } | |
| [pscustomobject]@{ | |
| Address = $RHostIP | |
| Port = $Port | |
| Open = $open | |
| } | |
| #endregion >> Main | |
| } | |
| # From: https://www.randomizedharmony.com/blog/2018/11/25/using-credentials-in-production-scripts | |
| function ConvertFrom-CredentialFileToCredential { | |
| [CmdletBinding()] | |
| param ( | |
| [Parameter(Mandatory = $true)] | |
| [ValidateScript({ test-path $_ })] | |
| [ValidateNotNullOrEmpty()] | |
| [string]$Path | |
| ) | |
| try { | |
| $rawData = Get-Content $Path | |
| $xmlstring = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($rawData | ConvertTo-SecureString)))) | |
| $type = [PSObject].Assembly.GetType('System.Management.Automation.Deserializer') | |
| $ctor = $type.GetConstructor('instance,nonpublic', $null, @([xml.xmlreader]), $null) | |
| $sr = New-Object System.IO.StringReader $xmlString | |
| $xr = New-Object System.Xml.XmlTextReader $sr | |
| $deserializer = $ctor.Invoke($xr) | |
| $done = $type.GetMethod('Done', [System.Reflection.BindingFlags]'nonpublic,instance') | |
| while (!$type.InvokeMember("Done", "InvokeMethod,NonPublic,Instance", $null, $deserializer, @())) { | |
| try | |
| { | |
| $credentialData = $type.InvokeMember("Deserialize", "InvokeMethod,NonPublic,Instance", $null, $deserializer, @()) | |
| } | |
| catch | |
| { | |
| Write-Warning "Could not deserialize ${string}: $_" | |
| } | |
| } | |
| $xr.Close() | |
| $sr.Dispose() | |
| $encryptedPassword = $credentialData.password | ConvertTo-SecureString | |
| New-Object System.Management.Automation.PSCredential($($credentialData.username), $($encryptedPassword)) | |
| } | |
| catch { | |
| Write-Error $_ | |
| return | |
| } | |
| } | |
| # From: https://blog.ipswitch.com/how-to-build-a-logging-function-in-powershell | |
| function Write-Log { | |
| [CmdletBinding()] | |
| param( | |
| [Parameter()] | |
| [ValidateNotNullOrEmpty()] | |
| [string]$LogFileDirectory, | |
| [Parameter()] | |
| [ValidateNotNullOrEmpty()] | |
| [string]$Message, | |
| [Parameter()] | |
| [ValidateNotNullOrEmpty()] | |
| [ValidateSet('Information','Warning','Error')] | |
| [string]$Severity = 'Information' | |
| ) | |
| try { | |
| $LogFileDirectory = (Resolve-Path $LogFilePath -ErrorAction Stop).Path | |
| } | |
| catch { | |
| Write-Error $_ | |
| return | |
| } | |
| [pscustomobject]@{ | |
| Time = (Get-Date -f g) | |
| Message = $Message | |
| Severity = $Severity | |
| } | Export-Csv -Path "$LogFileDirectory\CoralCheck_$(Get-Date -f MMddyy_hhmmss).csv" -Append -NoTypeInformation | |
| } | |
| #endregion >> Helper Functions | |
| #region >> Additional Prep | |
| $LogFileDir = "$HOME\CoralServerCheckLogs" | |
| $PSCredentialFileLocation = $null | |
| $UseBurntToast = $False | |
| $CoralServerServiceName = "CoralSvc" | |
| $IPOrFQDNofCoralServer = "192.168.2.40" | |
| $PortsToTest = @(104,108) | |
| $PortCheckIntervalInSeconds = 30 | |
| if (!$(Test-Path $LogFileDir)) { | |
| $null = New-Item -ItemType Directory -Path $LogFileDir | |
| } | |
| if ($PSCredentialFileLocation) { | |
| try { | |
| $PSCredentialFileLocation = $(Resolve-Path $PSCredentialFileLocation -ErrorAction Stop).Path | |
| } | |
| catch { | |
| Write-Error $_ | |
| return | |
| } | |
| $PSRemotingCredentials = ConvertFrom-CredentialFileToCredential -path $PSCredentialFileLocation | |
| } | |
| if ($UseBurntToast -and [Environment]::OSVersion.Version.Major -ge 10) { | |
| try { | |
| if (!$(Get-Module -ListAvailable BurntToast)) {Install-Module BurntToast} | |
| if (!$(Get-Module BurntToast)) {Import-Module BurntToast} | |
| } | |
| catch { | |
| Write-Verbose "Problem with installing the BurntToast Module! Skipping..." | |
| } | |
| } | |
| #endregion >> Additional Prep | |
| #region >> Main | |
| while ($True) { | |
| [System.Collections.Generic.List[PSObject]]$PortTestResults = @() | |
| foreach ($PortNum in $PortsToTest) { | |
| $TestResult = Test-Port -HostNameOrIP $IPOrFQDNofCoralServer -Port $PortNum | |
| $null = $PortTestResults.Add($TestResult) | |
| } | |
| if ($PortTestResults.Open -contains $False) { | |
| $PortsThatAreClosed = $($PortTestResults | Where-Object {$_.Open -eq $False}).Port | |
| $ClosedPortsCommaSeparated = $PortsThatAreClosed -join ', ' | |
| $null = Write-Log -LogFileDirectory $LogFileDir -Message "Coral Server port(s) $ClosedPortsCommaSeparated appear to be closed!" -Severity "Warning" | |
| if ($UseBurntToast -and [Environment]::OSVersion.Version.Major -ge 10) { | |
| $NewBTMsgSplatParams = @{ | |
| Text = @("Coral Server port(s) $ClosedPortsCommaSeparated appear to be closed! Restarting $CoralServerServiceName") | |
| Button = New-BTButton -Dismiss | |
| } | |
| New-BurntToastNotification @NewBTMsgSplatParams | |
| } | |
| try { | |
| $CoralServerNetworkInfo = ResolveHost -HostNameOrIP $IPOrFQDNofCoralServer -ErrorAction Stop | |
| } | |
| catch { | |
| if (TestIsValidIPAddress $IPOrFQDNofCoralServer) { | |
| if ($(Get-NetIPAddress -AddressFamily IPv4).IPAddress -contains $IPOrFQDNofCoralServer) { | |
| try { | |
| $null = Write-Log -LogFileDirectory $LogFileDir -Message "Restarting $CoralServerServiceName..." -Severity "Information" | |
| Restart-Service $CoralServerServiceName -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Error $_ | |
| } | |
| } | |
| } | |
| elseif (@($($IPOrFQDNofCoralServer -split '\.'))[0] -eq $env:ComputerName) { | |
| try { | |
| $null = Write-Log -LogFileDirectory $LogFileDir -Message "Restarting $CoralServerServiceName..." -Severity "Information" | |
| Restart-Service $CoralServerServiceName -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Error $_ | |
| } | |
| } | |
| else { | |
| Write-Error "Unable to resolve $IPOrFQDNOfCoralServer! Halting!" | |
| $global:FunctionResult = "1" | |
| return | |
| } | |
| } | |
| if ($CoralServerNetworkInfo.HostName -eq $env:ComputerName) { | |
| try { | |
| $null = Write-Log -LogFileDirectory $LogFileDir -Message "Restarting $CoralServerServiceName..." -Severity "Information" | |
| Restart-Service $CoralServerServiceName -ErrorAction Stop | |
| } | |
| catch { | |
| Write-Error $_ | |
| } | |
| } | |
| else { | |
| $InvCmdSplatParams = @{ | |
| ComputerName = $CoralServerNetworkInfo.FQDN | |
| Scriptblock = {Restart-Service $using:CoralServerServiceName} | |
| ErrorAction = "Stop" | |
| } | |
| if ($PSRemotingCredentials) { | |
| $InvCmdSplatParams.Add("Credential",$PSRemotingCredentials) | |
| } | |
| try { | |
| $null = Write-Log -LogFileDirectory $LogFileDir -Message "Restarting $CoralServerServiceName on Remote Host $($CoralServerNetworkInfo.FQDN)..." -Severity "Information" | |
| Invoke-Command @InvCmdSplatParams | |
| } | |
| catch { | |
| Write-Error $_ | |
| $global:FunctionResult = "1" | |
| return | |
| } | |
| } | |
| } | |
| Start-Sleep -Seconds $PortCheckIntervalInSeconds | |
| } | |
| #endregion >> Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment