LLDP does one thing very well: it will tell you about the port on a switch that a device is connected to and some information around the switch configuration. Where this comes in handy is if you need to move a port to another VLAN or trace a cable during switch upgrades. I searched everywhere for a Windows application that could do that and came up empty.

At a basic level it uses pktmon, which is a built-in Microsoft utility that allows you to create .etl files and then convert those to .txt so you can parse. That’s where the magic happens. I wrapped it in a GUI. The zip has the code and two executables. These need to be run from an elevated administrative session.

  • LLDPDiscovery.ps1 has the GUI code.
  • LLDPDiscoveryNoGUI.ps1 is the raw script.
  • LLDPDiscovery.exe launches a PowerShell console for debugging.
  • LLDPDiscoveryNC.exe launches without a console.
PowerShellLLDPDiscoveryNoGUI.ps1
$sessionName = "LLDPListener"
$etlPath = "$env:TEMP\LLDPListener.etl"
$txtPath = "$env:TEMP\LLDPListener.txt"

function Reset-Capture {
    Get-NetEventSession | ForEach-Object {
        Stop-NetEventSession -Name $_.Name
        Remove-NetEventSession -Name $_.Name
    }
    Remove-Item $etlPath, $txtPath -ErrorAction SilentlyContinue
    pktmon stop > $null
    pktmon filter remove > $null
}

function Start-Capture {
    Write-Host "Starting LLDP capture session..."
    New-NetEventSession -Name $sessionName -CaptureMode RealtimeLocal | Out-Null
    Add-NetEventPacketCaptureProvider -SessionName $sessionName -Level 0x0 -CaptureType Physical -TruncationLength 128 | Out-Null
    Start-NetEventSession -Name $sessionName | Out-Null
    pktmon filter add "LLDP" -d LLDP > $null
    pktmon start --capture --type flow --pkt-size 0 --file-name $etlPath --comp nics > $null
}

Reset-Capture
Start-Capture
Write-Host "Listening for LLDP packets on Ethernet interfaces... (Press Ctrl+C to stop)"
do {
    Start-Sleep -Seconds 2
    $counters = pktmon counters
} while ($counters -match "All counters are zero.")

Write-Host "LLDP packet received!"
pktmon stop > $null
pktmon etl2txt $etlPath --out $txtPath --verbose 3 > $null

These are for my own use, and no warranty is implied, but you are welcome to use the code.