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

Update Windows Date/Time

Posted on December 8, 2013February 12, 2016

cls date 11-27-2013 time 5:19:00 PM w32tm /config /syncfromflags:manual /manualpeerlist:"time.windows.com" net stop w32time net start w32time w32tm /resync w32tm /resync pause GitHub: https://gist.github.com/dkittell/c3c930d1b432d51ebb71 Originally Posted on December 8, 2013Last Updated on February 12, 2016 All information on this site is shared with the intention to help. Before any source code…

Read More

Mac OS – Azure CLI Setup

Posted on September 15, 2017June 26, 2019

Download from Microsoft curl -L https://aka.ms/InstallAzureCli | bash echo "alias az=’$HOME/bin/az’" >> ~/.bash_profile exec -l $SHELL Install using HomeBrew brew update brew install azure-cli brew upgrade azure-cli Originally Posted on September 15, 2017Last Updated on June 26, 2019 All information on this site is shared with the intention to help….

Read More

MSSQL DateTime Conversions

Posted on June 23, 2014December 26, 2018

Sometimes a basic function like MSSQL Format Date Function can not work as you do not have permission to create a function or you simply need something quick. To get day of week from DateTime column and order it by the proper day of week order. This is rather easy…

Read More

Code

Top Posts & Pages

  • Front Page
  • PowerShell - Rename Pictures to Image Taken
  • SQLite - Auto-Increment / Auto Generate GUID
  • PowerShell - Get Text Encoding Type
  • TeamCity - Mac Agent Install

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
  • SQLite - Auto-Increment / Auto Generate GUID
  • PowerShell - Get Text Encoding Type
  • TeamCity - Mac Agent Install
  • PowerShell - UNIX SED Equivalent - Change Text In File
  • Bleaching Wool using Hydrogen Peroxide
©2025 David Kittell | WordPress Theme by SuperbThemes
David Kittell
  • Services
    • Application Development
    • Online Application Integration
  • Code
  • Online Tools
  • Tech Support