Powershell - Sort-Objects, список IP-адресов

У меня есть сеть /20, и я хочу знать все используемые IP-адреса и их атрибуты, такие как MAC-адрес, имя и описание, а также все свободные адреса между используемыми, чтобы я получил длинный список, в котором я могу увидеть, адрес взят или нет. К счастью, я получил Server2012, чтобы я мог использовать CMDLets от Microsoft. Мой подход был для генерации всех возможных адресов. В конце я хочу список, который выглядит как что-то вроде этого:

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:

$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"
   }
}

Приведенный выше код создает адреса от 19.0.0.0 до 19.0.15.255

Теперь мне нужно получить мои используемые адреса:

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

В порядке поиска адресов ведьм, я думал о том, чтобы сравнить адреса. Я не был уверен, отсортированы ли списки объектов. Поэтому я попытался отсортировать их, используя следующий алгоритм:

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

После этого я спас их

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

Теперь я получил 2 отсортированных списка, где мне просто нужно сравнить друг друга. Первый список содержит все адреса, второй содержит только используемые адреса.

Теперь мне нужно сравнить эти два списка. Я пытался управлять этим так:

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
}        

Теперь у меня есть один большой список, который будет отсортирован - надеюсь.
Но, к сожалению, я получил некоторые ошибки. Некоторые адреса не соответствуют другим атрибутам, а некоторые адреса не в правильном порядке. Мне было интересно, почему... Мой код неверен? Считаю ли я слишком сложным или PowerShell может иногда размещать столько адресов в неправильном порядке, а иногда это "просто случается"?

3 ответа

Решение

Когда используешь Sort-Object Вы сортируете IP-адрес как строку.

Рассматривать:

19.0.9.234
19.0.15.5

Когда пример отсортирован по возрастанию в виде строки, 19.0.15.5 упорядочивается до 19.0.9.234.

Хотя 15 больше, чем 9, при сортировке строки учитываются только символы в одной и той же позиции строки, т.е. 1 против 9.

Одним из решений было бы заполнение октетов IP 0, чтобы строки имели одинаковую длину и выравнивали октеты. Т.е. 015, 009.

Вы могли бы сделать это с Sort-Object в качестве расчетного свойства или перед вашим магазином каждый из ваших исходных наборов данных.

Т.е.

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

Надеюсь, это поможет.

Я знаю, что это уже решено, но я просто хочу добавить эту опцию для людей, которые находят эту страницу в Google.

Этот способ не использует никаких манипуляций со строками:

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

или же

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

редактировать: удалена система как Райан Болгар правильно

Преобразование в шестнадцатеричную строку работает как для адресов IPv4, так и для адресов IPv6. function ConvertTo-HexString { [CmdletBinding()] param ( [Параметр (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 можно отсортировать так:

Get-DhcpServerv4Reservation -ComputerName $ComputerName -ScopeId $ScopeId | Sort @{ expression = { $_.IPAddress.AddressFamily } }, @{ expression = { ConvertTo-HexString $_.IPAddress.GetAddressBytes() } }
Другие вопросы по тегам