question

RobPettrey-7577 avatar image
0 Votes"
RobPettrey-7577 asked RichMatheisen-8856 edited

find all equipment vendors on the network using MAC and macvendors web request

(I am not an IT newbie, but kind of a PowerShell newbie, I have written some scripts but usually get stuck and have to borrow from the scripts and ideas of others. )

Every time I have a specific need for something I am trying to do it in PowerShell to learn it and also to have a repository of snippets for the next time and the next customer. For instance, I recently needed the most recent activity in a directory structure:

 Get-ChildItem "C:\Users\JDoe\OneDrive - Contoso" -Recurse `
     | sort lastwritetime -Descending `
     | select -first 40 lastwritetime, length, name, directory `
     | Format-Table -AutoSize

So in this instance I was trying to find a device on the network. It was the only device on the network that was manufactured by a specific vendor so it should've been easy, if I had a script it would've been fast and easy. (because it was a small network I found the device manually, but for the next time...!)

I started by getting all the MAC addresses on the /24 network by using 'arp -a' but thought it would be easier to use the data by doing it in PowerShell. I learned that Get-Neighbor is what I need but it pulls all IP's so I limited it by IPV4; it pulls unreachables and multicasts so I limited it by removing those; I wanted the list by MAC so I sorted it. Here's what I have so far:

 Get-NetNeighbor -AddressFamily IPv4 `
     | where {$_.State -ne 'Unreachable' -and $_.State -ne 'Permanent'} `
     | sort LinkLayerAddress -Unique `
     | Format-Table -AutoSize IPAddress, LinkLayerAddress, State
    
 IPAddress       LinkLayerAddress     State
 ---------       ----------------     -----
 192.168.123.34  08e689e28251     Reachable
 192.168.123.24  0e1b2f9f1cea         Stale
 etc.

