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() } }