简体   繁体   English

从可ping IP地址获取MAC地址列表

[英]Get a list of MAC addresses from pingable IP Addresses

GOAL: To get an array containing the Hostname (via DNS, blank if not found), MAC address and IP Address of active devices on a network. 目标:获取一个包含主机名(通过DNS,如果找不到则为空白),MAC地址和网络上活动设备的IP地址的阵列。 This must work for non-windows devices (switches, ESX hosts, etc) so WMI is out. 这必须适用于非Windows设备(交换机,ESX主机等),因此WMI不可用。

What I have so far, based on this 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 is the final working script for those who want to it as a reference. 编辑:这是那些想要将其作为参考的最终工作脚本。 Function is from 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

There are a few ways to remotely get the MAC address from a Windows computer. 有几种方法可以从Windows计算机远程获取MAC地址。

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

Or 要么

Get-WmiObject win32_networkadapterconfiguration | select description, macaddress

I have found that getmac is usually the data you want, the WMI query will need a little filtering. 我发现getmac通常是您想要的数据,WMI查询将需要一些过滤。 But you can compare and filter the results from the WMI query based upon the network interfaces you are discovering in your script. 但是,您可以根据在脚本中发现的网络接口,比较和过滤WMI查询的结果。

Also change your [int]$IPEnd = 255 to [int]$IPEnd = 254 255 is the broadcast address of your network. 另外,将[int]$IPEnd = 255更改为[int]$IPEnd = 254 255是网络的广播地址。

Edit: Okay since you seem to have a demanding set of constraints, but you've got a single collision domain (glad to hear it!). 编辑:好的,因为您似乎有一组苛刻的约束,但是您只有一个碰撞域(很高兴听到!)。

Seems like you'll need to call the iphlpapi.dll directly. 似乎您需要直接调用iphlpapi.dll

Someone has already solved this riddle though take a look at this script: http://poshcode.org/2763 看看这个脚本,已经有人解决了这个难题: http : //poshcode.org/2763

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM