Skip to content

Instantly share code, notes, and snippets.

@c22
Last active May 9, 2018 04:56
Show Gist options
  • Save c22/d378dec14b3c52ab19dd6705e256d7f4 to your computer and use it in GitHub Desktop.
Save c22/d378dec14b3c52ab19dd6705e256d7f4 to your computer and use it in GitHub Desktop.
GetAdapterAddresses in PowerShell. Turned out NetworkGuid wasn't what I needed. Took me long enough to figure out that I couldn't bring myself to throw the code away.
$MethodDefinition = @'
[DllImport("iphlpapi.dll")]
public static extern uint GetAdaptersAddresses(uint Family, uint Flags, IntPtr Reserved, IntPtr pAdapterAddresses, ref uint pOutBufLen);
'@
$iphlpapi = Add-Type -MemberDefinition $MethodDefinition -Name 'IPHelper' -Namespace 'Pinvoke' -PassThru
# This typedef just captures the NetworkGuid and pointer to the next struct.
$TypeDefinition = @'
namespace Pinvoke {
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct GUID {
public uint Data1;
public ushort Data2;
public ushort Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] Data4;
}
[StructLayout(LayoutKind.Explicit)]
public struct IP_ADAPTER_ADDRESSES {
[FieldOffset(8)] public IntPtr Next;
[FieldOffset(252)] public GUID NetworkGuid;
// // Alternative, struct-less offsets.
// [FieldOffset(252)] public uint NetworkGuid1;
// [FieldOffset(256)] public ushort NetworkGuid2;
// [FieldOffset(258)] public ushort NetworkGuid3;
// [FieldOffset(260)] public [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] byte[] NetworkGuid4;
}
}
'@
# This typedef captures all the adapter info.
$TypeDefinition = @'
namespace Pinvoke {
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct SOCKET_ADDRESS
{
public IntPtr lpSockAddr;
public int iSockaddrLength;
}
[StructLayout(LayoutKind.Sequential)]
public struct GUID {
public uint Data1;
public ushort Data2;
public ushort Data3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] Data4;
}
[StructLayout(LayoutKind.Sequential)]
public struct IP_ADAPTER_ADDRESSES
{
public UInt64 Alignment;
public IntPtr Next;
public IntPtr AdapterName;
public IntPtr FirstUnicastAddress;
public IntPtr FirstAnycastAddress;
public IntPtr FirstMulticastAddress;
public IntPtr FirstDnsServerAddress;
[MarshalAs(UnmanagedType.LPWStr)]
public string DnsSuffix;
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)]
public string Description;
[System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)]
public string FriendlyName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] PhysicalAddress;
public uint PhysicalAddressLength;
public uint Flags;
public uint Mtu;
public uint IfType;
public uint OperStatus;
uint Ipv6IfIndex;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public uint[] ZoneIndices;
public IntPtr FirstPrefix;
public UInt64 TrasmitLinkSpeed;
public UInt64 ReceiveLinkSpeed;
public IntPtr FirstWinsServerAddress;
public IntPtr FirstGatewayAddress;
public uint Ipv4Metric;
public uint Ipv6Metric;
public UInt64 Luid;
public SOCKET_ADDRESS Dhcpv4Server;
public uint CompartmentId;
public GUID NetworkGuid;
public uint ConnectionType;
public uint TunnelType;
public SOCKET_ADDRESS Dhcpv6Server;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 130)]
public byte[] Dhcpv6ClientDuid;
public uint Dhcpv6ClientDuidLength;
public uint Dhcpv6Iaid;
public uint FirstDnsSuffix;
}
}
'@
Add-Type -TypeDefinition $TypeDefinition -PassThru
$bufptr = [System.IntPtr]::Zero
$bufsize = 0
$iphlpapi::GetAdaptersAddresses(0, 0, [System.IntPtr]::Zero, $bufptr, [ref]$bufsize)
$bufptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($bufsize)
$iphlpapi::GetAdaptersAddresses(0, 0, [System.IntPtr]::Zero, $bufptr, [ref]$bufsize)
$adapter = [System.Runtime.InteropServices.Marshal]::PtrToStructure($bufptr, [System.Type][Pinvoke.IP_ADAPTER_ADDRESSES])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment