Public/Test-Port.ps1

Function Test-Port {
  <#
      .Synopsis
      Will test any number of TCP ports on any number of hosts.
      .DESCRIPTION
      Will accept piped Computers/IPs or Ports and then test those ports on the targets for TCP connectivity.
      .Parameter Computer
      Computer NetBIOS name, FQDN, or IP
      .Parameter Port
      TCP Port number to test.
      .Parameter TimeoutMS
      The amount of time to wait (in milliseconds) before abandoning a connection attempt on a given port.
      .EXAMPLE
      PS C:\> Test-Port -Computer '8.8.8.8' -Port 53
      .EXAMPLE
      PS C:\> 443,80,53,135,137,5723 | Test-Port -Computer 'MS01.contoso.com','DB01' | Sort-Object Computer,Port
      .EXAMPLE
      PS C:\> 'MS01.contoso.com','DB01' | Test-Port -Port 5723
      .NOTES
      Author: Tyson Paul
      Blog: https://monitoringguys.com/
      Version: 1.3
      Date: 2018.02.07
      History:
      2018.05.31: Improved error handling.
 
      Adapted from Boe Prox (https://gallery.technet.microsoft.com/scriptcenter/97119ed6-6fb2-446d-98d8-32d823867131)
  #>


  [CmdletBinding(DefaultParameterSetName='Parameter Set 1',
      SupportsShouldProcess=$true,
      PositionalBinding=$false,
      HelpUri = 'https://monitoringguys.com/',
  ConfirmImpact='Medium')]
  Param (
    [Parameter(Mandatory=$true,
        ValueFromPipeline=$true,
        ValueFromRemainingArguments=$false,
        Position=0,
    ParameterSetName='Parameter Set 1')]
    [string[]]$Computer,

    [Parameter(Mandatory=$true,
        ValueFromPipeline=$true,
        ValueFromRemainingArguments=$false,
        Position=1,
    ParameterSetName='Parameter Set 1')]
    [int[]]$Port,

    [int]$TimeoutMS=5000
  )
  Begin {
    $arrResults = @()
    $Error.Clear()
  }
  Process {
    If (-not $Port) { $Port = Read-host "Enter the port number to access" }

    ForEach ($thisComputer in $Computer) {
      ForEach ($thisPort in $Port) {
        $Status = "Failure"
        $objResult = New-Object -TypeName PSCustomObject
        $tcpobject = New-Object System.Net.Sockets.TcpClient
        #Connect to remote machine's port
        $connect = $tcpobject.BeginConnect($thisComputer,$thisPort,$null,$null)
        #Configure a timeout before quitting - time in milliseconds
        $wait = $connect.AsyncWaitHandle.WaitOne($TimeoutMS,$false)
        If (-Not $Wait) {
          $Message = "Connection Failure. Address:[$($thisComputer)], Port:[$($thisPort)] connection timed out [$($TimeoutMS) milliseconds].`n"
        }
        Else {
          Try{
            $tcpobject.EndConnect($connect)  #| out-Null
            $Status = "Success"
            $Message = "Connection Success. Address:[$($thisComputer)], Port:[$($thisPort)] connection successful.`n"
          }Catch{
            #If ([bool]$Error[0]) {
            $Message = ("{0}" -f $error[0].Exception.InnerException)
            #}
            #Else {
            # $Status = "Success"
            # $Message = "Connection Success. Address:[$($thisComputer)], Port:[$($thisPort)] connection successful.`n"
            #}
          }
        }
        $objResult | Add-Member -MemberType NoteProperty -Name Computer -Value $thisComputer
        $objResult | Add-Member -MemberType NoteProperty -Name Port -Value $thisPort
        $objResult | Add-Member -MemberType NoteProperty -Name Status -Value $Status
        $objResult | Add-Member -MemberType NoteProperty -Name Result -Value $Message
        $arrResults += $objResult
        $Error.Clear()
      }#End ForEach Port
    }#End ForEach Computer
  }#End Process

  End {
    Return $arrResults
  }

}