Created
February 26, 2026 08:35
-
-
Save pleabargain/a0fea9e8c0776e29336cdbda196b9f7c to your computer and use it in GitHub Desktop.
you have a list of API keys for your win11 env and you want to get those keys to your WSL env. this script will read your text file and move your keys to WSL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [CmdletBinding()] | |
| param( | |
| [string]$KeysFile = (Join-Path $PSScriptRoot 'keys.md'), | |
| [string]$Distro = '' # e.g. 'Ubuntu' or leave empty for default | |
| ) | |
| function Get-SuggestedEnvName { | |
| param( | |
| [Parameter(Mandatory = $true)] | |
| [string]$Label | |
| ) | |
| $raw = $Label.Trim() | |
| # Normalize: upper + underscores | |
| $base = ($raw.ToUpper() -replace '[^A-Z0-9]+', '_').Trim('_') | |
| if (-not $base) { return $null } | |
| # Known service mappings | |
| switch ($base) { | |
| 'OPENAI' { return 'OPENAI_API_KEY' } | |
| 'REPLICATE' { return 'REPLICATE_API_TOKEN' } | |
| 'EVERART' { return 'EVERART_API_KEY' } | |
| 'GEMINI' { return 'GEMINI_API_KEY' } | |
| 'OPENROUTER' { return 'OPENROUTER_API_KEY' } | |
| 'GROQ' { return 'GROQ_API_KEY' } | |
| 'GROK' { return 'GROK_API_KEY' } | |
| 'BRAVE' { return 'BRAVE_API_KEY' } | |
| 'SERPLY' { return 'SERPLY_API_KEY' } | |
| 'SERPAPI' { return 'SERPAPI_API_KEY' } | |
| 'DEEPGRAM' { return 'DEEPGRAM_API_KEY' } | |
| 'AGENTQL' { return 'AGENTQL_API_KEY' } | |
| 'DEEP_SEEK' { return 'DEEPSEEK_API_KEY' } | |
| 'YOUTUBE' { return 'YOUTUBE_API_KEY' } | |
| 'TRIPADVISOR' { return 'TRIPADVISOR_API_KEY' } | |
| 'TWILIO' { return 'TWILIO_AUTH_TOKEN' } | |
| 'WASSENGER' { return 'WASSENGER_API_KEY' } | |
| 'TWOCHAT' { return 'TWOCHAT_API_KEY' } | |
| default { | |
| if ($base -match 'API|KEY|TOKEN') { | |
| return $base | |
| } | |
| return "${base}_API_KEY" | |
| } | |
| } | |
| } | |
| function Test-WslEnvVariables { | |
| param( | |
| [string[]]$EnvNames, | |
| [string]$Distro = '' | |
| ) | |
| if (-not $EnvNames -or $EnvNames.Count -eq 0) { | |
| return | |
| } | |
| Write-Host '' | |
| Write-Host 'Verifying environment variables inside WSL...' -ForegroundColor Green | |
| if ($Distro) { | |
| $envOutput = wsl.exe -d $Distro env | |
| } else { | |
| $envOutput = wsl.exe env | |
| } | |
| foreach ($name in $EnvNames) { | |
| $line = $envOutput | Where-Object { $_ -like "$name=*" } | |
| if ($line) { | |
| Write-Host " [$name] visible" -ForegroundColor Green | |
| } else { | |
| Write-Warning " [$name] NOT found in WSL env" | |
| } | |
| } | |
| } | |
| function Get-NextKeyCandidate { | |
| param( | |
| [string[]]$Lines, | |
| [int]$StartIndex | |
| ) | |
| # Look ahead a few lines for something that looks like a key/token | |
| for ($j = $StartIndex; $j -lt $Lines.Count -and $j -le $StartIndex + 5; $j++) { | |
| $candidate = $Lines[$j].Trim() | |
| if (-not $candidate) { continue } | |
| if ($candidate -match '^\s*#') { continue } | |
| if ($candidate -match '^https?://') { continue } | |
| # Skip pure separator lines like "-----" | |
| if ($candidate -match '^[\-=]+$') { continue } | |
| # Require some length and at least one letter/number | |
| if ($candidate.Length -lt 10) { continue } | |
| if ($candidate -notmatch '[A-Za-z0-9]') { continue } | |
| # Treat only single-token strings (no spaces) as keys | |
| if ($candidate -match '\s') { continue } | |
| return [pscustomobject]@{ | |
| Index = $j | |
| Value = $candidate | |
| } | |
| } | |
| return $null | |
| } | |
| if (-not (Test-Path -LiteralPath $KeysFile)) { | |
| Write-Error "Keys file not found: $KeysFile" | |
| exit 1 | |
| } | |
| $lines = Get-Content -LiteralPath $KeysFile -Encoding UTF8 | |
| $pairs = New-Object System.Collections.Generic.List[object] | |
| for ($i = 0; $i -lt $lines.Count; $i++) { | |
| $line = $lines[$i].Trim() | |
| if (-not $line) { continue } | |
| if ($line -match '^\s*#') { continue } | |
| if ($line -match '^\s*API\s*:\s*(\S+)\s*$') { | |
| $value = $matches[1] | |
| $pairs.Add([pscustomobject]@{ | |
| Label = 'Telegram' | |
| Value = $value | |
| }) | |
| continue | |
| } | |
| # UPPER_CASE env var name on this line; look ahead for the key | |
| if ($line -match '^[A-Z0-9_]{5,}$') { | |
| $candidate = Get-NextKeyCandidate -Lines $lines -StartIndex ($i + 1) | |
| if ($candidate) { | |
| $pairs.Add([pscustomobject]@{ | |
| Label = $line | |
| Value = $candidate.Value | |
| }) | |
| $i = $candidate.Index | |
| } | |
| continue | |
| } | |
| # Service-style labels (e.g. "OpenAI", "replicate", "groq") – but skip headings like "API keys" | |
| if ($line -match '^[A-Za-z0-9][A-Za-z0-9\s_-]{1,40}$' -and | |
| $line -notmatch '^https?://' -and | |
| $line -notmatch '(?i)keys?') { | |
| $candidate = Get-NextKeyCandidate -Lines $lines -StartIndex ($i + 1) | |
| if ($candidate) { | |
| $pairs.Add([pscustomobject]@{ | |
| Label = $line | |
| Value = $candidate.Value | |
| }) | |
| $i = $candidate.Index | |
| } | |
| } | |
| } | |
| if ($pairs.Count -eq 0) { | |
| Write-Warning "No key candidates found in $KeysFile" | |
| exit 0 | |
| } | |
| $envMap = @{} | |
| foreach ($p in $pairs) { | |
| $label = $p.Label | |
| $value = $p.Value | |
| if (-not $value) { continue } | |
| $suggested = Get-SuggestedEnvName -Label $label | |
| Write-Host '' | |
| Write-Host "Found key with label/context: '$label'" -ForegroundColor Cyan | |
| if ($suggested) { | |
| Write-Host "Suggested env var name: $suggested" -ForegroundColor Yellow | |
| $prompt = "Enter env var name (Enter = use '$suggested', 's' = skip): " | |
| } | |
| else { | |
| $prompt = "Enter env var name (or 's' to skip): " | |
| } | |
| $name = Read-Host -Prompt $prompt | |
| if ($name -eq 's') { | |
| continue | |
| } | |
| if (-not $name) { | |
| if ($suggested) { | |
| $name = $suggested | |
| } | |
| else { | |
| continue | |
| } | |
| } | |
| $name = ($name.Trim() -replace '[^A-Za-z0-9_]', '_').Trim('_') | |
| if (-not $name) { continue } | |
| $envMap[$name] = $value | |
| } | |
| if ($envMap.Count -eq 0) { | |
| Write-Warning 'No environment variables selected; not starting WSL.' | |
| exit 0 | |
| } | |
| Write-Host '' | |
| Write-Host 'Setting environment variables for WSL (names only):' -ForegroundColor Green | |
| $envMap.Keys | ForEach-Object { Write-Host " $_" } | |
| foreach ($k in $envMap.Keys) { | |
| Set-Item -Path "Env:$k" -Value $envMap[$k] | |
| } | |
| # Ensure these variables are propagated into WSL via WSLENV | |
| $existingWslEnv = $env:WSLENV | |
| $entries = @() | |
| if ($existingWslEnv) { | |
| $entries += $existingWslEnv.Split(':') | Where-Object { $_ } | |
| } | |
| foreach ($k in $envMap.Keys) { | |
| $entryWithFlag = "$k/u" | |
| $already = $false | |
| foreach ($e in $entries) { | |
| $varName = $e.Split('/')[0] | |
| if ($varName -eq $k) { | |
| $already = $true | |
| break | |
| } | |
| } | |
| if (-not $already) { | |
| $entries += $entryWithFlag | |
| } | |
| } | |
| if ($entries.Count -gt 0) { | |
| $env:WSLENV = ($entries -join ':') | |
| } | |
| Test-WslEnvVariables -EnvNames $envMap.Keys -Distro $Distro | |
| Write-Host '' | |
| Write-Host 'Launching WSL...' -ForegroundColor Green | |
| if ($Distro) { | |
| wsl.exe -d $Distro | |
| } | |
| else { | |
| wsl.exe | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment