2015-12-29 3 views
0

ЦЕЛЬ: получить массив, содержащий имя хоста (через DNS, пустое, если не найденное), MAC-адрес и IP-адрес активных устройств в сети. Это должно работать для не-windows-устройств (коммутаторы, хосты ESX и т. Д.), Поэтому WMI отключен.Получить список MAC-адресов из pingable IP-адресов

То, что я до сих пор, на основе этого post:

[CmdletBinding()] 
Param (
    [string]$Network = "192.168.1", 
    [int]$IPStart = 1, 
    [int]$IPEnd = 255 
) 

$outArray = @() 
ForEach ($IP in ($IPStart..$IPEnd)) 
{ 
    Try { 
     $Ping = Get-WMIObject Win32_PingStatus -Filter "Address = '$Network.$IP' AND ResolveAddressNames = TRUE" -ErrorAction Stop 
    } 
    Catch { 
     $windows = 0 
     $hostname = ([system.net.dns]::GetHostByAddress($IP)).hostname 
     Continue 
    } 
    if ($Ping.StatusCode -eq 0) 
    { 
     Try { 
      $Adapters = Get-WmiObject Win32_NetworkAdapter -Filter "NetEnabled = True" -ComputerName $Ping.ProtocolAddressResolved -ErrorAction Stop 
     } 
     Catch { 
      $windows = 0 
      Continue 
     } 
     if ($windows -ne 0) { 
      ForEach ($Adapter in $Adapters) 
      { $Config = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "Index = $($Adapter.Index)" -ComputerName $Ping.ProtocolAddressResolved 
       ForEach ($IPAddr in $Config.IPAddress) 
       { $adapterInfo = New-Object PSObject -Property @{ 
         Host = $Ping.ProtocolAddressResolved 
         'Interface Name' = $Adapter.Name 
         'IP Address' = $IPAddr 
         'MAC Address' = $Config.MACAddress 
        } 
        $outArray += $adapterInfo 
       } 
      } 
     } 
    } 
    Else { 
     $MACAddress = ?  # NEED THIS INFORMATION 

     $hostinfo = New-Object PSObject -Property @{ 
       Host = "" 
       'Interface Name' = "" # Don't care in this instance. Placeholder to keep the array happy 
       'IP Address' = $IP 
       'MAC Address' = $MACAddress 
      } 
     $outArray += $hostInfo 
    } 
} 

$outArray | Export-CSV -Path .\ipinfo.csv -notypeinformation 

EDIT: Вот окончательный рабочий сценарий для тех, кто хочет к нему в качестве ссылки. Функция от here.

[CmdletBinding()] 
Param (
    [string]$Network = "192.168.1", 
    [int]$IPStart = 1, 
    [int]$IPEnd = 254 
) 

### FUNCTIONS ### 
Function Get-MACFromIP { 
param ($IPAddress) 

$sign = @" 
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Net; 
using System.Net.NetworkInformation; 
using System.Runtime.InteropServices; 

public static class NetUtils 
{ 
    [System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)] 
    static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen); 

    public static string GetMacAddress(String addr) 
    { 
     try 
       {     
        IPAddress IPaddr = IPAddress.Parse(addr); 

        byte[] mac = new byte[6]; 

        int L = 6; 

        SendARP(BitConverter.ToInt32(IPaddr.GetAddressBytes(), 0), 0, mac, ref L); 

        String macAddr = BitConverter.ToString(mac, 0, L); 

        return (macAddr.Replace('-',':')); 
       } 

       catch (Exception ex) 
       { 
        return (ex.Message);    
       } 
    } 
} 
"@ 


$type = Add-Type -TypeDefinition $sign -Language CSharp -PassThru 


$type::GetMacAddress($IPAddress) 

} 
### END FUNCTIONS ### 

# - Clear the array before entering the loop. 
$outArray = @() 

