Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build and deploy AI applications on Azure AI Foundry using Microsoft's model catalog and AI services
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
foundry-agent/create/scripts/verify-environment.ps1
1<#2.SYNOPSIS3Verifies the local environment for creating a hosted Foundry agent with `azd ai`.4.DESCRIPTION5Runs all the read-only checks in one pass and prints a single concise summary,6so the agent does not have to run (and reason over) each azd command separately.78Output lines are prefixed with [OK], [WARN], or [ACTION].9Exit code is 0 when no blocking actions remain, 1 when at least one [ACTION] is required.10.EXAMPLE11./verify-environment.ps112#>1314$ErrorActionPreference = "Stop"15$actionRequired = $false1617function Note-Ok { param([string]$m) Write-Output "[OK] $m" }18function Note-Warn { param([string]$m) Write-Output "[WARN] $m" }19function Note-Action { param([string]$m) Write-Output "[ACTION] $m"; $script:actionRequired = $true }2021function Get-AzdJson {22param([string[]]$AzdArgs)23try {24$raw = & azd @AzdArgs 2>$null25if (-not $raw) { return $null }26return ($raw | ConvertFrom-Json -ErrorAction Stop)27} catch {28return $null29}30}3132# Refresh PATH to pick up recently-installed tools (e.g. azd installed in same session)33$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")3435function Add-CommandFallbackPath {36param(37[string] $CommandName,38[string[]] $Directories39)4041if (Get-Command $CommandName -ErrorAction SilentlyContinue) {42return [pscustomobject]@{ Found = $true; AddedPath = $null }43}4445foreach ($dir in $Directories) {46if (-not $dir) { continue }47foreach ($ext in @(".exe", ".cmd", ".bat")) {48$candidate = Join-Path $dir "$CommandName$ext"49if (Test-Path $candidate) {50$env:Path = "$dir;$env:Path"51return [pscustomobject]@{ Found = $true; AddedPath = $dir }52}53}54}5556return [pscustomobject]@{ Found = [bool](Get-Command $CommandName -ErrorAction SilentlyContinue); AddedPath = $null }57}5859function Test-AzdAuthLoggedIn {60$raw = ""61try {62$raw = (& azd auth login --check-status 2>&1) -join "`n"63} catch {64$raw = $_ | Out-String65}66$authExit = $LASTEXITCODE6768if ($raw -match "(?i)(not\s+logged\s+in|not\s+authenticated|no\s+account|login\s+required|please\s+run.*azd\s+auth\s+login|run.*azd\s+auth\s+login|expired)") {69return $false70}7172if ($raw -match "(?i)(logged\s+in|authenticated|already\s+logged\s+in)") {73return $true74}7576# Unrecognized output -- fall back to exit code77return ($authExit -eq 0)78}7980# 1. Required CLIs81# Check PATH first, then probe common install locations (winget, MSI, chocolatey)82$azdCommand = Add-CommandFallbackPath "azd" @(83"$env:LOCALAPPDATA\Programs\Azure Dev CLI",84"$env:ProgramFiles\Azure Dev CLI",85"${env:ProgramFiles(x86)}\Azure Dev CLI",86"$env:USERPROFILE\.azd\bin"87)88$azdInstalled = $azdCommand.Found89if ($azdCommand.AddedPath) {90Note-Warn "azd found at '$($azdCommand.AddedPath)' but was not on PATH. Added automatically for this session."91}92if (-not $azdInstalled) {93Note-Action "Azure Developer CLI (azd) is not installed. Install it from https://aka.ms/azd-install, then re-run."94}9596$azCommand = Add-CommandFallbackPath "az" @(97"$env:ProgramFiles\Microsoft SDKs\Azure\CLI2\wbin",98"${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\CLI2\wbin"99)100$azInstalled = $azCommand.Found101if ($azCommand.AddedPath) {102Note-Warn "az found at '$($azCommand.AddedPath)' but was not on PATH. Added automatically for this session."103}104if (-not $azInstalled) {105Note-Action "Azure CLI (az) is not installed. Install it from https://aka.ms/installazurecli, then re-run."106}107108if (-not $azdInstalled -or -not $azInstalled) {109Write-Output ""110Write-Output "Summary: CLI missing -- cannot continue."111exit 1112}113114$verJson = Get-AzdJson @("version", "--output", "json")115$azdVersion = if ($verJson -and $verJson.azd -and $verJson.azd.version) { $verJson.azd.version } else { "unknown" }116Note-Ok "azd installed (version $azdVersion)."117118try {119$azVersionRaw = (& az version --query '"azure-cli"' -o tsv 2>$null) -join "`n"120} catch {121$azVersionRaw = ""122}123$azVersion = if ($azVersionRaw) { $azVersionRaw.Trim() } else { "unknown" }124Note-Ok "Azure CLI installed (version $azVersion)."125126# 2. Required azd extensions127try {128$extRaw = (& azd extension list --output json 2>$null) -join "`n"129} catch {130$extRaw = ""131}132foreach ($ext in @("azure.ai.agents", "azure.ai.projects")) {133if ($extRaw -match [regex]::Escape($ext)) {134Note-Ok "Extension '$ext' is installed."135} else {136Note-Action "Extension '$ext' is missing. Run: azd extension install $ext"137}138}139140# 3. Auth status141if (Test-AzdAuthLoggedIn) {142Note-Ok "Logged in to azd."143} else {144Note-Action "Not logged in to azd. Ask the user to run 'azd auth login' (it opens a browser; never run it for them)."145}146147try {148$azAccountRaw = (& az account show --output json 2>$null) -join "`n"149} catch {150$azAccountRaw = ""151}152if (-not $azAccountRaw) {153Note-Action "Not logged in to Azure CLI. Ask the user to run 'az login' (it opens a browser; never run it for them)."154} else {155try {156$azAccount = $azAccountRaw | ConvertFrom-Json -ErrorAction Stop157$state = if ($azAccount.PSObject.Properties.Name -contains "state") { $azAccount.state } else { "" }158if ($state -and $state -ne "Enabled") {159Note-Action "Azure CLI active subscription state is '$state'. Ask the user to select an enabled subscription with 'az account set --subscription <id>'."160} else {161$subName = if ($azAccount.PSObject.Properties.Name -contains "name" -and $azAccount.name) { $azAccount.name } else { "unknown" }162Note-Ok "Azure CLI logged in (subscription: $subName)."163}164} catch {165Note-Action "Unable to verify Azure CLI login status. Ask the user to run 'az login' and re-run this script."166}167}168169if ($actionRequired) {170Write-Output ""171Write-Output "Summary: action required -- resolve the [ACTION] items above before continuing."172exit 1173}174175# 4. Foundry project endpoint (optional at this stage)176# Short-circuit when there's no azd project in cwd: `azd ai project show` / `agent show`177# would just return nothing after a ~3s subprocess each.178if (-not (Test-Path "azure.yaml")) {179Note-Warn "No Foundry project endpoint set yet. A new project will be created at provision/deploy time, or supply an existing project resource ID."180Note-Ok "No agent deployed yet. Proceed with create."181} else {182$projectJson = Get-AzdJson @("ai", "project", "show", "--output", "json")183$endpoint = $null184if ($projectJson) {185foreach ($k in @("endpoint", "projectEndpoint", "aiProjectEndpoint")) {186if ($projectJson.PSObject.Properties.Name -contains $k -and $projectJson.$k) {187$endpoint = $projectJson.$k188break189}190}191}192if ($endpoint) {193Note-Ok "Foundry project endpoint configured: $endpoint"194} else {195Note-Warn "No Foundry project endpoint set yet. A new project will be created at provision/deploy time, or supply an existing project resource ID."196}197198# 5. Agent deployment status199$agentJson = Get-AzdJson @("ai", "agent", "show", "--output", "json")200if ($agentJson) {201$status = if ($agentJson.PSObject.Properties.Name -contains "status" -and $agentJson.status) { $agentJson.status } else { "unknown" }202switch ($status) {203{ $_ -in @("active", "deployed") } { Note-Ok "An agent is already deployed (status: $status). Skip to deploy.md to redeploy, or tools to add a tool." }204"not_deployed" { Note-Ok "No agent deployed yet (status: not_deployed). Proceed with create." }205default { Note-Warn "Agent status: $status." }206}207} else {208Note-Ok "No agent deployed yet. Proceed with create."209}210}211212Write-Output ""213if ($actionRequired) {214Write-Output "Summary: action required -- resolve the [ACTION] items above before continuing."215exit 1216} else {217Write-Output "Summary: environment ready for 'azd ai' hosted-agent creation."218exit 0219}220