[英]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.