|
| 1 | +Add-Type -AssemblyName System.Device |
| 2 | + |
| 3 | +$watcher = New-Object System.Device.Location.GeoCoordinateWatcher |
| 4 | +$watcher.Start() |
| 5 | +Start-Sleep 2 |
| 6 | + |
| 7 | +# CSV log files |
| 8 | +$logFile = "$env:USERPROFILE\location_log.csv" |
| 9 | +$alertFile = "$env:USERPROFILE\location_alerts.csv" |
| 10 | + |
| 11 | +# Create CSV headers if files don't exist |
| 12 | +if (-not (Test-Path $logFile)) { |
| 13 | + "Timestamp,Latitude,Longitude,Accuracy,City,State,Country,Source,PublicIP,SSIDs,BSSIDs" | Out-File $logFile -Encoding UTF8 |
| 14 | +} |
| 15 | +if (-not (Test-Path $alertFile)) { |
| 16 | + "Timestamp,Latitude,Longitude,Accuracy,City,State,Country,Source,PublicIP,SSIDs,BSSIDs" | Out-File $alertFile -Encoding UTF8 |
| 17 | +} |
| 18 | + |
| 19 | +while ($true) { |
| 20 | + # Wait for a valid location fix |
| 21 | + $loc = $watcher.Position.Location |
| 22 | + if ($loc -eq $null -or ($loc.Latitude -eq 0 -and $loc.Longitude -eq 0)) { |
| 23 | + Write-Host "Waiting for location fix..." |
| 24 | + Start-Sleep 5 |
| 25 | + continue |
| 26 | + } |
| 27 | + |
| 28 | + $accuracy = $loc.HorizontalAccuracy |
| 29 | + $lat = $loc.Latitude |
| 30 | + $lon = $loc.Longitude |
| 31 | + |
| 32 | + if ($accuracy -lt 50) { $source = "WiFi" } else { $source = "IP/Other" } |
| 33 | + |
| 34 | + # Public IP |
| 35 | + try { $publicIP = (Invoke-RestMethod -Uri "https://api.ipify.org?format=json").ip } |
| 36 | + catch { $publicIP = "Unavailable" } |
| 37 | + |
| 38 | + # Wi-Fi SSID + BSSID scan |
| 39 | + try { |
| 40 | + $wifiScan = netsh wlan show networks mode=bssid |
| 41 | + $ssidMatches = @() |
| 42 | + $bssidMatches = @() |
| 43 | + |
| 44 | + # Parse SSID and BSSID explicitly |
| 45 | + foreach ($line in $wifiScan) { |
| 46 | + if ($line -match '^\s*SSID\s+\d+\s+:\s+(.*)$') { |
| 47 | + $ssidMatches += $Matches[1].Trim() |
| 48 | + } |
| 49 | + elseif ($line -match '^\s*BSSID\s+\d+\s+:\s+([0-9a-fA-F:]+)') { |
| 50 | + $bssidMatches += $Matches[1].Trim() |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + if (-not $ssidMatches) { $ssidMatches = @("None found") } |
| 55 | + if (-not $bssidMatches) { $bssidMatches = @("None found") } |
| 56 | + |
| 57 | + $ssidCSV = '"' + ($ssidMatches -join "; ") + '"' |
| 58 | + $bssidCSV = '"' + ($bssidMatches -join "; ") + '"' |
| 59 | + |
| 60 | + } catch { |
| 61 | + $ssidCSV = "Unavailable" |
| 62 | + $bssidCSV = "Unavailable" |
| 63 | + } |
| 64 | + |
| 65 | + # Reverse geocoding |
| 66 | + try { |
| 67 | + $geo = Invoke-RestMethod -Uri "https://nominatim.openstreetmap.org/reverse?format=json&lat=$lat&lon=$lon" |
| 68 | + |
| 69 | + if ($geo.address.city) { $city = $geo.address.city } |
| 70 | + elseif ($geo.address.town) { $city = $geo.address.town } |
| 71 | + elseif ($geo.address.suburb) { $city = $geo.address.suburb } |
| 72 | + else { $city = "Unknown" } |
| 73 | + |
| 74 | + if ($geo.address.state) { $state = $geo.address.state } else { $state = "Unknown" } |
| 75 | + if ($geo.address.country) { $country = $geo.address.country } else { $country = "Unknown" } |
| 76 | + |
| 77 | + # Normalize Brisbane |
| 78 | + if ($city -match 'Brisbane') { $city = "Brisbane" } |
| 79 | + |
| 80 | + } catch { |
| 81 | + $city = $state = $country = "Unknown" |
| 82 | + } |
| 83 | + |
| 84 | + # Construct CSV line |
| 85 | + $csvLine = "{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}" -f ` |
| 86 | + (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $lat, $lon, $accuracy, $city, $state, $country, $source, $publicIP, $ssidCSV, $bssidCSV |
| 87 | + |
| 88 | + # Output to console |
| 89 | + Write-Host $csvLine |
| 90 | + |
| 91 | + # Append to CSV logs |
| 92 | + Add-Content -Path $logFile -Value $csvLine |
| 93 | + if ($city -ne "Brisbane") { Add-Content -Path $alertFile -Value $csvLine } |
| 94 | + |
| 95 | + Start-Sleep 15 |
| 96 | +} |
0 commit comments