从可 ping IP 地址中获取 MAC 个地址的列表
Get a list of MAC addresses from pingable IP Addresses
目标:获取包含主机名(通过 DNS,如果未找到则为空白)、MAC 地址和网络上活动设备的 IP 地址的数组。这必须适用于非 windows 设备(交换机、ESX 主机等),因此 WMI 已失效。
到目前为止我所拥有的,基于此 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
编辑:这是供那些希望将其作为参考的人使用的最终工作脚本。函数来自 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
有几种方法可以从 Windows 计算机远程获取 MAC 地址。
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
目标:获取包含主机名(通过 DNS,如果未找到则为空白)、MAC 地址和网络上活动设备的 IP 地址的数组。这必须适用于非 windows 设备(交换机、ESX 主机等),因此 WMI 已失效。
到目前为止我所拥有的,基于此 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
编辑:这是供那些希望将其作为参考的人使用的最终工作脚本。函数来自 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
有几种方法可以从 Windows 计算机远程获取 MAC 地址。
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