MACVendors.psm1


#
#
# MACVendors lookup
#
#


$ErrorActionPreference = 'Stop'


#
# Module functions
#


Function Get-MACVendorInfo {

    <#
 
    .SYNOPSIS
    MAC address vendor lookup
 
    .DESCRIPTION
    MAC address vendor lookup
 
    .PARAMETER MAC
    The MAC address to lookup
 
    .PARAMETER Offline
    This switch will get the vendor information after downloading
    the database to the local machine
 
    .EXAMPLE
    Get-MACVendorInfo -MAC 00:00:0C:00:00:00
 
    .EXAMPLE
    Get-MACVendorInfo -MAC 00:00:0C:00:00:00 -Offline
 
    .NOTES
    Internet connection required
 
    The separators can be ':', '-' or '.'
 
    00:00:0C:00:00:00
    00-00-0C-00-00-00
    00.00.0C.00.00.00
 
    The offline results do not include
    Company address, Country and Type
 
    .LINK
    N/A
 
    #>


    [CmdletBinding ()]

    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter MAC address'
                   )
        ]

        [String[]]$MAC,

        [Switch]$Offline

    )

    BEGIN {

        Function Show-Data {

            [PSCustomObject]@{

                MAC = $MACEntry
                Company = $Results.Result.Company
                Address = $Results.Result.Address
                Country = $Results.Result.Country
                MAC_Prefix = $Results.Result.MAC_Prefix
                Start_Hex = $Results.Result.Start_Hex
                End_Hex = $Results.Result.End_Hex
                Type = $Results.Result.Type
                Status = $Status

            }

        }

    }

    PROCESS {

        ForEach ($MACEntry In $MAC) {

            $Results = @{}

            Try {

                If ($MACEntry -notmatch '^([0-9A-F]{2}[:.-]){5}([0-9A-F]{2})$') {

                    $Status = 'Invalid MAC address or not formatted properly'

                    Show-Data

                    Continue

                }

                If ($Offline) {

                    If ((Test-Path -Path $env:TEMP\VendorMACS.xml) -eq $False) {

                        Update-MACVendorOfflineDatabase

                    }

                    $TempMACEntry = ($MACEntry -replace '-', ':').Replace('.', ':')

                    [xml]$Doc = Get-Content $env:TEMP\VendorMACS.xml

                    $Prefix = $Doc.MacAddressVendorMappings.VendorMapping.MAC_Prefix
                    $VendorName = $Doc.MacAddressVendorMappings.VendorMapping.Vendor_Name
                    $Index = 0

                    ForEach ($PrefixEntry In $Prefix) {

                        If ($PrefixEntry -eq $TempMACEntry.Substring(0, $PrefixEntry.Length) -and $VendorName[$Index] -notlike 'IEEE*') {

                            $StartHex = ($PrefixEntry -replace ':', '') + '000000'
                            $EndHex = ($PrefixEntry -replace ':', '') + 'FFFFFF'

                            [PSCustomObject]@{

                                MAC = $MACEntry
                                Company = $VendorName.Get($Index)
                                MAC_Prefix = $PrefixEntry
                                Start_Hex = $StartHex.Substring(0, 12)
                                End_Hex =  $EndHex.Substring(0, 12)

                            }

                        }

                        $Index++

                    }

                }

                Else {

                    $Results = Invoke-WebRequest -Uri "http://macvendors.co/api/$MACEntry" | ConvertFrom-Json

                    $Status = 'Ok'

                    Show-Data

                }

            }

            Catch {

                $Status = $PSItem.Exception.Message

                Show-Data

            }

        }

    }

    END {}

}

Function Get-MACVendorInfoByCompanyName {

    <#
 
    .SYNOPSIS
    Get the MAC prefixes and ranges by Company Name
 
    .DESCRIPTION
    Get the MAC prefixes and ranges by Company Name
 
    .PARAMETER CompanyName
 
    .EXAMPLE
    Exact match
 
    Get-MACVendorInfoByCompanyName -CompanyName Cablevision
 
    .EXAMPLE
    Exact match
 
    Get-MACVendorInfoByCompanyName -CompanyName Cablevision, Microsoft
 
    .EXAMPLE
    Using wildcard
 
    Get-MACVendorInfoByCompanyName -CompanyName Intel*
 
    .EXAMPLE
    Using wildcard and exact match
 
    Get-MACVendorInfoByCompanyName -CompanyName Intel*, Microsoft
 
    .NOTES
 
    .LINK
    N/A
 
    #>


    [CmdletBinding ()]

    Param (

        [Parameter (Mandatory = $True,
                    ValueFromPipeline = $True,
                    ValueFromPipelineByPropertyName = $True,
                    HelpMessage = 'Enter Company Name'
                   )
        ]

        [String[]]$CompanyName

    )

    BEGIN {

        If ((Test-Path -Path $env:TEMP\VendorMACS.xml) -eq $False) {

            Update-MACVendorOfflineDatabase

        }

        [xml]$Doc = Get-Content $env:TEMP\VendorMACS.xml

        $Prefix = $Doc.MacAddressVendorMappings.VendorMapping.MAC_Prefix
        $VendorName = $Doc.MacAddressVendorMappings.VendorMapping.Vendor_Name

        Function Show-Data {

            $StartHex = ($Prefix[$Index] -replace ':', '') + '000000'
            $EndHex = ($Prefix[$Index] -replace ':', '') + 'FFFFFF'

            [PSCustomObject]@{

                Company = $VendorEntry
                MAC_Prefix = $Prefix[$Index]
                Start_Hex = $StartHex.Substring(0, 12)
                End_Hex =  $EndHex.Substring(0, 12)

            }

        }

    }

    PROCESS {

        ForEach ($CompanyEntry In $CompanyName) {

            $Index = 0

            If ($CompanyEntry.Contains('*')) {

                ForEach ($VendorEntry In $VendorName) {

                    If ($VendorEntry -like $CompanyEntry) {

                        Show-Data

                    }

                    $Index++

                }

            }

            Else {

                ForEach ($VendorEntry In $VendorName) {

                    If ($VendorEntry -eq $CompanyEntry) {

                        Show-Data

                    }

                    $Index++

                }

            }

        }

    }

    END {}

}

Function Update-MACVendorOfflineDatabase {

    <#
 
    .SYNOPSIS
    Download the MAC vendors database
 
    .DESCRIPTION
    Download the MAC vendors database
 
    .PARAMETER
 
    .EXAMPLE
    Update-MACVendorOfflineDatabase
 
    .NOTES
 
    .LINK
    N/A
 
    #>


    [CmdletBinding ()]

    Param ()

    BEGIN {}

    PROCESS {

        Try {

            Invoke-WebRequest -Uri http://macvendors.co/vendormacs/download -OutFile $env:TEMP\VendorMACS.xml

        }

        Catch {

            Write-Warning -Message $PSItem.Exception.Message

        }

    }

    END {}

}