Building a PowerShell Ping Sweep Tool: Adding a Port Check

Posted on May 11, 2015 by Jeff Hicks in PowerShell with 0 Comments

Over the last few articles on the Petri IT Knowledgebase, I’ve been walking you through the process of creating a PowerShell-based tool that you could use to ping a range of subnet addresses. I hope you’ve been following along and if not, then take a few minutes to get caught up. Hopefully you’ll notice I’ve followed an iterative process, where I started with a basic command and slowly added pieces onto the tool. If I had tried to write everything all at once and then test, then it’s more than likely that something would not work, and it might take longer to figure out why. Today, I want to add the final piece to the tool, where we’ll add a port check to our existing tool.

PowerShell Ping Sweep Tool Article Series

  1. Building a Ping Sweep Tool with PowerShell
  2. PowerShell Ping Sweep Tool: Adding Parameter Validation
  3. Adding Trace Information to a PowerShell Ping Tool
  4. Identifying a Computer Name with a PowerShell Ping Sweep Tool
  5. Building a PowerShell Ping Sweep Tool: Adding a Port Check

Philosophically, PowerShell tools, that is scripts and functions, should be designed to do one thing and write a single object type to the pipeline. One of the features I want to add is a quick port check. On one hand, this seems like it should be a completely separate tool. But I’m going to limit my port scan to a single user-defined port. My assumption is that you might want to use the sweep tool to not only see what IP addresses are up, but also see which IT addresses that might have a specific port open.

First, let’s test some code to handle the port scan. I want to test a single server and port.

I already know this port is open, so whatever code I come up with needs to reflect that fact. There’s no easy way around this, but we’ll have to use the .NET Framework directly. How did I know what to use? Google.

But now you know as well. Here’s what we have.

Using $tcp in Windows PowerShell. (Image Credit: Jeff Hicks)

Using $tcp in Windows PowerShell. (Image Credit: Jeff Hicks)

The object has a method, which you could discover by piping to Get-Member or reading the MSDN documentation called ConnectAsync. It needs an IP address and port.

This has made a connection. There is also a Connect method, which you could have used to test. But I used ConnectAsync for performance reasons. Here’s what the object looks like.

Using $tcpconnection in Windows PowerShell. (Image Credit: Jeff Hicks)

Using $tcpconnection in Windows PowerShell. (Image Credit: Jeff Hicks)

You might think you could use the IsCompleted property, but as far as I can tell that has to do with whether the connection process is complete. It turns out we need to dig a bit deeper and look at the AsyncWaitHandle property. This property is a nested object that has a method called WaitOne that will wait for a connection to be made. I’m going to give PowerShell 1000 milliseconds to connect to the port.

The value of $wait will be true or false, which is very handy in PowerShell.

Our $wait property has returned true. (Image Credit: Jeff Hicks)

Our $wait property has returned true. (Image Credit: Jeff Hicks)

Of course, I should verify that with another port that I know is not open.

Our $wait property has returned false. (Image Credit: Jeff Hicks)

Our $wait property has returned false. (Image Credit: Jeff Hicks)

Just what I expected. While PowerShell will probably clean up for me, it is a good practice to close and dispose of the connection.

In my function, I’ll add a parameter called Port, but I won’t assign a default value. As the function processes each IP address, if there is a port value, I can test using the code from above.

Sponsored

If you recall, the function is writing a custom object to the pipeline and I’m going to add a property called Port. If the port is open, I’ll include the value in the output. Otherwise I’ll set the value to null. If no port is tested, then the property will also be null. Here is the finished function.

Sponsored

With the function loaded into my PowerShell session, I can test a range of addresses and see what is listening on port 53.

Testing port 53 with our new function. (Image Credit: Jeff Hicks)

Testing port 53 with our new function. (Image Credit: Jeff Hicks)

Because I have an object, I can use my tool like any other command in a PowerShell expression.

The only task that remains is to insert some comment based help, which I will leave for you to write. I’ll be the first to admit this is far from a perfect PowerShell tool, but I hope the process served as a learning platform. If you have any questions on what I did or why, I hope you’ll leave a comment.

Sponsored

Tagged with , , , ,