Sidebar: why does this not work?

     | Where-Object {$_.State -ne ('Permanent' -and 'Unreachable')} `

What I want to do from here is to sort uniquely the first 6 characters of the MAC address to get all unique vendor IP ranges, then call the macvendors site for each vendor range, something like this in PS V7:

 Invoke-WebRequest -Uri "https://api.macvendors.com/"$_.LinkLayerAddress""

If I surf to
https://api.macvendors.com/08-BD-43
I get: NETGEAR

If I call it from PowerShell I get this:

 Invoke-WebRequest -Uri "https://api.macvendors.com/08-BD-43"
    
 StatusCode        : 200
 StatusDescription : OK
 Content           : NETGEAR
 RawContent        : HTTP/1.1 200 OK
                     Cache-Control: must-revalidate, max-age=0, private
                     Date: Mon, 01 Feb 2021 04:00:21 GMT
                     Server: Cowboy
                     X-Request-ID: Fl-DuOn7vVssClx3sObi
                     Content-Length: 7
                     Content-Type: text/plai…
 Headers           : {[Cache-Control, System.String[]], [Date, System.String[]], [Server, System.String[]],
                     [X-Request-ID, System.String[]]…}
 Images            : {}
 InputFields       : {}
 Links             : {}
 RawContentLength  : 7
 RelationLink      : {}

What I would like to end up with is this:

  IPAddress          OUI        Vendor
     ---------       ------     -----
     192.168.123.34  08e689     Apple, Inc.
     192.168.123.24  08bd43     NETGEAR
     etc.

This is typically my frustration. I know what I want to do, I can find the commands I need to do it, but I can't put it together. I would be greatly appreciative of anyone who could point me in a direction. -Rob







windows-serverwindows-server-powershellwindows-server-manager
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I hope you have either a very limited number of network devices in your network or the appropriate plan for that web site. If you get rate-limited based on the number of requests per second you'll probably want to use a Start-Sleep cmdlet between each execution of Invoke-WebRequest.

 $LimitPerSecond = 2
 $Padding =10
 $Delay = 0
    
 $Delay = (1 / $LimitPerSecond) * 1000 + $Padding
    
 # inside your loop:
 Start-Sleep -Milliseconds $Delay
 $vendor = (Invoke-WebRequest -Uri "https://api.macvendors.com/$($_.LinkLayerAddress")).content

You may also get limited by the number of requests you can make in one day.


0 Votes 0 ·
RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered

To you "Sidebar: why does this not work?" question . . .

  | Where-Object {$_.State -ne ('Permanent' -and 'Unreachable')}

Both "Permanent" and "Unreachable" would be seen as strings and the expression "('Permanent' -and 'Unreachable')" would be evaluated -- as a Boolean expression. Both strings are non-empty strings and the result is always going the be $TRUE.

The variable "$_.State" is also a non-empty string so the result of the 1st expression (the one with the "-and" operator) is cast as a string and that value is "TRUE". The result of the entire operation is always going to be $True because the $_State is not equal to "true".

That can be better expressed as:

 Where-Object {'Permanent', 'Unreachable' -notcontains $_.State}
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered

To your "what to do", try this:

 (Invoke-WebRequest -Uri "https://api.macvendors.com/08-BD-43").Content
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RobPettrey-7577 avatar image
0 Votes"
RobPettrey-7577 answered RobPettrey-7577 published

After looking at other sites I got some other clues, and all of a sudden I had a breakthrough, and was able to write it myself! With understanding! (Updating the target 2012R2 server to PS V7 didn't hurt either!)

It's not perfect, but any more work is the law of diminishing returns. It does what I want:
it gets me all the vendor names of all network neighbor devices with the IP address.

I initially wanted to start with the first 6 characters of the mac address, but found Windows 10 displaying dashes and 2012R2 not, so I had to manipulate the output depending. My original intention was to only show unique vendor codes but now I am glad I have all the IP's for each unique device instead of just unique vendors.

To make it faster (and also to try to not lean on macvendors too much) I skipped all the duplicates and only looked up each unique sextet. I don't know what macvendors' threshold is but a second between lookups works fine. No match on the vendor lookup throws a huge messy error so I had to account for that.

I had a lot more spaces and line feeds but took them all out. It affects the readability a little but I developed some rules for myself along the way. I'm sure there is a better way to do it, I have seen a lot of really amazing and dense PS out there but I wanted to maintain a COBOL-like readability. (Yes, I have written production COBOL which makes me a dinosaur.) :^)

 # get-vendor-name - use first 6 of mac to poll macvendors for name
 $ErrorActionPreference = 'SilentlyContinue' #if no name match is found
 $netNeighbors = Get-NetNeighbor -AddressFamily IPv4 `
     | where {$_.State -ne 'Unreachable' -and $_.State -ne 'Permanent'} `
     | sort LinkLayerAddress -Unique
 ForEach ($neighbor in $netNeighbors)
     {$IP = ($neighbor.IPAddress).PadRight(16)
      $mac = $neighbor.LinkLayerAddress
      if ($mac.Length -eq 17) #if mac has delimeters
         {$oui = $mac.Substring(0,8)} else {$oui = $mac.Substring(0,6)}
      if ($oui -ne $oldOui)   #if unique vendor code
         {$vendor = (Invoke-WebRequest -Uri "https://api.macvendors.com/$oui").Content
         Start-Sleep -Milliseconds 1000 }    #don't get blocked by macvendors
      else {$vendor = '.'}    #else do not look up duplicates - show '.'
      Write-Host $oui, $ip, $vendor
      $oldOui = $oui
      $vendor = '' }
    
 000000 192.168.123.136  XEROX CORPORATION
 000074 192.168.123.103  RICOH COMPANY LTD.
 000e58 192.168.123.96   Sonos, Inc.
 000e58 192.168.123.75   .
 000e58 192.168.123.85   .
 001d50 192.168.123.65   SPINETIX SA
 0090a9 192.168.123.47   WESTERN DIGITAL
 01005e 224.0.0.2
 01005e 224.0.0.22       .
 01005e 224.0.0.251      .
 01005e 224.0.0.252      .
 01005e 239.254.127.63   .
 01005e 239.255.255.250  .
 0e1b2f 192.168.123.28
 18b169 192.168.123.5    Sonicwall
 1e83e4 192.168.123.30
 204747 192.168.123.3    Dell Inc.
 204747 192.168.123.56   .
 24a43c 192.168.123.64   Ubiquiti Networks Inc.
 24be05 192.168.123.19   Hewlett Packard
 3024a9 192.168.123.240  HP Inc.
 347e5c 192.168.123.52   Sonos, Inc.
 40b034 192.168.123.84   Hewlett Packard
 48a6b8 192.168.123.87   Sonos, Inc.
 48a6b8 192.168.123.97   .
 48a6b8 192.168.123.91   .
 48a6b8 192.168.123.72   .
 48a6b8 192.168.123.62   .
 48a6b8 192.168.123.135  .
 4c3fd3 192.168.123.57   Texas Instruments
 542a1b 192.168.123.51   Sonos, Inc.
 686dbc 192.168.123.200  Hangzhou Hikvision Digital Technology Co.,Ltd.
 6c2b59 192.168.123.122  Dell Inc.
 6c2b59 192.168.123.105  .
 6c4b90 192.168.123.43   LiteON
 6c4b90 192.168.123.41   .
 7483c2 192.168.123.81   Ubiquiti Networks Inc.
 74e6e2 192.168.123.76   Dell Inc.
 7828ca 192.168.123.74   Sonos, Inc.
 84fdd1 192.168.123.106  Intel Corporate
 86f907 192.168.123.42
 8c3bad 192.168.123.80   NETGEAR
 9c934e 192.168.123.10   Xerox Corporation
 9c934e 192.168.123.100  .
 a02195 192.168.123.55   Samsung Electronics Co.,Ltd
 a02195 192.168.123.73   .
 a0510b 192.168.123.60   Intel Corporate
 a41f72 192.168.123.71   Dell Inc.
 a4bb6d 192.168.123.88   Dell Inc.
 a6b6af 192.168.123.31
 ac8112 192.168.123.69   Gemtek Technology Co., Ltd.
 ac8112 192.168.123.111  .
 ac8112 192.168.123.89   .
 ac8112 192.168.123.99   .
 b083fe 192.168.123.1    Dell Inc.
 b2112b 192.168.123.27
 b88a60 192.168.123.70   Intel Corporate
 b8ca3a 192.168.123.48   Dell Inc.
 bc305b 192.168.123.40   Dell Inc.
 c272e9 192.168.123.32
 c64dd4 192.168.123.33
 cecf52 192.168.123.36
 d49524 192.168.123.22   Clover Network, Inc.
 d49524 192.168.123.21   .
 d49524 192.168.123.49   .
 d49524 192.168.123.94   .
 d4d252 192.168.123.61   Intel Corporate
 d89ef3 192.168.123.86   Dell Inc.
 dc9fdb 192.168.123.77   Ubiquiti Networks Inc.
 dc9fdb 192.168.123.78   .
 dcefca 192.168.123.29   Murata Manufacturing Co., Ltd.
 e237bd 192.168.123.35
 e454e8 192.168.123.95   Dell Inc.
 e454e8 192.168.123.93   .
 ffffff 192.168.123.255

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.