Как захватить таблицу ARP и вывести ее в файл в Powershell

У меня возникли проблемы с поиском ответа на этот вопрос. Поэтому я решил поделиться тем, что я создал, с массами. Что я пытался сделать, так это запустить команду ARP -a и зафиксировать результаты, чтобы использовать их в файле TXT для чего-то другого позже. После долгих поисков я смог скомпилировать это.

Я включил примечания в код, чтобы помочь менее опытным пользователям понять, что делает каждый раздел.

Но этот код делает эти компоненты

  1. Установите выходной путь (при необходимости)
  2. Ищет текущие IP-адреса машин
  3. Разбивает схему IP для размещения только первых 3 октетов. * Там есть строка кода #, если вы используете машину с несколькими сетевыми картами или IP-адресами, чтобы вы могли фильтровать только один необходимый IF.
  4. Захватывает таблицу ARP. *У меня есть 2 версии захвата ARP. Первый — ЕСЛИ вы собираетесь фильтровать по схеме IP-адресов устройств. Это поможет удалить записи DNS и замыкания на себя. Во-вторых, если вы хотите ВСЕ.
  5. Выводит результаты IP-адресов в текстовый файл.

В моем случае я использую его только для фильтрации IP-адресов. Он может понадобиться вам для других целей. Хорошей новостью является то, что можно легко изменить части, чтобы вы могли больше фильтровать в соответствии с вашими потребностями.

    #Captures ARP Table then Displays ALL IPs that match the local computers IP Address

#Set the file you wish for the data to Output to
$OutputPath = "C:\Temp\Test.txt"

#Captures the devices IP Scheme and break it down, remove the Last Octet from the string
#This section is only used IF you are trying to filter the ARP by the local network the device is on.
[string[]]$ComputerName = $env:computername
$OrgSettings = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -EA Stop | ? { $_.IPEnabled }
$ip = $OrgSettings.IPAddress[0]
#IF (!($ip[1] -eq $null)) {$ip = $ip[0]}
$ip = (([ipaddress] $ip).GetAddressBytes()[0..2] -join ".") + "."
$ip = $ip.TrimEnd(".")

#Searches the ARP table for IPs that match the scheme and parses out the data into an Array (It removed the Devices IP from the list.)
Remove-Variable macarray
$macarray = @()
#(arp -a) -match $ip | Foreach{ #Use if needed for filtering results
(arp -a) | Foreach{    #Use this IF no filtering needed
      $obj = New-Object PSObject -Property @{
        IP  = ($_ -split "\s+")[1]
        MAC = ($_ -split "\s+")[2]
      }
     IF (!($obj.MAC -eq "---" -or $obj.MAC -eq "Address" -or $obj.MAC -eq $null -or $obj.MAC -eq "ff-ff-ff-ff-ff-ff")) {$macarray += $obj}
  }

#Outputting the IP Addresses captured.
$macarray | Select -ExpandProperty "IP" | Out-file -FilePath $OutputPath -Force

person Ross G    schedule 25.10.2016    source источник
comment
Я действительно не вижу здесь вашего вопроса. Что именно не так?   -  person Matt    schedule 25.10.2016
comment
Windows8/Server2012 или более поздней версии имеет командлет Get-NetNeighbor.   -  person BenH    schedule 25.10.2016
comment
Вы просто рекламируете свой код для использования? Было бы более уместно, если бы вы использовали для этого GitHub или что-то в этом роде.   -  person Matt    schedule 25.10.2016


Ответы (1)


Вот что я использую при разборе текстовых таблиц. Этот код работает, когда заголовки выровнены по левому краю с данными под ними. Хитрость в том, что arp будет показывать данные для нескольких интерфейсов. Если вам нужно отфильтровать на основе этого, то эта логика сгенерирует пользовательский массив объектов, который вы можете фильтровать или выводить в файл, теперь с Export-CSV, по мере необходимости. Если вам нужно больше информации о том, что происходит внутри циклов, это можно узнать из еще один мой ответ.

Этот подход основан на расположении полей заголовка. Ничто не жестко закодировано, и все это создается на основе этих индексов и имен полей. Используя эти $headerIndexes, мы разделяем каждую строку и помещаем результаты, если они есть, в соответствующий столбец. Существует логика, гарантирующая, что мы не попытаемся захватить какую-либо часть строки, которая может не существовать, и обработать последнее поле как особое.

$arpResults = arp.exe -a | Out-String
$arpResults | Select-string -Pattern '(?smi)((?<=Interface:).*?(?=Interface:|\Z))' -AllMatches | 
        Select-Object -ExpandProperty Matches | ForEach-Object{
    $interfaceData = $_.Groups[0].Value.Trim() -split "`r`n"

    # Header of the data table is the second array element.
    $headerString = $interfaceData[1]
    $headerElements = $headerString -split "\s{2,}" | Where-Object{$_}
    $headerIndexes = $headerElements | ForEach-Object{$headerString.IndexOf($_)}

    # Skip the first two lines as they are for the interface address and header for each table
    $interfaceData | Select-Object -Skip 2 | ForEach-Object{
        $props = @{Interface = $interfaceData[0].Trim()}
        $line = $_
        For($indexStep = 0; $indexStep -le $headerIndexes.Count - 1; $indexStep++){
            $value = $null            # Assume a null value 
            $valueLength = $headerIndexes[$indexStep + 1] - $headerIndexes[$indexStep]
            $valueStart = $headerIndexes[$indexStep]
            If(($valueLength -gt 0) -and (($valueStart + $valueLength) -lt $line.Length)){
                $value = ($line.Substring($valueStart,$valueLength)).Trim()
            } ElseIf ($valueStart -lt $line.Length){
                $value = ($line.Substring($valueStart)).Trim()
            }
            $props.($headerElements[$indexStep]) = $value    
        }
        [pscustomobject]$props
    } 

} | Select-Object Interface, "Internet Address","Physical Address",Type

Пример частичного вывода

Interface               Internet Address Physical Address  Type   
---------               ---------------- ----------------  ----   
10.10.13.153 --- 0xb    224.0.0.252      01-00-5e-00-00-fc static 
10.10.13.153 --- 0xb    228.5.6.7        01-00-5e-05-06-07 static 
10.10.13.153 --- 0xb    239.255.255.250  01-00-5e-7f-ff-fa static 
10.10.13.153 --- 0xb    255.255.255.255  ff-ff-ff-ff-ff-ff static 
169.254.215.111 --- 0xc 169.254.255.255  ff-ff-ff-ff-ff-ff static 
169.254.215.111 --- 0xc 224.0.0.22       01-00-5e-00-00-16 static 

Как указывает BenH в комментариях ..

В Windows8/Server2012 или более поздней версии есть командлет Get-NetNeighbor.

person Matt    schedule 25.10.2016