Private/Invoke-VBLoadOUITable.ps1
|
function Invoke-VBLoadOUITable { <# .SYNOPSIS Load (and if necessary download/refresh) the IEEE OUI CSV into a hashtable. Private helper used only by Get-VBOUIVendor. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$OUIFilePath ) $OUI_URL = 'https://standards-oui.ieee.org/oui/oui.csv' $REFRESH_DAYS = 30 $MIN_SIZE_BYTES = 1MB # Ensure parent folder exists $parent = Split-Path -Path $OUIFilePath -Parent if (-not (Test-Path -LiteralPath $parent)) { New-Item -Path $parent -ItemType Directory -Force | Out-Null } $needsDownload = $false if (-not (Test-Path -LiteralPath $OUIFilePath)) { Write-Verbose "[OUI] oui.csv not found -- downloading from IEEE" $needsDownload = $true } else { $item = Get-Item -LiteralPath $OUIFilePath if ($item.Length -lt $MIN_SIZE_BYTES) { Write-Verbose "[OUI] oui.csv too small ($([int]($item.Length/1KB)) KB) -- re-downloading" $needsDownload = $true } elseif (((Get-Date) - $item.LastWriteTime).TotalDays -gt $REFRESH_DAYS) { Write-Verbose "[OUI] oui.csv is $([int]((Get-Date) - $item.LastWriteTime).TotalDays) days old (threshold $REFRESH_DAYS) -- refreshing" $needsDownload = $true } } if ($needsDownload) { try { if ($PSVersionTable.PSVersion.Major -lt 6) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 } Write-Verbose "[OUI] Downloading OUI database from $OUI_URL ..." $tmpPath = "$OUIFilePath.tmp" Invoke-WebRequest -Uri $OUI_URL -OutFile $tmpPath -UseBasicParsing -ErrorAction Stop # Validate the download before replacing $tmpItem = Get-Item -LiteralPath $tmpPath if ($tmpItem.Length -lt $MIN_SIZE_BYTES) { Remove-Item -LiteralPath $tmpPath -Force -ErrorAction SilentlyContinue throw "Downloaded file too small ($([int]($tmpItem.Length/1KB)) KB) -- download may have failed" } # Replace old file if (Test-Path -LiteralPath $OUIFilePath) { Remove-Item -LiteralPath $OUIFilePath -Force } Move-Item -LiteralPath $tmpPath -Destination $OUIFilePath -Force Write-Verbose "[OUI] Download complete: $([math]::Round($tmpItem.Length/1MB,1)) MB" } catch { Write-Warning "[OUI] Download failed: $($_.Exception.Message). Vendor lookup will be unavailable this session." return @{} } } # Import CSV into hashtable keyed by 6-char uppercase OUI (Assignment column) Write-Verbose "[OUI] Loading OUI table into memory..." $table = @{} try { $rows = Import-Csv -LiteralPath $OUIFilePath -Encoding UTF8 -ErrorAction Stop foreach ($row in $rows) { # IEEE CSV columns: Registry, Assignment, "Organization Name", "Organization Address" $oui = $row.Assignment.ToUpperInvariant().Trim() $vendor = $row.'Organization Name'.Trim() if ($oui.Length -eq 6 -and -not [string]::IsNullOrWhiteSpace($vendor)) { $table[$oui] = $vendor } } Write-Verbose "[OUI] Table loaded: $($table.Count) OUI entries" } catch { Write-Warning "[OUI] Failed to parse oui.csv: $($_.Exception.Message)" } $table } |