$ErrorActionPreference = 'Stop'

Add-Type -AssemblyName System.Runtime.WindowsRuntime
$watcherType = [Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementWatcher, Windows.Devices.Bluetooth, ContentType = WindowsRuntime]
$watcher = [Activator]::CreateInstance($watcherType)
$seen = [System.Collections.Concurrent.ConcurrentDictionary[string, string]]::new()
$subscription = Register-ObjectEvent -InputObject $watcher -EventName Received -Action {
    $event = $Event.SourceEventArgs
    $name = [string]$event.Advertisement.LocalName
    if ([string]::IsNullOrWhiteSpace($name)) { return }
    $address = '{0:X12}' -f $event.BluetoothAddress
    $Event.MessageData[$address] = $name
} -MessageData $seen

try {
    $watcher.Start()
    Start-Sleep -Seconds 12
}
finally {
    $watcher.Stop()
    Unregister-Event -SubscriptionId $subscription.Id -ErrorAction SilentlyContinue
    Remove-Job -Id $subscription.Id -Force -ErrorAction SilentlyContinue
}

$seen.GetEnumerator() |
    Sort-Object Value, Key |
    ForEach-Object { '{0} {1}' -f $_.Key, $_.Value }
