Scripting. Powershell, VMware, Windows, Active Directory & Exchange. All that kind of stuff…..
RSS icon Email icon Home icon
  • Testing TCP Port Response from PowerShell

    Posted on December 20th, 2011 Jonathan Medd 10 comments

    Recently I was listening to the PowerScripting Podcast and Hal mentioned a Test-TCPPort function he had put together a while back. I had a similar need to be able to test a bunch of machines post reboot, that they had come back successfully and a Ping test wouldn’t do since that didn’t necessarily mean that Windows has successfully booted :-)

    So taking inspiration from that post I put together the following script (I convert it to a function for my own use, but it’s easier for my colleagues to use as a script) which will test by default RDP response from servers and report the results. A few examples of how to use it:

    Test a single server

    
    .\Test-PortResponse.ps1 -ComputerName Server01 | Format-Table -AutoSize
    

    Testing multiple servers

    
    Get-Content servers.txt | .\Test-PortResponse.ps1 | Format-Table -AutoSize
    

    Testing multiple servers on port 22 and exporting the results to csv

    
    Get-Content servers.txt | .\Test-PortResponse.ps1 -Port 22 | Export-Csv Ports.csv -NoTypeInformation
    

    Here’s the code you can use.

    
    <#
    .SYNOPSIS
    Test the response of a computer to a specific TCP port
    
    .DESCRIPTION
    Test the response of a computer to a specific TCP port
    
    .PARAMETER  ComputerName
    Name of the computer to test the response for
    
    .PARAMETER  Port
    TCP Port number to test
    
    .EXAMPLE
    PS C:\> ./Test-PortResponse.ps1 -ComputerName Server01
    
    .EXAMPLE
    PS C:\> Get-Content Servers.txt | ./Test-PortResponse.ps1 -Port 22
    
    .NOTES
    Author: Jonathan Medd
    Date: 20/12/2011
    #>
    
    [CmdletBinding()]
    param(
    [Parameter(Position=0,Mandatory=$true,HelpMessage="Name of the computer to test",
    ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$true)]
    [Alias('CN','__SERVER','IPAddress','Server')]
    [System.String]
    $ComputerName,
    
    [Parameter(Position=1)]
    [ValidateRange(1,65535)]
    [Int]
    $Port = 3389
    )
    
    process {
    
    $Connection = New-Object Net.Sockets.TcpClient
    
    try {
    
    $Connection.Connect($ComputerName,$Port)
    
    if ($Connection.Connected) {
    $Response = “Open”
    $Connection.Close()
    }
    
    }
    
    catch [System.Management.Automation.MethodInvocationException]
    
    {
    $Response = “Closed / Filtered”
    }
    
    $Connection = $null
    
    $MYObject = “” | Select-Object ComputerName,Port,Response
    $MYObject.ComputerName = $ComputerName
    $MYObject.Port = $Port
    $MYObject.Response = $Response
    $MYObject
    
    }
    
     

    9 responses to “Testing TCP Port Response from PowerShell” RSS icon

    • Excellent!

    • I’m curious why you don’t use New-Object to create $MyObject and why you add it to $myCol. In this version you end up writing a string object to the pipeline with a number of note properties. I would think all you need is code like this:

      New-Object -TypeName PSObject -Property @{
      Computername=$computername
      Port=$Port
      Response=$Response
      }

      Simple write each response object to the pipeline.

    • Thanks Jeff for the feedback, that was mostly lazy in my part in moving a lot of pre-packaged stuff I have used in other scripts and making it more appropriate for pipeline use, rather than foreach statements – updated accordingly. Always appreciate someone of your knowledge casting a critical eye :-)

      I’ve never liked New-Object and the fact you can’t control the order of the output (slightly OCD), so I prefer to use the Select-Object way until I can use v3 and [ordered].

    • I have the same reservations about New-Object. The way around it is to add type name to the custom object and include your own format extension (.psxml) file.

      The other challenge here is that if a computer is offline or unreachable the port will show as closed. And maybe that’s ok. But it could also lead to a misunderstanding.

    • I also don’t like the fact that New-Object doesn’t retain the order of properties, but as Jeff suggested, I also prefer to use New-Object. When I need to retain the order of properties I pipe the result to the Select-Object cmdlet and specify the properties again in the order I need. Not so friendly :)

      Now, you can still use the same method you chose and cast the properties to the desired type:

      $MYObject = “” | Select-Object ComputerName,Port,Response
      $MYObject.ComputerName = $ComputerName
      $MYObject.Port = [int]$Port
      $MYObject.Response = $Response
      $MYObject

      Lastly, you need to mark the ComputerName parameter as Mandatory. I would also make the the ComputerName parameter more robust and pipeline-able by adding the ValueFromPipelineByPropertyName and the Alias attributes:

      [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$true)]
      [Alias('CN','__SERVER','IPAddress','Server')]
      [System.String]
      $ComputerName,

    • >I also don’t like the fact that New-Object doesn’t retain the order of properties

      Hi Shay Levy,

      I recently authored a post that talks about port connectivity using powershell.

      http://techibee.com/powershell/powershell-test-port-connectivity/1214

      I created custom object for output by using new-object cmdlet and able to print the colums in desired order by using select statement. Is this approach is good?

    • That is great, thanks for the feedback. The alias attribute is super cool, I had somehow missed seeing that before.

      Thanks!

    • Cool, excellent suggestion. Take the point about the computer being offline. For my requirements that is exactly the scenario I am trying to match, I guess I could also add an optional ping test.

    • Hey,

      I was testing this power shell script and works great on W2k8 R2 systems, but when I tried on wsk8 it doesn’t work. It gives me this error:
      ==
      Missing closing ‘)’ in expression.
      At C:\Users\syseng\Desktop\Test-PortResponse.ps1:26 char:1
      + [ <<<< Alias('CN','__SERVER','IPAddress','Server')]
      ==

      Anyone knows what's the deal with this error?

      Many thanks.


    1 Trackbacks / Pingbacks

    Leave a reply