Get Free Ip Address in a DHCP server in reservation mode

Good morning everyone,
First of all I’d like to apologize for my English as I’m French.
I am a beginner in powershell in an internship as a technician where my administrator asked me to get all non used Ip adresses. The goal is for them to be able to easily find which Ip address to give to someone new in the company.
I cannot use the cmdlet Get-DhcpServer4FreeIpAdress as it excludes all reserved addresses.
So my plan was to use Get-DhcpServer4Lease then to use an operation in which I will take each Ip address and add +1, whenever the Ip address isn’t match in the list it would be displayed.
So far I tried with where-object after a pipe but it wasn’t conclusive at all… if you could help me?
Thank you !!

Math,
Welcome to the forum. :wave:t3:

Nobody is perfect. :wink:

Hmmm … why not using Get-DhcpServer4FreeIpAdress AND Get-DhcpServerv4Reservation and comapre them with Compare-Object?

Regardless of that …

Please do describe your code - post it! :wink:

When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org 1 <---- Click :point_up_2:t4: :wink:

( !! Sometimes the preformatted text button hides behind the settings gear symbol. :wink: )

< $tableau = @()
$ipa = Get-DhcpServerv4Lease -ComputerName "dhcpservername" -ScopeId 192.168.0.0(just an exemple) | Select-Object IPAddress
function IncrementLastOctet($ipAddress) {
$octets = $ipAddress -split '\.'
    $lastOctet = [int]$octets[-1]
    $newLastOctet = ($lastOctet + 1) 
    $octets[-1] = $newLastOctet
        return $octets -join '.'
}
foreach($ip in $ipa){
    $NouvelleAddresseIP = IncrementLastOctet $ip 
    if ($tableau -notcontains $NouvelleAddresseIP) {
        $tableau += $NouvelleAddresseIP  
    }
}>

I cannot use Get-DhcpServerv4FreeIpAddress as the server is set on ip reservation and there’s an exclusion range that cover the entire network. For security reasons they have practically removed the main purpose of a dhcp server. So when I try that cmdglet I get

I get a warning saying that it cannot find free IP addresses. But when I use Get-DhcpServerv4Lease I can see that Ip addresses are missing.

In my code I tried to focus on the last octet to add +1 and whenever the ip address that’s supposed to be found isn’t, it writes it in the board ( $tableau). But so far it hasn’t worked out.

“Hasn’t worked out” please explain what this means. What was expected? What happened instead?

Good morning,
Yes sorry, I expected it to take every Ip adresses, add +1 at the end and check if it was in my ip adress list. For exemple it should analyze 10.32.151.20, add + 1 to the last octet then check if 10.32.151.21 is on the list given by the cmdlet “Get-DhcpServerv4Lease”(at the beginning of my code). If the IP address is on the list it does nothing, if not it should display it in the chart.
That’s why I tried to use every last octet as int and not string.
Instead I got an error message telling me that it couldn’t convert the every value in “System.Int32”. Error: the input string is incorrect for $lastoctet = [int]$octects[-1].

"Impossible de convertir la valeur « 99} » en type « System.Int32 ». Erreur : « Le format de la chaîne d'entrée est incorrect. »
Au caractère C:\Users\myname\Documents\script\testchiffrred.ps1:6 : 5
+     $lastOctet = [int]$octets[-1]
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument : (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToInteger

I apologize as it is writen in french and I thank you for your kind help.

What a bullshit. :roll_eyes:

I think you are overcomplicating this. :smirk:

I assume you have the information about the IP ranges you use. And I understood that you can get the IP leases. That’s all you need I’d think.

Let’s say you want to check the IP range from 192.168.0.1 to 192.168.0.32. Then you simply create a reference like this:

$IPRange = 1..32 |
    ForEach-Object {
        '192.168.0.{0}' -f $_
    }

Let’s say you have got the IP leases in a variable $IPLeases:

$IPLeases = 
'192.168.0.9',
'192.168.0.8',
'192.168.0.17',
'192.168.0.16',
'192.168.0.25',
'192.168.0.24',
'192.168.0.31'

Now you simply compare theses two variables with Compare-Object

Compare-Object -ReferenceObject $IPRange -DifferenceObject $IPLeases -IncludeEqual

I included the parameter -IncludeEqual just to show the general function. Of course you could omit it since you’re interested in the free IP addresses.
The output would be this:

InputObject  SideIndicator
-----------  -------------
192.168.0.8  ==
192.168.0.9  ==
192.168.0.16 ==
192.168.0.17 ==
192.168.0.24 ==
192.168.0.25 ==
192.168.0.31 ==
192.168.0.1  <=
192.168.0.2  <=
192.168.0.3  <=
192.168.0.4  <=
192.168.0.5  <=
192.168.0.6  <=
192.168.0.7  <=
192.168.0.10 <=
192.168.0.11 <=
192.168.0.12 <=
192.168.0.13 <=
192.168.0.14 <=
192.168.0.15 <=
192.168.0.18 <=
192.168.0.19 <=
192.168.0.20 <=
192.168.0.21 <=
192.168.0.22 <=
192.168.0.23 <=
192.168.0.26 <=
192.168.0.27 <=
192.168.0.28 <=
192.168.0.29 <=
192.168.0.30 <=
192.168.0.32 <=

… and is easily processable with PowerShell. :wink:

Woaw… THANK YOU. It’s almost what I am looking for, it does help a lot. It works for your code but for mine as I get my ip address list from the Get-DhcpServerv4Lease it appears as such :

@{IPAddress=172.16.251.208} =>
@{IPAddress=172.16.251.209} =>
@{IPAddress=172.16.251.210} =>
@{IPAddress=172.16.251.243} =>
@{IPAddress=172.16.251.249} =>
172.16.251.208              <=
172.16.251.209              <=
172.16.251.210              <=
172.16.251.211              <=
172.16.251.212              <=
172.16.251.213              <=
172.16.251.214              <=
172.16.251.215              <=
172.16.251.216              <=
172.16.251.217              <=
         

Some of the IP addresses listed here are used and listed in the Lease.
In my code I have used :

$ipa = Get-DhcpServerv4Lease -ComputerName "servername" -ScopeId 172.16.251.0 | Select-Object IPAddress

The displayed result is as such :

172.16.251.208
172.16.251.209
172.16.251.210
172.16.251.243
172.16.251.249

There isn’t a table format… So I don’t really understand why the data return differently
I cannot thank you enough though.

Change it to:

$ipa = 
    Get-DhcpServerv4Lease -ComputerName "servername" -ScopeId 172.16.251.0 | 
        Select-Object -ExpandProperty IPAddress

Thank you very much ! It works ! I have another question as a student : How can I get efficiently better at scripting in powershell, as it is hard to find a place where informations about it are very complete. I find your knowledge truly astonishing !

Practice, practice, practice. :man_shrugging:t3:

Find a problem you think you mey solve with a script and start googling if there’s already some code available for. If you find something - learn from it. And maybe improve it or adapt it to your particular needs. There is no shortcut where you get all needed information at one place. Sorry.

Just for your reference … I do PowerShell for about 16 years now. :wink:

Wow ok I understand why now ! Thank you for your advices I’ll do my best to improve myself ! I don’t really like asking for help and bother people haha