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?
Is the input list available addresses or used addresses?
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
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
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
$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”
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
}
}
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!