2

I've got a /20 network and I want to know all used IP Addresses and their attributes like the MAC, the name and the description plus all free addresses between the used ones so that I got a long list where I can see if the address is taken or not. Luckily I got a Server2012 so that I can use the CMDLets of Microsoft. My aproach was to generate all possible addresses. At the end I want a list which looks like smth like this:

IP, Mac, Name, Comment
19.0.0.0, 00:00:11:11:11:01, TestUser_1, This is the 1st Testuser
. (here are some used and some free)
.
19.0.2.45 (this one is free)
.
19.0.6.3 (this one is free, too)
19.0.11.201, 11:22:33:44:55:66, TestUser_N, This is just another comment

Sampe Code:

$x=0
$y=0
$ipstring = "19.0."
for ($i=$x;$i -le 15; $i++)
{
   for ($j=$y;$j -le 255;$j++)
   {
      $gesIP = $ipstring+"$i"+"."+"$j"
   }
}

The code above creates addresses between 19.0.0.0 to 19.0.15.255

Now I need to get my used addresses:

$usedAddresses = Get-DhcpServerv4Reservation -ComputerName $env:computername -ScopeId ((Get-DhcpServerv4Scope -ComputerName $env:computername).IPAddress.IPAddressToString)

In order of looking witch addresses are free I was thinking about to compare the addresses. I wasn't quite sure if the lists of objects are sorted. So I tried to sort them using the following algorithm:

$IP_sort = $IPv4_res  | Sort-Object {"{0:d3}.{1:d3}.{2:d3}.{3:d3}" -f @([int[]]$_.IPAddress.IPAddressToString.split('.'))}

After that I saved 'em

foreach ($ine in $IP_sort)
{
write-output ("{0}  {1}  {2}  {3}" -f ($ine).IPAddress.IPAddressToString, ($ine).ClientId, ($ine).Description, ($ine).Name) | ac EnterPlaceAndTextfileHere
}

Now I got 2 sorted lists where I just need to compare each other. The first list contains all addresses, the second contains only the used addresses.

Now I need to compare those two lists. I tried to manage it like that:

if ($ges_IP -eq $IP_sort[$k].IPAddress.IPAddressToString)
{
  write-output ("{0}  {1}  {2}  {3}" -f ($IPv4_res[$k]).IPAddress.IPAddressToString, ($IPv4_res[$k]).ClientId, ($IPv4_res[$k]).Name, ($IPv4_res[$k]).Description) | ac EnterPlaceAndTextfileHere
}
else
{
   $ges_IP | ac EnterPlaceAndTextfileHere
}        

Now I got one big list which would be sorted - hopefully.
But unfortunaltey I got some errors. Some addresses does not match the other attributes and some adresses are not in the correct order. I was wondering why... Is my code wrong? Do I think too complicated or does powershell manage to place this much addresses at the wrong order sometimes and it "just happens" sometime?

1

When using Sort-Object you are sorting the IP address as it was a string.

Consider:

19.0.9.234
19.0.15.5

When the example is sorted ascending as a string, 19.0.15.5 is ordered before 19.0.9.234.

While 15 is bigger then 9, when a string is sorted only characters in the same string position are considered, I.e. 1 vs 9.

One solution would be to pad the IP octets with 0, there by make the strings the same length and lining the octets up. I.e. 015, 009.

You could do this with Sort-Object as a calculated property or before your store each of your source data sets.

I.e.

Sort-Object -Property @{ Expression = { [String]::Join('.',  $_.IPAddress.IPAddressToString.Split('.').PadLeft('0', 3)); } }

Hope that helps.

  • I have already solved this problem by myself. But thaks for your effort. – Sascha R. Feb 16 '15 at 6:34
2

I know this is already solved, but am just wanting to add this option for people who find this page on google.

This way doesn't use any string manipulation:

Get-DhcpServerv4Reservation -ComputerName $env:computername -ScopeId ((Get-DhcpServerv4Scope -ComputerName $env:computername).IPAddress.IPAddressToString)  | sort -Property { [Version]$_.IPAddress.IPAddressToString }

or

$dhcpreservations | sort -Property { [Version]$_.IPAddress.IPAddressToString }

edit: removed System as Ryan Bolgar is correct

  • You don't even need the 'System.' prefix. You can use use [Version]. – Ryan Bolger Apr 20 '17 at 3:23
0

Converting to a hexadecimal string works for both IPv4 and IPv6 addresses. function ConvertTo-HexString { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [byte[]] $Byte )

    begin
    {
        [char[]] $digits = @('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
        [System.Text.StringBuilder] $hexString = New-Object System.Text.StringBuilder
    }

    process
    {
        foreach ($byteValue in $Byte)
        {
            [void] $hexString.Append($digits[$byteValue -shr 4])
            [void] $hexString.Append($digits[$byteValue -band 0x0F])
        }
    }

    end
    {
        return $hexString.ToString();
    }
}

# Because the number of bytes in the different address families is variable, 
# sort by the AddressFamily first and then the hexadecimal string.
$ipAddresses | Sort AddressFamily, @{ expression = { ConvertTo-HexString $_.GetAddressBytes() } }

DHCP reservations can be sorted like this:

Get-DhcpServerv4Reservation -ComputerName $ComputerName -ScopeId $ScopeId | Sort @{ expression = { $_.IPAddress.AddressFamily } }, @{ expression = { ConvertTo-HexString $_.IPAddress.GetAddressBytes() } }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.