I'm in the process of creating an IP and network scanner, mostly just for fun and practice. I've run into a bit of a dilemma regarding how to retrieve my own IP and MAC addresses before performing the scan. I've been using ARP for MAC address/vendor translation, but it doesn't show my own address. Right now, I'm trying to grab these values efficiently using PowerShell.
I tried using a piece of code that sets up a ConcurrentDictionary to store the IP and MAC addresses like this:
```powershell
$HostMacAddressList = [System.Collections.Concurrent.ConcurrentDictionary[string, string]]::new()
Get-NetAdapter | Where-Object Status -EQ "Up" | ForEach-Object {
[void]$HostMacAddressList.TryAdd(($PSItem | Get-NetIPAddress).IPAddress , $PSItem.MacAddress )
}
$HostMacAddressList
```
While it works, it seems surprisingly slow compared to other methods like running `ipconfig /all`, which is instant. I find this behavior puzzling and would love to hear your thoughts on faster alternatives or solutions!
4 Answers
The performance difference likely comes from how PowerShell handles different commands. `Get-NetAdapter` is a WMI call, which often runs slower due to parsing overhead. If you're comfortable with C#, creating a custom module may yield faster results since it can interface directly with Windows APIs. Just a thought!
I think caching might impact your measurements too. If you run these commands multiple times in the same session, they could complete faster due to some data being cached. Testing in fresh sessions might yield different results!
Definitely something I noticed! It’s puzzling why it would matter so much though.
One efficient way I've found to grab both IP and MAC addresses is using this command:
```powershell
Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, @{n='MacAddress';e={$_.NetAdapter.MacAddress}}
```
This method is surprisingly quick since it avoids unnecessary looping and gets everything in one go. You might want to give that a try!
Interesting! I've measured both methods, and for me, your approach was slower. Do you think it might vary depending on the system? I found that filtering for just the 'Up' adapters made more sense.
I've had success with this compact snippet:
```powershell
[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |
Where-Object { $_.OperationalStatus -eq 'Up' } |
ForEach-Object {
$mac = $_.GetPhysicalAddress().ToString() -replace '(.{2})(?=.)', '$1-'
$ips = $_.GetIPProperties().UnicastAddresses |
Where-Object { $_.Address.AddressFamily -eq 'InterNetwork' } |
Select-Object -ExpandProperty Address |
Select-Object -ExpandProperty IPAddressToString
if ($ips) {
[PSCustomObject]@{ IP = $ips; MAC = $mac }
}
}
```
This delivered super fast results in my tests!
I expanded on that idea and added it to my existing scripts—it’s really quick! Makes such a difference in performance.

Yeah, I figured C# would be faster, but that might complicate things unnecessarily. I might stick with PowerShell for now since it works well enough for my project.