PowerShell offers you a plentitude of approaches to solve a task. They always boil down to the same strategies. In this mini-series, we will illustrate them all one by one.
Here’s the problem to solve: get the MAC address of your computer.
In our previous tips we looked at commands and operators. But what if you still cannot get the information you need?
Even then PowerShell has options for you because you can directly access .NET Framework types and methods. Or put differently: if there was no programmer that did the job for you and provided you with specific commands, you can program the functionality yourself.
Obviously, this can quickly become the most difficult approach because now you need programmer skills and need to google even more. What you need to find is a built-in .NET type that deals with the information you need.
After a bit of research you may discover that the [System.Net.NetworkInformation.NetworkInterface] .NET type manages network adapters, and all .NET types expose their methods in PowerShell when you add two colons:
PS C:\> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() Id : {DC7C0CE2-B070-4070-B5CB-1C400DA69AF8} Name : vEthernet (Default Switch) Description : Hyper-V Virtual Ethernet Adapter NetworkInterfaceType : Ethernet OperationalStatus : Up Speed : 10000000000 IsReceiveOnly : False SupportsMulticast : True Id : {44FE83FC-7565-4B18-AAC8-AB3EC075E822} Name : Ethernet 2 Description : USB Ethernet NetworkInterfaceType : Ethernet OperationalStatus : Up Speed : 1000000000 IsReceiveOnly : False SupportsMulticast : True ...
Since .NET returns structured data, there is no difference between results returned by a PowerShell cmdlet and results returned by a raw .NET method. You can consume and process the data in the same way:
PS C:\> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | Select-Object -Property Name, NetworkInterfaceType, Description Name NetworkInterfaceType Description ---- -------------------- ----------- vEthernet (Default Switch) Ethernet Hyper-V Virtual Ethernet Adapter Ethernet 2 Ethernet USB Ethernet Local Area Connection* 1 Wireless80211 Microsoft Wi-Fi Direct Virtual Adapter Local Area Connection* 2 Wireless80211 Microsoft Wi-Fi Direct Virtual Adapter #2 WLAN Wireless80211 Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W) Bluetooth Network Connection Ethernet Bluetooth Device (Personal Area Network) Loopback Pseudo-Interface 1 Loopback Software Loopback Interface 1
However, the .NET method you found may not directly contain the information you require. In our example, GetAllNetworkInterfaces() returns all network adapters, but to get their MAC addresses, you need to dive deeper into the .NET object tree. That’s what makes this technique harder (but also exciting and rewarding) to use.
Here is the finished .NET code to get all the required information about your network adapter, this time even including the information whether or not a particular adapter is currently up:
[System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | ForEach-Object { $nic = $_ [PSCustomObject]@{ Name = $_.Name Status = $_.OperationalStatus Mac = [System.BitConverter]::ToString($nic.GetPhysicalAddress().GetAddressBytes()) Type = $_.NetworkInterfaceType SpeedGb = $(if ($_.Speed -ge 0) { $_.Speed/1000000000 } ) Description = $_.Description } }
This is where the circle closes: by wrapping this raw .NET code into a PowerShell function, you add a new simple command to the PowerShell vocabulary:
function Get-MacAddress { [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() | ForEach-Object { $nic = $_ [PSCustomObject]@{ Name = $_.Name Status = $_.OperationalStatus Mac = [System.BitConverter]::ToString($nic.GetPhysicalAddress().GetAddressBytes()) Type = $_.NetworkInterfaceType SpeedGb = $(if ($_.Speed -ge 0) { $_.Speed/1000000000 } ) Description = $_.Description } } }
Once you run this function definition, you now can again use a highly specialized and easy to use PowerShell command and append your always common set of PowerShell cmdlets (Select-Object, Where-Object) to bring the data into the desired form:
PS C:\> Get-MacAddress | Where-Object Mac | Select-Object -Property Name, Status, Mac, SpeedGb Name Status Mac SpeedGb ---- ------ --- ------- vEthernet (Default Switch) Up 00-15-5D-58-46-A8 10 Ethernet 2 Up 80-3F-5D-05-58-91 1 Local Area Connection* 1 Down 24-EE-9A-54-1B-E6 Local Area Connection* 2 Down 26-EE-9A-54-1B-E5 WLAN Down 24-EE-9A-54-1B-E5 0,78 Bluetooth Network Connection Down 24-EE-9A-54-1B-E9 0,003