Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Deploy, evaluate, and manage AI agents end-to-end on Microsoft Azure AI Foundry
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