Blog Post

ITOps Talk Blog
2 MIN READ

PowerShell Basics: How to Scan Open Ports Within a Network

AnthonyBartolo's avatar
Oct 22, 2019

Network complexity is rapidly increasing with the addition of non-traditional devices gaining access to organizational networks. Singular purpose devices made available through the Internet of Things (IoT) offering has increased network complexity even further with the ease of adding said devices to the network and sometimes without the knowledge of a system administrator.  Hence the following received question:

 

"How do I ensure all the appropriate ports are closed with all these devices being added to my network?"

 

In scenarios like these, tools such as Azure Security Center do a great job on reporting probability of attacks that can occur in one's network and steps are needed to address this. However sometimes the challenge itself is convincing the organizational decision makers of the needed investment.  
 
azure iot security architecture

To help with this, the following PowerShell script will provide a rudimentary analysis report on what ports of what IPs are currently open. This report can be used as a great starting point to highlight probable attack vectors that could occur and the beginning to a conversation on additional security tool adoption.  Lets begin.

 

    1. Run PowerShell
       
      Run PowerShell Force AzureAD Password Sync
       
    2. Specify the $port value to scan: 
       
      $port = (80)
       
    3. Specify the $network value to scan: 
       
      $network = (192.168.0)
    4. Specify the $range value to scan: 
       
      $range = (1..254)
    5. Enable silent scan (without error reporting) of said network: 
       
      $ErrorActionPreference= ‘silentlycontinue’
    6. Calling the IP addresses one by one from the desired range and displaying the percentage to complete: 
       
      $(Foreach ($add in $range)
      { $ip = “{0}.{1}” –F $network,$add
      Write-Progress “Scanning Network” $ip -PercentComplete (($add/$range.Count)*100)
    7. Pinging the desired IP via the Test-Connection cmdlet to validate its existence on the network: 
       
      If(Test-Connection –BufferSize 32 –Count 1 –quiet –ComputerName $ip)
    8. Attempt made to connect to the desired port for testing: 
       
      { $socket = new-object System.Net.Sockets.TcpClient($ip, $port)
    9. Report success if the desired port is open: 
       
      If($socket.Connected) { “$ip port $port open”
      $socket.Close() }
      else { “$ip port $port not open ” }
      }
    10. Create the CSV output file reporting on desired open port: 
       
      }) | Out-File C:\reports\portscan.csv

The following is the above script in its entirety:

$port = (enter port value)
$network = “enter network value”
$range = 1..254
$ErrorActionPreference= ‘silentlycontinue’
$(Foreach ($add in $range)
{ $ip = “{0}.{1}” –F $network,$add
Write-Progress “Scanning Network” $ip -PercentComplete (($add/$range.Count)*100)
If(Test-Connection –BufferSize 32 –Count 1 –quiet –ComputerName $ip)
{ $socket = new-object System.Net.Sockets.TcpClient($ip, $port)
If($socket.Connected) { “$ip port $port open”
$socket.Close() }
else { “$ip port $port not open ” }
}
}) | Out-File C:\reports\portscan.csv

 
Again this is a rudimentary report output that can be utilized to begin the conversation with organizational decision makers regarding needed investments. Do comment below on additional tips or script edits.  

Updated Feb 18, 2022
Version 3.0
  • cfenton's avatar
    cfenton
    Copper Contributor

    I wrote a Workflow not too long ago doing just this. Using a Workflow allowed me to use foreach -parallel which substantially sped up the process. Let me know if we can start an Nmap project in Pwsh... 

  • Casper042's avatar
    Casper042
    Copper Contributor

    Not sure what changed, but this doesn't work for me.

     

    portscan.csv is created but is always 0 bytes, even scanning for port 80 on my home network which I know has a bunch of stuff on 80.

     

  • bnielsenPB's avatar
    bnielsenPB
    Copper Contributor

    The problem is with:

     

    3. Specify the $network value to scan: 

    $network = (192.168.0)

     I just used quotes here instead of parenthesis and it works

  • cryptic_dreamer's avatar
    cryptic_dreamer
    Copper Contributor

    Nope, doesn't work for me either and I have the path to the output file correct.

  • Jrdgamer11's avatar
    Jrdgamer11
    Copper Contributor

    Do you need to be plugged in to the ethernet?

    Because I have tried everything that the comments said and it still doesn't work.

  • Casper042's avatar
    Casper042
    Copper Contributor

    Jrdgamer11 
    Here is a literal copy and paste from my machine where I just tested this:

     

     

    $port = (80)
    $network = “192.168.42”
    $range = 240..252
    $ErrorActionPreference= ‘silentlycontinue’
    $(Foreach ($add in $range)
    { $ip = “{0}.{1}” –F $network,$add
    Write-Progress “Scanning Network” $ip -PercentComplete (($add/$range.Count)*100)
    If(Test-Connection –BufferSize 32 –Count 1 –quiet –ComputerName $ip)
    { $socket = new-object System.Net.Sockets.TcpClient($ip, $port)
    If($socket.Connected) { “$ip port $port open”
    $socket.Close() }
    else { “$ip port $port not open ” }
    }
    }) | Out-File D:\Documents\Scripts\PowerShell\PortScan\PortScan.csv

     

     

    With results:

     

     

    192.168.42.240 port 80 open
    192.168.42.241 port 80 open
    192.168.42.247 port 80 open
    192.168.42.248 port 80 open
    192.168.42.249 port 80 open
    192.168.42.250 port 80 open

     

     

     

    As was noted above, make sure the CSV location can be written to, my line 14 is where I have "My Documents" redirected to on my laptop and then some sub folders.
    The folders all need to exist ahead of time.  The CSV itself does not.

     

    And this should work on WiFi as well as Wired, but if you are connected to nothing then what are you scanning?

     

    -Casper042