Use powershell to get device names and their ipaddress on a home network

I use NETSTAT all the time to figure out what applications are doing.

From a normal cmd prompt:

netstat -b

will return all connections and the app associated with it.

Here's a sample of what netstat returns:

 TCP    127.0.0.1:50452        iqbrix-pc:15485        ESTABLISHED
 [Everything.exe]
  TCP    192.168.4.210:27036    ZOE-SURFACE:55915      ESTABLISHED
 [Steam.exe]
  TCP    192.168.4.210:49674    server18101:5938       ESTABLISHED
 [TeamViewer_Service.exe]
  TCP    192.168.4.210:49798    msnbot-65-52-108-183:https  ESTABLISHED
  WpnService
 [svchost.exe]
  TCP    192.168.4.210:49829    pf-in-f109:imaps       ESTABLISHED
  OneSyncSvc_320294
 [svchost.exe]

You could parse the data that is returned and move from there.


I converted my batch tool for this into a Powershell script.
It is a wrapper for the cmd line tools ping.exe, arp.exe and nslookup.exe.

  • To get good results all devices should be switched on and connected.
  • To get all possible DeviceIPs into the arp cache of your computer,
    a ping to all IPs in a presumed /24 subnet is executed in advance.
  • Arp.exe -a will return the IP and MAC.
  • Nslookup.exe is used to find the Name stripped from any local domain suffix.

Edit the var $SubNet to fit your environment.

## Q:\Test\2017\01\21\SO_41785413.ps1
$FileOut = ".\Computers.csv"
## Ping subnet
$Subnet = "192.168.xyz."
1..254|ForEach-Object{
    Start-Process -WindowStyle Hidden ping.exe -Argumentlist "-n 1 -l 0 -f -i 2 -w 1 -4 $SubNet$_"
}
$Computers =(arp.exe -a | Select-String "$SubNet.*dynam") -replace ' +',','|
  ConvertFrom-Csv -Header Computername,IPv4,MAC,x,Vendor|
                   Select Computername,IPv4,MAC

ForEach ($Computer in $Computers){
  nslookup $Computer.IPv4|Select-String -Pattern "^Name:\s+([^\.]+).*$"|
    ForEach-Object{
      $Computer.Computername = $_.Matches.Groups[1].Value
    }
}
$Computers
$Computers | Export-Csv $FileOut -NotypeInformation
#$Computers | Out-Gridview

Sample Output

Computername     IPv4            MAC              
------------     ----            ---              
Zyxel-24G-Switch 192.168.xyz.1   fc-f5-28-fc-f5-28
TMDat1-Plex      192.168.xyz.60  02-7c-2c-02-7c-2c
HPn54L           192.168.xyz.91  c8-cb-b8-c8-cb-b8
Medion-Tablett   192.168.xyz.114 08-d8-33-08-d8-33
dLAN-LiveCam     192.168.xyz.115 bc-f2-af-bc-f2-af
McMini           192.168.xyz.128 40-6c-8f-40-6c-8f
HPojPro8500plus  192.168.xyz.144 d4-85-64-d4-85-64
Amazon-Kindle2   192.168.xyz.152 10-ae-60-10-ae-60
SG-S4-active     192.168.xyz.162 40-0e-85-40-0e-85
TMDat1           192.168.xyz.167 28-92-4a-28-92-4a
HP-G1610         192.168.xyz.176 10-60-4b-10-60-4b
NetStream4Sat    192.168.xyz.191 00-0c-6c-00-0c-6c
Netio230b        192.168.xyz.230 24-a4-2c-24-a4-2c
fritz            192.168.xyz.250 bc-05-43-bc-05-43
HomeMatic-CCU    192.168.xyz.254 00-1a-22-00-1a-22

My own extended version appends the Vendor extracted from the first 6 hex digit of the Mac but requires the very slow download of Oui.txt from
"http://standards-oui.ieee.org/oui.txt"


Can find dns with "Resolve-DnsName", and mac/ips with "Get-NetNeighbor" (arp table cache). Can scan ips and use "Test-Connection" (ping). "Test-Connection" also lets you look for open tcp ports, so if port 80 is open you can go to that address in the browser, or if port 135 is open can go to that fileshare address. Finally, if you still can't identify the devices you can use a site to lookup the mac address given with arp or use the code at the bottom.

Using the arp table cache to find devices

requires powershell 7 or higher:

#replace the string with e.g. "192.168.1.$_", whatever your subnet is, optional but will improve # of devices found
$ips= 0..255 | %{"10.0.0.$_"};

#optional: add ports to scan. 22=ssh, 80=http, 443=https, 135=smb, 3389=rdp
$ports= 22, 80, 443, 135, 3389;

#optional: change batch size to speed up / slow down (warning: too high will throw errors)
$batchSize=64;

$ips += Get-NetNeighbor | %{$_.IPAddress}
$ips = $ips | sort | unique;
$ips | % -Throttlelimit $batchSize -Parallel {
    $ip=$_;
    $activePorts = $using:ports | %{ if(Test-Connection $ip -quiet -TcpPort $_ -TimeoutSeconds 1){ $_ } }
    if(Test-Connection $ip -quiet -TimeoutSeconds 1 -count 1){
        [array]$activePorts+="(ping)";
    } 
    if($activePorts){
        $dns=(Resolve-DnsName $ip -ErrorAction SilentlyContinue).NameHost;
        $mac=((Get-NetNeighbor |?{$_.State -ne "Incomplete" -and $_.State -ne "Unreachable" -and $_.IPAddress -match $ip}|%{$_}).LinkLayerAddress )
        return [pscustomobject]@{dns=$dns; ip=$ip; ports=$activePorts; mac=$mac}
    }
} | tee -variable "dvcResults"
$dvcResults | sort -property mac

note: You can't be sure about dns because a reverse zone may not be configured. (so the dns field may not be perfect)

If you want to lookup the mac address you can use the code below to append this data or go to a website (note: the code below downloads data from standards-oui.ieee.org/oui/oui.txt )

#build dict
$oui = (irm standards-oui.ieee.org/oui/oui.txt) -split '\r?\n';
$dict=@{};
$oui | ?{$_ -match "^[^\s]{8}"} | %{$arr=$_ -split "\s+";$dict[$arr[0]]=(($arr |select-object -skip 2) -join " ")}

#append data
$dvcDescriptions = $dvcResults | %{[pscustomobject]@{dns=$_.dns; ip=$_.ip; ports=$_.ports; companyName=$_.mac ? $dict[$_.mac.Substring(0,8)] : ""; mac=$_.mac;}};

$dvcDescriptions | sort -property companyName | Format-Table

Ex. output:

ex output

Output shows an asus computer hosting a windows fileshare, a dell server hosting https, a raspberry pi with ssh, a mac mini, and an hp printer hosting a webserver. If I go into my router page I can see the raspberry pi device name (pizero1) which our resolve-dnsname wasn't able to figure out.

Tags:

Powershell