Network Scan using PowerShell

As a network administrator, it’s often necessary to quickly scan the network to identify connected machines and obtain the list of open ports on each machine. However, installing third-party tools such as “Advanced IP Scanner” can be cumbersome and pose security risks, especially when you prefer not to install additional software on servers.

To meet this need, I’ve developed a PowerShell script that efficiently scans the network and retrieves the list of open ports for each machine without the need to install additional software. This script uses multitasking for fast execution, automatically detects your address and performs the scan within the same address range.

Very Important : if you are using DHCP address no action needed, otherwise if you are using STATIC IP address you should specify your address in $localIP variable.

The script is very fast in execution because it uses multi-tasking.

The script also scans known ports for machines found on the network :

  1. 20 (FTP – File Transfer Protocol)
  2. 21 (FTP – Control)
  3. 22 (SSH – Secure Shell)
  4. 23 (Telnet)
  5. 25 (SMTP – Simple Mail Transfer Protocol)
  6. 53 (DNS – Domain Name System)
  7. 80 (HTTP – Hypertext Transfer Protocol)
  8. 110 (POP3 – Post Office Protocol version 3)
  9. 123 (NTP – Network Time Protocol)
  10. 143 (IMAP – Internet Message Access Protocol)
  11. 161 (SNMP – Simple Network Management Protocol)
  12. 389 (LDAP – Lightweight Directory Access Protocol)
  13. 443 (HTTPS – Hypertext Transfer Protocol Secure)
  14. 445 (SMB – Server Message Block)
  15. 993 (IMAPS – Internet Message Access Protocol over SSL)
  16. 995 (POP3S – Post Office Protocol version 3 over SSL/TLS)
  17. 3306 (Port 3306 is mainly used for connections to MySQL databases)
  18. 3389 (RDP (Remote Desktop Protocol))
  19. 5900 (Port 5900 is mainly used for remote desktop connections via the VNC (Virtual Network Computing) protocol)
  20. 8080 (Port 8080 is commonly used as an alternative port for web servers)

You can adjust List of common ports to be scanned in the script as your needs, you can refer to the following Sheet :

Here is the script execution result :

Find out how to simplify your network scans with my PowerShell script :

 # if you dont specify IP Address here, the script will get automatically address from network card with DHCP attribute
$localIP = ''

# Obtain the IP address of the local machine
if($localIP -eq '')
{ 
    $localIP = (Get-NetIPAddress | Where-Object { $_.AddressFamily -eq 'IPv4' -and $_.PrefixOrigin -eq 'Dhcp' }).IPAddress
}

# List of common ports to be scanned
$portsToScan = @(20,21,22,23,25,53,80,110,123,143,161,443,445,993,995,3306,3389,5900,8080)

# Extract the first three bytes of the IP address
$networkPrefix = $localIP -replace "(\d+\.\d+\.\d+)\.\d+", '$1'

# Creating a runspace pool
$runspacePool = [runspacefactory]::CreateRunspacePool(1, [int]$env:NUMBER_OF_PROCESSORS + 1)
$runspacePool.Open()


# Script Block will scan for connected machine and opned ports
$scriptBlock = {
    param($ip, $ports)
    
    if (Test-Connection -ComputerName $ip -Count 1 -Quiet) 
    {
        try {
            $hostName = [System.Net.Dns]::GetHostEntry($ip).HostName
        } catch {
            $hostName = "N/A"
        }
        $macAddress = arp -a $ip | Select-String '([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})' | ForEach-Object { $_.Matches.Value }
        #$openPorts = Test-Port -ip $ip -ports $ports

        # Get opned ports for connected machine
        $openPorts = @()
        foreach ($port in $ports) {
            $tcp = New-Object System.Net.Sockets.TcpClient
            try {
                $result = $tcp.BeginConnect($ip, $port, $null, $null)
                $wait = $result.AsyncWaitHandle.WaitOne(300,$false)
                if($wait) {
                    $openPorts += $port
                }
            } finally {
                $tcp.Close()
            }
        }
        
        return [PSCustomObject]@{
            "IP Address" = $ip
            "Hostname" = $hostName
            "MAC Address" = if ($macAddress) { $macAddress } else { "N/A" }
            "Open Ports" = $openPorts
        }
    }
}

# Create and start jobs
$jobs = 1..254 | ForEach-Object {
    $ip = "$networkPrefix.$_"
    $job = [powershell]::Create().AddScript($scriptBlock).AddArgument($ip).AddArgument($portsToScan)
    $job.RunspacePool = $runspacePool
    [PSCustomObject]@{
        Pipe = $job
        Result = $job.BeginInvoke()
    }
}

# Collecting results
$results = @()
$totalJobs = $jobs.Count
$completedJobs = 0

while ($completedJobs -lt $totalJobs) {
    $completedJobs = ($jobs | Where-Object { $_.Result.IsCompleted }).Count
    $percentComplete = ($completedJobs / $totalJobs) * 100
    Write-Progress -Activity "Scanning Network and Ports" -Status "Progress: $completedJobs / $totalJobs" -PercentComplete $percentComplete
    Start-Sleep -Milliseconds 100
}

foreach ($job in $jobs) {
    $result = $job.Pipe.EndInvoke($job.Result)
    if ($result) {
        $results += $result
    }
    $job.Pipe.Dispose()
}

$runspacePool.Close()
$runspacePool.Dispose()

# Show results
$results | Format-Table -AutoSize

Write-Host "Scan Completed...." -ForegroundColor Green

Thanks

Aymen EL JAZIRI (Microsoft MVP)
Aymen EL JAZIRI (Microsoft MVP)

Hi, I’m Aymen El Jaziri , a passionate System Administrator and Microsoft MVP, with years of hands-on experience in managing and securing modern IT infrastructures.
This blog is where I share technical guides, automation scripts, product reviews, and real-world solutions that help IT professionals simplify their day-to-day work and stay ahead in a fast-evolving cloud ecosystem.
Whether you’re here to troubleshoot an issue, improve your automation game, or learn new best practices , welcome in my blog !
Let’s build a stronger, smarter IT community together.
Feel free to connect with me on LinkedIn for more content, discussions, or collaboration opportunities.

Thanks

Aymen

Articles: 156