Skip to content

Instantly share code, notes, and snippets.

@da5is
Created August 4, 2026 19:00
Show Gist options
  • Select an option

  • Save da5is/858fae0cff726404e48c17a3f8f0e876 to your computer and use it in GitHub Desktop.

Select an option

Save da5is/858fae0cff726404e48c17a3f8f0e876 to your computer and use it in GitHub Desktop.
FoundryPicker.ps1
#!/usr/bin/env pwsh
# Interactive BYOM launcher for GitHub Copilot CLI (PowerShell edition).
#
# ./run_copilot_foundry.ps1
#
# Walks every Azure AI Foundry (Cognitive Services / AIServices) resource you
# can see, lists their model deployments, and lets you pick one. It then mints a
# short-lived Entra (Azure AD) bearer token scoped to Cognitive Services, sets
# the COPILOT_* provider variables, and launches Copilot in that context. When
# Copilot exits, the COPILOT_* variables are cleared again.
#
# Run it directly: the env vars only live for this process and its child Copilot
# process, and are cleared on exit.
[CmdletBinding()]
param(
[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$CopilotArgs
)
$ErrorActionPreference = 'Stop'
$BYOM_TOKEN_RESOURCE = 'https://cognitiveservices.azure.com'
# Azure OpenAI data-plane requires an explicit api-version query parameter.
$BYOM_AZURE_API_VERSION = if ($env:BYOM_AZURE_API_VERSION) { $env:BYOM_AZURE_API_VERSION } else { '2024-10-21' }
# Honor the work-scoped Azure CLI config if present, else use default creds.
$workConfig = Join-Path $HOME '.azure-work'
if (Test-Path -LiteralPath $workConfig -PathType Container) {
$env:AZURE_CONFIG_DIR = $workConfig
}
foreach ($bin in @('az', 'copilot')) {
if (-not (Get-Command $bin -ErrorAction SilentlyContinue)) {
Write-Error "Required command '$bin' not found on PATH."
exit 1
}
}
Write-Host 'Discovering Azure AI Foundry resources...' -ForegroundColor Cyan
# Grab every AIServices / OpenAI account visible to the current credential.
$accountsRaw = az cognitiveservices account list `
--query "[?kind=='AIServices' || kind=='OpenAI'].{name:name, rg:resourceGroup, endpoint:properties.endpoint, location:location}" `
-o json 2>$null
$accounts = @()
if ($accountsRaw) { $accounts = $accountsRaw | ConvertFrom-Json }
if (-not $accounts -or $accounts.Count -eq 0) {
Write-Error "No Foundry (AIServices/OpenAI) resources found for the current context.`nEnsure you are logged in ('az login') and pointed at the right subscription."
exit 1
}
# Build a flat list of model deployments across all discovered resources.
$options = New-Object System.Collections.Generic.List[object]
foreach ($account in $accounts) {
$deploymentsRaw = az cognitiveservices account deployment list `
-n $account.name -g $account.rg `
--query "[?properties.provisioningState=='Succeeded'].{name:name, model:properties.model.name}" `
-o json 2>$null
$deployments = @()
if ($deploymentsRaw) { $deployments = $deploymentsRaw | ConvertFrom-Json }
foreach ($dep in $deployments) {
$endpoint = $account.endpoint.TrimEnd('/')
$options.Add([pscustomobject]@{
Endpoint = $endpoint
Model = $dep.model
Deployment = $dep.name
Label = "$($account.name) ($($account.location)) -> $($dep.name) [model: $($dep.model)]"
})
}
}
if ($options.Count -eq 0) {
Write-Error 'Found Foundry resources but no succeeded model deployments to offer.'
exit 1
}
Write-Host ''
Write-Host 'Available Foundry model deployments:'
for ($i = 0; $i -lt $options.Count; $i++) {
'{0,4}) {1}' -f ($i + 1), $options[$i].Label | Write-Host
}
Write-Host ''
$choice = $null
while ($true) {
$answer = Read-Host "Select a deployment [1-$($options.Count)] (q to quit)"
if ($answer -match '^[qQ]$') {
Write-Host 'Aborted.'
exit 0
}
if ($answer -notmatch '^\d+$') {
Write-Host 'Please enter a number.'
continue
}
$num = [int]$answer
if ($num -ge 1 -and $num -le $options.Count) {
$choice = $num
break
}
Write-Host 'Out of range.'
}
$sel = $options[$choice - 1]
Write-Host "Acquiring Entra bearer token for $BYOM_TOKEN_RESOURCE..." -ForegroundColor Cyan
$token = az account get-access-token `
--resource $BYOM_TOKEN_RESOURCE `
--query accessToken -o tsv 2>$null
if (-not $token) {
Write-Error "Failed to acquire Entra bearer token via 'az account get-access-token'.`nEnsure you are logged in ('az login') and have access to the Foundry resource."
exit 1
}
$env:COPILOT_PROVIDER_TYPE = 'azure'
$env:COPILOT_PROVIDER_BASE_URL = "$($sel.Endpoint)/openai/deployments/$($sel.Deployment)"
$env:COPILOT_PROVIDER_AZURE_API_VERSION = $BYOM_AZURE_API_VERSION
$env:COPILOT_PROVIDER_MODEL_ID = $sel.Model
$env:COPILOT_PROVIDER_BEARER_TOKEN = $token
Write-Host "BYOM enabled: $($env:COPILOT_PROVIDER_MODEL_ID) via $($env:COPILOT_PROVIDER_BASE_URL) (api-version $($env:COPILOT_PROVIDER_AZURE_API_VERSION), Entra bearer token)." -ForegroundColor Green
try {
Write-Host 'Launching Copilot...' -ForegroundColor Cyan
if ($CopilotArgs) {
copilot @CopilotArgs
} else {
copilot
}
}
finally {
# Always clear the provider variables when Copilot exits, however it exits.
Remove-Item Env:COPILOT_PROVIDER_TYPE -ErrorAction SilentlyContinue
Remove-Item Env:COPILOT_PROVIDER_BASE_URL -ErrorAction SilentlyContinue
Remove-Item Env:COPILOT_PROVIDER_AZURE_API_VERSION -ErrorAction SilentlyContinue
Remove-Item Env:COPILOT_PROVIDER_MODEL_ID -ErrorAction SilentlyContinue
Remove-Item Env:COPILOT_PROVIDER_BEARER_TOKEN -ErrorAction SilentlyContinue
Write-Host 'BYOM disabled: COPILOT_* provider variables cleared.'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment