Convert MAC address to IPv6 link-local address

Hi Everyone.

trying to convert a Mac address to an Ipv6 link-local address. basically doing this ( ref in powershell.

  1. take the mac address: for example 52:74:f2:b1:a8:7f
  2. throw ff:fe in the middle: 52:74:f2:ff:fe:b1:a8:7f
  3. reformat to IPv6 notation 5274:f2ff:feb1:a87f
  4. convert the first octet from hexadecimal to binary: 52 -> 01010010
  5. invert the bit at index 6 (counting from 0): 01010010 -> 01010000
  6. convert octet back to hexadecimal: 01010000 -> 50
  7. replace first octet with newly calculated one: 5074:f2ff:feb1:a87f
  8. prepend the link-local prefix: fe80::5074:f2ff:feb1:a87f
  9. done!
Note the that IPV6 address obtained by the ipconfig / Get-NetIPAddress are not suitable for my needs, these address obfuscate the Mac address. I got starting by getting the Mac I am interested in. I am parsing WDS network unlock logs and want to identify source computer. The WDS logs are obtained in this manner $WDSEventsVerbose = Get-WinEvent -cn $WDS -EA silentlycontinue -FilterHashtable @{ProviderName="Microsoft-Windows-Deployment-Services-Diagnostics";ID=32769,32768,24581;StartTime=$(get-date).AddMinutes(-$MinToQuery)}

$RemoteMacaddress = (Get-Netadapter -CimSession $Script:RemoteCimSession | Where-Object { ( ($.name -like ‘Ethernet’) -and ($.InterfaceDescription -like ‘Surface’ ) )}).MacAddress

Any suggestions on how to convert my $RemoteMacaddress variable to ipv6 link notation. Regex search and replace would be too complex for me how would you approach the problem ?

That is a lot of work just to do this. Well, depending on what PowerShell version and OS version you are doing this against.
Just work with the raw cmdlets and combine the data points.

# Get IPv4 Address and Mac address
Get-WmiObject win32_networkadapterconfiguration `
| Select-Object -Property @{name='IPAddress';Expression={($_.IPAddress[0])}},MacAddress `
| Where IPAddress -NE $null

# Get IPv6 Address and Mac address
Get-WmiObject win32_networkadapterconfiguration `
| Select-Object -Property @{name='IPAddress';Expression={($_.IPAddress[1])}},MacAddress `
| Where IPAddress -NE $null

# Get address family information IPv4
Get-NetNeighbor -AddressFamily IPv4

# Get address family information IPv6
Get-NetNeighbor -AddressFamily IPv6

Or this approach combine approach…

ForEach ($Adapter in Get-NetAdapter)
    $Adapter | Select Name, Status, MacAddress,
    @{Name = 'Ipv6LinkLocal';Expression = {
    (Get-NetIPConfiguration |
     Where InterfaceAlias -Match $Adapter.InterfaceAlias).IPv6LinkLocalAddress }
     } | Format-List

For remote systems just use PSRemoting as normal.

I agree simple is better but in this case it does not work,

The WDS Bitlocker network unlock logs show the IPv6 Link local address of the physical device when the client PC is booting, and it the PC’s UEFI bios that send’s out the Network unlock request. in this example the WDS server show a log entry such as :

1/29/2019 11:02:51 PM 24581 [WDSServer/WDSPXE] [NKPPROV] Reply Sent - Request:fe80::ba31:b5ff:fe30:e661:546 Dst:fe80::ba31:b5ff:fe30:e661:546 Len:135

The windows IPv6LinkLocalAddress value for that device is fe80::6d8d:28d8:191b:3f30%3

We are talking about the same Ethernet device. yet the IPv6 address are complete different.

fe80::ba31:b5ff:fe30:e661:546 ( UEFI bios IPv6)

fe80::6d8d:28d8:191b:3f30%3 (windows IPV6)

This site explains, the Windows does not use the Mac address to generate the IPv6 LinkLocalAddress IPv6: How Windows generates Link-Local Addresses (EUI-64) – SID-500.COM.

Therefore if I want to parse the WDS log files to identify each PC in the logs I need to construct the IPv 6 address using the EUI-64 method. Can’t rely on the windows randomly generated IPV6 address.

OK, then, that would mean going down this approach, well, potentially.
After thinking and toying with this for a bit more.

$IPv6LinkLocalAddress = (($MacAddressConvert = ($MacAddress = ((Get-WmiObject win32_NetworkAdapterConfiguration).MacAddress)[1] -replace ':') `
-replace '^.{0,4}',([System.Convert]::ToString(('0x' + ($MacAddress).Substring(0,4)),2).PadLeft(8,'0')) `
-replace '(?<=^.{5})(.)',($BitFlip = If (($MacAddress).Substring(6,1) -eq 1){0}Else{1})) `
-replace (($MacAddressConvert).Substring(0,15)),('{0:X}' -f ([Convert]::ToInt32(($MacAddressConvert).Substring(0,15),2)))).