MacAddressVendorDatabaseIEEE.psm1

Function Update-MacAddressDatabase {
param(
    [string]$Uri = 'http://standards-oui.ieee.org/oui.txt',
    [string]$Regex = [regex]::Escape('(hex)')
)
    if(!$PSScriptRoot){$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent}
    $OuiFile = $PSScriptRoot + '\oui.txt'
    $CsvFile = $PSScriptRoot + '\oui.csv'
    try {
        Invoke-WebRequest -Uri $Uri -OutFile $OuiFile
        Start-Sleep -Seconds 2
        $OuiFileContent = Get-Content -Path $OuiFile
    } catch {
        Write-Warning -Message "Database File not exists"
        break
    }
    $MacAddressDatabase = @{}
    $OuiFileContent | % {
        if ([bool]($_ -match $Regex)){
            [string]$MacAddress,[string]$Vendor = $_ -split $Regex -replace "^\s+|\s+$"
            $MacAddress = $MacAddress -replace "\-"
            if ($MacAddressDatabase.ContainsKey($MacAddress)){
                $MacAddressDatabase[$MacAddress] = [string](@($MacAddressDatabase[$MacAddress],$Vendor) -join ';; ')
            } else {
                $MacAddressDatabase.Add($MacAddress,$Vendor)
            }
        }
    }
    $Global:MacAddressDatabase = $MacAddressDatabase
    $MacAddressDatabase.GetEnumerator() | % {[pscustomobject][ordered]@{'MacAddress' = $($_.Key); 'Vendor' = $($_.Value)}} | Export-Csv -Delimiter ';' -NoTypeInformation -Path $CsvFile
}

Function Import-MacAddressDatabase {
param()
    if(!$PSScriptRoot){$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent}
    $CsvFile = $PSScriptRoot + '\oui.csv'
    if (![bool](Test-Path -Path $CsvFile -ErrorAction SilentlyContinue)) {
        Write-Warning -Message "Database File not found; Use Update-MacAddressDatabase comandlet"
        break
    }
    $MacAddressDatabase = @{}
    try {
        Import-Csv -Path $CsvFile -Delimiter ';' | % {
            $MacAddressDatabase.Add([string]$_.MacAddress, [string]$_.Vendor)
        }
    } catch {
        Write-Warning -Message "Database File not valid"
        break
    }
    $Global:MacAddressDatabase = $MacAddressDatabase
}

Function Get-MacAddressVendor {
<#
.EXAMPLE
Get-NetNeighbor -IPAddress 192* | Get-MacAddressVendor
HTC Corporation
Microsoft Corporation
D-Link International
ZyXEL Communications Corporation
.EXAMPLE
Get-NetNeighbor -IPAddress 192* | Get-MacAddressVendor -PassThru | Select-Object IPAddress,LinkLayerAddress,Vendor
IPAddress LinkLayerAddress Vendor
--------- ---------------- ------
192.168.0.255 ffffffffffff
192.168.0.106 1c659d7cb596 Liteon Technology Corporation
192.168.0.101 000000000000
192.168.0.92 f079606a3eda Apple, Inc.
192.168.0.51 00155d003200 Microsoft Corporation
192.168.0.1 588bf34b5e10 ZyXEL Communications Corporation
#>

param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]$InputObject,
[switch]$PassThru
)
Begin{
    if (!$Global:MacAddressDatabase) {
        Import-MacAddressDatabase
    }
    Function Resolve-MacAddress {
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][alias('LinkLayerAddress','PhysicalAddress','ClientId')][AllowEmptyString()][string[]]$MAC
    )
    Begin {}
    Process {
        $MAC | % {
            $MAC6 = [string]''
            $MAC6 = $_ -replace '[^\w\d]' -replace '(......)(.+)','$1'
                if( ($MAC6 -match '^[\d\w]{6}$') -and  ($MAC6 -notmatch '^(0){6}$') -and ($MAC6 -notmatch '^(f){6}$')) {
                    $MacAddressDatabase[$MAC6]
                }
        }
    }
    End {}
    }
}
Process{
    $InputObject | % {
        if (![bool]$PassThru) {
            $($_ | Resolve-MacAddress)
        } else {
            Add-Member -InputObject $_ -MemberType NoteProperty -Name 'Vendor' -Value $($_ | Resolve-MacAddress) -Force -PassThru
        }
    }
}
End{}
}