Powershell - Sort-Objects, lista de endereços IP

2

Eu tenho uma rede / 20 e quero saber todos os endereços IP usados e seus atributos, como o MAC, o nome e a descrição, além de todos os endereços livres entre os usados, para que eu tenha uma longa lista onde posso veja se o endereço foi recebido ou não. Felizmente eu tenho um Server2012 para que eu possa usar os CMDLets da Microsoft. Minha abordagem foi gerar todos os endereços possíveis. No final eu quero uma lista que se pareça com isso:

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

Código 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"
   }
}

O código acima cria endereços entre 19.0.0.0 e 19.0.15.255

Agora preciso dos meus endereços usados:

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

Por ordem de procurar bruxas, os endereços são gratuitos e eu estava pensando em comparar os endereços. Eu não tinha certeza se as listas de objetos são classificadas. Então tentei classificá-los usando o seguinte algoritmo:

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

Depois disso eu salvei eles

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

Agora eu tenho duas listas classificadas, onde só preciso comparar umas às outras. A primeira lista contém todos os endereços, o segundo contém apenas os endereços usados.

Agora preciso comparar essas duas listas. Eu tentei gerenciar assim:

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
}        

Agora eu tenho uma lista grande que seria classificada - esperançosamente.
Mas unfortunaltey eu tenho alguns erros. Alguns endereços não correspondem aos outros atributos e alguns endereços não estão na ordem correta. Eu estava me perguntando por que ... Meu código está errado? Eu acho muito complicado ou o PowerShell consegue colocar tantos endereços na ordem errada às vezes e isso "simplesmente acontece" em algum momento?

    
por Sascha R. 22.10.2014 / 08:27

3 respostas

1

Ao usar Sort-Object , você está classificando o endereço IP como se fosse uma string.

Considere:

19.0.9.234
19.0.15.5

Quando o exemplo é classificado como crescente, 19.0.15.5 é ordenado antes de 19.0.9.234.

Enquanto 15 é maior que 9, quando uma string é classificada, somente caracteres na mesma posição são considerados, ou seja, 1 vs 9.

Uma solução seria preencher os octetos IP com 0, fazendo as sequências do mesmo tamanho e alinhando os octetos. Ou seja 015, 009.

Você poderia fazer isso com Sort-Object como uma propriedade calculada ou antes de armazenar cada um dos seus conjuntos de dados de origem.

Ou seja,

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

Espero que ajude.

    
por 14.02.2015 / 00:47
2

Eu sei que isso já está resolvido, mas estou apenas querendo adicionar essa opção para as pessoas que encontrarem essa página no google.

Dessa forma, não é usada manipulação de string:

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

ou

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

edit: sistema removido como Ryan Bolgar está correto

    
por 20.04.2017 / 02:15
0

A conversão para uma cadeia hexadecimal funciona para endereços IPv4 e IPv6.     função ConvertTo-HexString     {         [CmdletBinding ()]         param         (             [Parâmetro (obrigatório = $ 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() } }

As reservas DHCP podem ser classificadas da seguinte forma:

Get-DhcpServerv4Reservation -ComputerName $ComputerName -ScopeId $ScopeId | Sort @{ expression = { $_.IPAddress.AddressFamily } }, @{ expression = { ConvertTo-HexString $_.IPAddress.GetAddressBytes() } }
    
por 11.06.2018 / 20:33