Skip to content
David Kittell
David Kittell

Application & System: Development / Integration / Orchestration

  • Services
    • Application Development
    • Online Application Integration
  • Code
  • Online Tools
  • Tech Support
David Kittell

Application & System: Development / Integration / Orchestration

PowerShell – Ping Subnet

Posted on November 9, 2015 By David Kittell
#requires -Version 2.0
Function Ping-Subnet {
    #.Synopsis
    # Ping a subnet returning all alive hosts.
    #.Example
    # Ping-Subnet -IP 192.168.1.0 -Netmask /24
    #.Example
    # Ping-Subnet -IP 192.168.1.128 -Netmask 255.255.255.128
    Param(
        [string]
        $IP,
        [string]
        $netmask
    )
    Begin {
        $IPs = New-Object System.Collections.ArrayList
        $Jobs = New-Object System.Collections.ArrayList
        $max = 50
        
        Function Get-NetworkAddress {
            #.Synopsis 
            # Get the network address of a given lan segment
            #.Example 
            # Get-NetworkAddress -IP 192.168.1.36 -mask 255.255.255.0
            Param (
                [string]
                $IP, 
                
                [string]
                $Mask, 
                
                [switch]
                $Binary
            )
            Begin {
                $NetAdd = $null
            }
            Process {
                $BinaryIP = ConvertTo-BinaryIP $IP
                $BinaryMask = ConvertTo-BinaryIP $Mask
                0..34 | %{
                    $IPBit = $BinaryIP.Substring($_,1)
                    $MaskBit = $BinaryMask.Substring($_,1)
                    IF ($IPBit -eq '1' -and $MaskBit -eq '1') {
                        $NetAdd = $NetAdd + "1"
                    } elseif ($IPBit -eq ".") {
                        $NetAdd = $NetAdd +'.'
                    } else {
                        $NetAdd = $NetAdd + "0"
                    }
                }
                if ($Binary) {
                    return $NetAdd
                } else {
                    return ConvertFrom-BinaryIP $NetAdd
                }
            }
        }
        
        Function ConvertTo-BinaryIP {
            #.Synopsis
            # Convert an IP address to binary
            #.Example 
            # ConvertTo-BinaryIP -IP 192.168.1.1
            Param (
                [string]
                $IP
            )
            Process {
                $out = @()
                Foreach ($octet in $IP.split('.')) {
                    $strout = $null
                    0..7|% {
                        IF (($octet - [math]::pow(2,(7-$_)))-ge 0) { 
                            $octet = $octet - [math]::pow(2,(7-$_))
                            [string]$strout = $strout + "1"
                        } else {
                            [string]$strout = $strout + "0"
                        }   
                    }
                    $out += $strout
                }
                return [string]::join('.',$out)
            }
        }


        Function ConvertFrom-BinaryIP {
            #.Synopsis 
            # Convert from Binary to an IP address
            #.Example 
            # Convertfrom-BinaryIP -IP 11000000.10101000.00000001.00000001
            Param (
                [string]
                $IP
            )
            Process {
                $out = @()
                Foreach ($octet in $IP.split('.')) {
                    $strout = 0
                    0..7|% {
                        $bit = $octet.Substring(($_),1)
                        IF ($bit -eq 1) { 
                            $strout = $strout + [math]::pow(2,(7-$_))
                        } 
                    }
                    $out += $strout
                }
                return [string]::join('.',$out)
            }
        }

        Function ConvertTo-MaskLength {
            #.Synopsis 
            # Convert from a netmask to the masklength
            #.Example 
            # ConvertTo-MaskLength -Mask 255.255.255.0
            Param (
                [string]
                $mask
            )
            Process {
                $out = 0
                Foreach ($octet in $Mask.split('.')) {
                    $strout = 0
                    0..7|% {
                        IF (($octet - [math]::pow(2,(7-$_)))-ge 0) { 
                            $octet = $octet - [math]::pow(2,(7-$_))
                            $out++
                        }
                    }
                }
                return $out
            }
        }

        Function ConvertFrom-MaskLength {
            #.Synopsis 
            # Convert from masklength to a netmask
            #.Example 
            # ConvertFrom-MaskLength -Mask /24
            #.Example 
            # ConvertFrom-MaskLength -Mask 24
            Param (
                [int]
                $mask
            )
            Process {
                $out = @()
                [int]$wholeOctet = ($mask - ($mask % 8))/8
                if ($wholeOctet -gt 0) {
                    1..$($wholeOctet) |%{
                        $out += "255"
                    }
                }
                $subnet = ($mask - ($wholeOctet * 8))
                if ($subnet -gt 0) {
                    $octet = 0
                    0..($subnet - 1) | %{
                         $octet = $octet + [math]::pow(2,(7-$_))
                    }
                    $out += $octet
                }
                for ($i=$out.count;$i -lt 4; $I++) {
                    $out += 0
                }
                return [string]::join('.',$out)
            }
        }
        Function Get-IPRange {
            #.Synopsis 
            # Given an Ip and subnet, return every IP in that lan segment
            #.Example 
            # Get-IPRange -IP 192.168.1.36 -Mask 255.255.255.0
            #.Example 
            # Get-IPRange -IP 192.168.5.55 -Mask /23
            Param (
                [string]
                $IP,
                
                [string]
                $netmask
            )
            Process {
                iF ($netMask.length -le 3) {
                    $masklength = $netmask.replace('/','')
                    $Subnet = ConvertFrom-MaskLength $masklength
                } else {
                    $Subnet = $netmask
                    $masklength = ConvertTo-MaskLength -Mask $netmask
                }
                $network = Get-NetworkAddress -IP $IP -Mask $Subnet 
                
                [int]$FirstOctet,[int]$SecondOctet,[int]$ThirdOctet,[int]$FourthOctet = $network.split('.')
                $TotalIPs = ([math]::pow(2,(32-$masklength)) -2)
                $blocks = ($TotalIPs - ($TotalIPs % 256))/256
                if ($Blocks -gt 0) {
                    1..$blocks | %{
                        0..255 |%{
                            if ($FourthOctet -eq 255) {
                                If ($ThirdOctet -eq 255) {
                                    If ($SecondOctet -eq 255) {
                                        $FirstOctet++
                                        $secondOctet = 0
                                    } else {
                                        $SecondOctet++
                                        $ThirdOctet = 0
                                    }
                                } else {
                                    $FourthOctet = 0
                                    $ThirdOctet++
                                }  
                            } else {
                                $FourthOctet++
                            }
                            Write-Output ("{0}.{1}.{2}.{3}" -f `
                            $FirstOctet,$SecondOctet,$ThirdOctet,$FourthOctet)
                        }
                    }
                }
                $sBlock = $TotalIPs - ($blocks * 256)
                if ($sBlock -gt 0) {
                    1..$SBlock | %{
                        if ($FourthOctet -eq 255) {
                            If ($ThirdOctet -eq 255) {
                                If ($SecondOctet -eq 255) {
                                    $FirstOctet++
                                    $secondOctet = 0
                                } else {
                                    $SecondOctet++
                                    $ThirdOctet = 0
                                }
                            } else {
                                $FourthOctet = 0
                                $ThirdOctet++
                            }  
                        } else {
                            $FourthOctet++
                        }
                        Write-Output ("{0}.{1}.{2}.{3}" -f `
                        $FirstOctet,$SecondOctet,$ThirdOctet,$FourthOctet)
                    }
                }
            }
        }
    }
    Process {
        #get every ip in scope
        Get-IPRange $IP $netmask | %{
            [void]$IPs.Add($_)
        }
        #loop untill we've pinged them all
        While ($IPs.count -gt 0 -or $jobs.count -gt 0) {
            #if we have open spots kick off some more
            IF ($jobs.count -le $max) {
                # determin how many to kick off
                $addjobs = ($max - $jobs.count)
                Foreach ($IP in ($IPS | Select -first $addjobs)) {
                    #save the job id, and move on
                    [VOID]$Jobs.Add((gwmi -q "SELECT Address,StatusCode FROM Win32_Pingstatus WHERE Address = `'$IP`'" -asjob).Id)
                    #remove the IP from our pool
                    $IPs.Remove($IP)
                }
            }
            #we'll use this array to track what's comeback
            $Clean = @()
            
            Foreach ($J in $jobs) {
                # If this job is done get the results
                if ((Get-Job -id $j).JobStateInfo.state -eq 'Completed') {
                    # if the ping was sucessfull return the IP Address
                    write-output (Receive-Job -id $j) | ?{$_.StatusCode -eq 0}| select -expand Address
                    # dispose of the job
                    remove-job -id $j
                    $clean += $j
                }
            }
            Foreach ($c in $Clean) {
                #remove the jobs that we just processed
                $jobs.remove($c)
            }
        }
    }
}

Ping-Subnet 192.168.70.20 /24

Reference: http://poshcode.org/976

All information on this site is shared with the intention to help. Before any source code or program is ran on a production (non-development) system it is suggested you test it and fully understand what it is doing not just what it appears it is doing. I accept no responsibility for any damage you may do with this code.

Related

Code PowerShell

Post navigation

Previous post
Next post

Related Posts

Useful CSVKit Commands

Posted on May 14, 2015

# Cleans a CSV file of common syntax errors. csvclean -n myfile.csv # Shows you stats about the file (e.g. col names, type, nulls, min, max, median, std deviation, unique values, most frequent) $csvstat myfile.csv # Peak at excel file to display in terminal $in2csv myfile.xlsx $in2csv myfile.xlsx > myfile.csv…

Read More

AES Encrypted SSO – C# to PHP

Posted on March 25, 2013October 26, 2015

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="csharp.aspx.cs" Inherits="csharp" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>CSharp to PHP</title> </head> <body> <form id="form1" runat="server"> <div id="divDebugInfo" runat="server" visible="false"> </div> </form> </body> </html> using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; #region AES Pass-Through – Start using System.Security.Cryptography; using System.Text;…

Read More

PowerShell – Script for adding/removing/viewing entries to the hosts file.

Posted on March 7, 2019

As a web developer you often have to use a host file, this script helps assist a safe and fast change with little effort. # # Powershell script for adding/removing/showing entries to the hosts file. # # Known limitations: # – does not handle entries with comments afterwards ("<ip> <host>…

Read More

Code

Top Posts & Pages

  • PowerShell - Rename Pictures to Image Taken
  • Front Page
  • C# - Start/Stop/Restart Services
  • MacPorts / HomeBrew - Rip CD tracks from terminal
  • PowerShell - Show File Extensions

Recent Posts

  • Javascript – Digital Clock with Style
  • BASH – Web Ping Log
  • BASH – Picture / Video File Name Manipulation
  • Mac OSX Terminal – Create SSH Key
  • Bash – Rename Picture

Top Posts

  • PowerShell - Rename Pictures to Image Taken
  • C# - Start/Stop/Restart Services
  • MacPorts / HomeBrew - Rip CD tracks from terminal
  • PowerShell - Show File Extensions
  • SQLite - Auto-Increment / Auto Generate GUID
©2025 David Kittell | WordPress Theme by SuperbThemes