# - Loop through each of the host addresses and do stuff. 
ForEach ($IP in ($IPStart..$IPEnd)) 
{ 
    # - Try to get network information with WMI. If it doesn't work, set the hostname and tell the script that it's not a windows device. 
    Try { 
     $Ping = Get-WMIObject Win32_PingStatus -Filter "Address = '$Network.$IP' AND ResolveAddressNames = TRUE" -ErrorAction Stop 
    } 
    Catch { 
     $windows = 0 
     $hostname = ([system.net.dns]::GetHostByAddress($IP)).hostname 
     Continue 
    } 

    # - If the ping does not return an error, do stuff. 
    if ($Ping.StatusCode -eq 0) 
    { 
     # - Try to get the information from all the adapters on the windows host with WMI. If that doesn't work, tell the script it's not a windows host and keep on going. 
     Try { 
      $Adapters = Get-WmiObject Win32_NetworkAdapter -Filter "NetEnabled = True" -ComputerName $Ping.ProtocolAddressResolved -ErrorAction Stop 
     } 
     Catch { 
      $windows = 0 
      Continue 
     } 

     # - If it's windows, do stuff. 
     if ($windows -ne 0) { 
      ForEach ($Adapter in $Adapters) { 
       # - Get the networking information from the adapter. 
       $Config = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "Index = $($Adapter.Index)" -ComputerName $Ping.ProtocolAddressResolved 

       # - Screen output to provide feedback (optional) 
       Write-Host "The IP Address is $IPaddr" 
       Write-Host "The MAC Address is $Config.MACAddress" 

       # - Build the array with information from the network adapter 
       ForEach ($IPAddr in $Config.IPAddress) { 
        $adapterInfo = New-Object PSObject -Property @{ 
         Host = $Ping.ProtocolAddressResolved 
         'Interface Name' = $Adapter.Name 
         'IP Address' = $IPAddr 
         'MAC Address' = $Config.MACAddress 
        } 
        $outArray += $adapterInfo 
       } 
      } 
     } 

     # - If it's not windows, do stuff. 
     Else { 
      # - Set the IP Address and get the MAC Address from the IP. 
      $IPAddr = $Network + "." + $IP 
      $MACAddress = Get-MACFromIP $IPAddr 
      Write-Host "The IP Address is $IPaddr" 
      Write-Host "The MAC Address is $MACAddress" 

      # - Build the array with information 
      $hostinfo = New-Object PSObject -Property @{ 
        Host = "" 
        'Interface Name' = "" # Don't care in this instance. Placeholder to keep the array happy 
        'IP Address' = $IPAddr 
        'MAC Address' = $MACAddress 
       } 
      $outArray += $hostInfo 
     } 
    } 
} 

# - Output the final array to a CSV file 
$outArray | Export-CSV -Path .\ipinfo.csv -notypeinformation 

ответ

1

Существует несколько способов удаленного доступа к MAC-адресу с компьютера под управлением Windows.

getmac /S <computername> /FO CSV | ConvertFrom-Csv

Или

Get-WmiObject win32_networkadapterconfiguration | select description, macaddress

Я обнаружил, что getmac, как правило, данные, которые вы хотите, запрос WMI будет нужно немного фильтрации. Но вы можете сравнивать и фильтровать результаты запроса WMI на основе сетевых интерфейсов, которые вы обнаруживаете в своем скрипте.

Также измените свой [int]$IPEnd = 255 на [int]$IPEnd = 254 255 - это широковещательный адрес вашей сети.

Редактировать: Хорошо, потому что у вас, кажется, сложный набор ограничений, но у вас есть единый домен столкновения (рад его слышать!).

Похоже, что вам нужно позвонить напрямую iphlpapi.dll.

Кто-то уже решил эту загадку, хотя взгляните на этот скрипт: http://poshcode.org/2763

+0

К сожалению, getmac и Get-WMIObject и полезны только при запросе окна устройств. Мне нужно запросить не-windows-устройства (коммутаторы, хосты ESX и т. Д.). – McKenning

+0

Тогда вам понадобится заглушить все тайники arp от коммутаторов. Может быть способ получить адреса Mac с каждого устройства, но он будет специфичным для поставщика. Удачи! –

+0

А как насчет локального кеша ARP? Возможно ли получить MAC для локальных подсетных хостов из локального ARP в Powershell? – McKenning

 Смежные вопросы

  • Нет связанных вопросов^_^