Find IP addresses available in a list

This topic contains 7 replies, has 5 voices, and was last updated by Profile photo of Vandrey Trindade Vandrey Trindade 1 year, 11 months ago.

  • Author
    Posts
  • #29068
    Profile photo of Vandrey Trindade
    Vandrey Trindade
    Participant

    Hi again,

    I'm trying to create a code that shows me what IPs are available in a range:

    Let's suppose this string variable content:

    192.168.47.1
    192.168.47.2
    192.168.47.3
    192.168.47.4
    192.168.47.6
    192.168.47.7
    192.168.47.8
    192.168.47.9
    192.168.47.14
    192.168.47.47
    192.168.47.244

    Is there an easy way to know the first IP address available?

  • #29069
    Profile photo of Tim Curwick
    Tim Curwick
    Participant

    Is the input list available addresses or used addresses?

  • #29070
    Profile photo of Will Anderson
    Will Anderson
    Keymaster

    If it's being fed into your script as an array, you can always pipe it to Select-Object -First 1 and it'll give you the first object in your array. If it's a continuous string, you'll have to get more creative. For Example:

    [string]$IPAddress = Get-Content C:\scripts\ipaddress.txt
    
    $IPAddress.Split(' ') | Select-Object -First 1

    Will change your output from this:

    PS C:\WINDOWS\system32> $IPAddress
    192.168.47.1 192.168.47.2 192.168.47.3 192.168.47.4 192.168.47.6 192.168.47.7 192.168.47.8 192.168.47.9 192.168.47.14 192.168.47.47 1
    92.168.47.244

    To this:

    PS C:\WINDOWS\system32> $IPAddress.Split(' ')
    192.168.47.1
    192.168.47.2
    192.168.47.3
    192.168.47.4
    192.168.47.6
    192.168.47.7
    192.168.47.8
    192.168.47.9
    192.168.47.14
    192.168.47.47
    192.168.47.244
    
    PS C:\WINDOWS\system32> $IPAddress.Split(' ') | Select-Object -First 1
    192.168.47.1
  • #29071
    Profile photo of Vandrey Trindade
    Vandrey Trindade
    Participant

    Tim Curwick,

    Used addresses.

    Will Anderson,

    It's an array, but I need the first one available.
    In my example it should be IP address: 192.168.47.5

  • #29072
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    This would compare the entire range against what is used and provide the first IP. The only thing that gets a bit more sticky is if you need to sort because you would have to pad each subnet with zero, but this is the general code you'll need:

    #Get used IP's from a file
    $ipFile = Get-Content C:\Temp\test.txt
    
    #Convert it to a PSObject 
    $usedIPs = $ipFile | foreach{
        New-Object -TypeName PSObject -Property @{IP=$_}
    }
    
    #Create a PSObject with all possible IPs in the range
    $allIPs = for ($i=1;$i -le 255;$i++){
        New-Object -TypeName PSObject -Property @{IP=("192.168.47.{0}" -f $i)}
    }
    
    #Compare the objects and that are in the all IP's and not in the used and select the first one
    Compare-Object -ReferenceObject $allIPs -DifferenceObject $usedIPs -Property IP -PassThru | 
    Where {$_.SideIndicator -eq "< ="} |
    Select -ExpandProperty IP -First 1
    
  • #29073
    Profile photo of Tim Curwick
    Tim Curwick
    Participant

    $UsedIPs = @'
    192.168.47.1
    192.168.47.2
    192.168.47.3
    192.168.47.4
    192.168.47.6
    192.168.47.7
    192.168.47.8
    192.168.47.9
    192.168.47.14
    192.168.47.47
    192.168.47.244
    '@

    $UsedOctets = $UsedIPs.Split( "`n" ) | ForEach { [int]$_.Split( '.' )[-1] }

    $FirstAvailableOctet = 1..255 | Where { $UsedOctets -notcontains $_ } | Select -First 1

    "192.168.47.$FirstAvailableOctet"

  • #29110
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    Slightly different approach using the "[version] magic" to split out the octets.

    $usedIps = @'
    192.168.47.1
    192.168.47.2
    192.168.47.3
    192.168.47.4
    192.168.47.6
    192.168.47.7
    192.168.47.8
    192.168.47.9
    192.168.47.14
    192.168.47.47
    192.168.47.244
    '@ -split "`r`n"
    $pattern = [regex]"((\d{1,3}\.){3})"
    $ptr = 0
    $usedIps[0] -match $pattern | Out-Null
    $net = $Matches[1]
    $usedIps | foreach {
        if (([version]$_).Revision -eq ($ptr + 1))
        {
            Write-Verbose "Saw $_"
            $ptr++
        }
        else
        {
            "Next IP is $net$($ptr + 1)"
            break
        }
    }
    
  • #29149
    Profile photo of Vandrey Trindade
    Vandrey Trindade
    Participant

    Will Anderson, Tim Curwick, Rob Simmers and Bob McCoy,

    Thank you all for the help.
    I'm having some personal problems at the moment and that's why I took so long to answer.

    Thank you once again!

You must be logged in to reply to this topic.