Public/Set-PSUAzureOpenAIEnvironment.ps1
|
function Set-PSUAzureOpenAIEnvironment { <# .SYNOPSIS Automated Azure OpenAI Service setup and environment variable configuration. .DESCRIPTION This function automates the complete setup of Azure OpenAI Service including: - Interactive subscription and resource group selection - Azure OpenAI Service resource creation - GPT-4, GPT-4o, GPT-4-Turbo, or GPT-35-Turbo model deployment - Automatic retrieval of endpoint and API keys - Environment variable configuration for AI-powered utilities PREREQUISITES: - Azure PowerShell modules (Az.Accounts, Az.Resources, Az.CognitiveServices) - Active Azure subscription with Azure OpenAI access approval - Must run Connect-AzAccount before executing this function - Contributor or Owner role on the target subscription .PARAMETER ResourceGroupName (Optional) Name of the resource group for Azure OpenAI resources. If not provided, interactive selection of existing or creation of new resource group is offered. .PARAMETER Location (Optional) Azure region for deployment. Default is 'eastus'. Available regions: eastus, eastus2, westus, westus2. .PARAMETER OpenAIServiceName (Optional) Name for the Azure OpenAI Service resource. Must be globally unique. If not provided, a unique name will be generated using timestamp suffix. .PARAMETER DeploymentName (Optional) Name for the model deployment within the Azure OpenAI Service. Default is 'gpt-4-deployment'. .PARAMETER ModelName (Optional) Model to deploy in the Azure OpenAI Service. Default is 'gpt-4'. Valid options: 'gpt-4', 'gpt-35-turbo', 'gpt-4-turbo', 'gpt-4o'. .EXAMPLE Set-PSUAzureOpenAIEnvironment Interactive mode - guides through all setup steps and automatically configures environment variables. .EXAMPLE Set-PSUAzureOpenAIEnvironment -ResourceGroupName "rg-ai-tools" -Location "eastus" Creates Azure OpenAI resources in specified resource group and location with default GPT-4 model. .EXAMPLE Set-PSUAzureOpenAIEnvironment -ModelName "gpt-4o" -DeploymentName "gpt4o-deployment" Deploys GPT-4o model with custom deployment name using interactive resource group selection. .OUTPUTS [PSCustomObject] .NOTES Author: Lakshmanachari Panuganti Date: 7th October 2025 Requires: Azure OpenAI access approval for subscription (request at https://aka.ms/oai/access) Environment Variables Set by this function: - API_KEY_AZURE_OPENAI: Azure OpenAI Service API key - AZURE_OPENAI_ENDPOINT: Azure OpenAI Service endpoint URL - AZURE_OPENAI_DEPLOYMENT: Model deployment name .LINK https://github.com/lakshmanachari-panuganti/OMG.PSUtilities/tree/main/OMG.PSUtilities.AI https://www.linkedin.com/in/lakshmanachari-panuganti/ https://www.powershellgallery.com/packages/OMG.PSUtilities.AI https://learn.microsoft.com/en-us/azure/ai-services/openai/ #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Justification = 'Console UX: interactive setup requires formatted, colorized output for user guidance' )] param( [Parameter()] [string]$ResourceGroupName, [Parameter()] [ValidateSet('eastus', 'eastus2', 'westus', 'westus2')] [string]$Location = 'eastus', [Parameter()] [string]$OpenAIServiceName, [Parameter()] [string]$DeploymentName = 'gpt-4-deployment', [Parameter()] [ValidateSet('gpt-4', 'gpt-35-turbo', 'gpt-4-turbo', 'gpt-4o')] [string]$ModelName = 'gpt-4' ) process { try { # Check if required modules are installed Write-Step "Checking required Azure PowerShell modules..." $requiredModules = @('Az.Accounts', 'Az.Resources', 'Az.CognitiveServices') foreach ($module in $requiredModules) { if (-not (Get-Module -ListAvailable -Name $module)) { Write-Info "Module '$module' not found. Installing from PowerShell Gallery..." try { Install-Module -Name $module -Force -AllowClobber -Scope CurrentUser -ErrorAction Stop Write-Success "$module installed successfully" } catch { Write-ErrorMsg "Failed to install $module`: $($_.Exception.Message)" throw "Unable to install required module: $module. Please install manually and try again." } } else { Write-Success "$module is already installed" } } # Check if connected to Azure Write-Step "Checking Azure connection..." $context = Get-AzContext if (-not $context) { throw "Not connected to Azure. Please run 'Connect-AzAccount' before executing this function." } Write-Success "Connected to Azure as: $($context.Account.Id)" Write-Info "Subscription: $($context.Subscription.Name) ($($context.Subscription.Id))" # Select or confirm subscription Write-Step "Subscription Selection" $subscriptions = Get-AzSubscription if ($subscriptions.Count -gt 1) { Write-Host "`nAvailable Subscriptions:" -ForegroundColor Yellow for ($i = 0; $i -lt $subscriptions.Count; $i++) { Write-Host " [$($i + 1)] $($subscriptions[$i].Name) ($($subscriptions[$i].Id))" } $selection = Read-Host "`nSelect subscription number [1-$($subscriptions.Count)] or press Enter to use current" if ($selection -ne '') { Set-AzContext -SubscriptionId $subscriptions[[int]$selection - 1].Id | Out-Null Write-Success "Switched to subscription: $($subscriptions[[int]$selection - 1].Name)" } } # Resource Group selection/creation Write-Step "Resource Group Configuration" if (-not $ResourceGroupName) { $existingRGs = Get-AzResourceGroup Write-Host "`nOptions:" -ForegroundColor Yellow Write-Host " [1] Create new resource group" for ($i = 0; $i -lt $existingRGs.Count; $i++) { Write-Host " [$($i + 2)] Use existing: $($existingRGs[$i].ResourceGroupName) ($($existingRGs[$i].Location))" } $rgSelection = Read-Host "`nSelect option [1-$($existingRGs.Count + 1)]" if ($rgSelection -eq '1') { $ResourceGroupName = Read-Host "Enter new resource group name" $userLocation = Read-Host "Enter location (default: eastus)" if (-not [string]::IsNullOrWhiteSpace($userLocation)) { $Location = $userLocation } Write-Info "Creating resource group: $ResourceGroupName in $Location..." New-AzResourceGroup -Name $ResourceGroupName -Location $Location | Out-Null Write-Success "Resource group created successfully" } else { $selectedRG = $existingRGs[[int]$rgSelection - 2] $ResourceGroupName = $selectedRG.ResourceGroupName $Location = $selectedRG.Location Write-Success "Using existing resource group: $ResourceGroupName" } } else { # Check if provided resource group exists $rg = Get-AzResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue if (-not $rg) { Write-Info "Resource group '$ResourceGroupName' does not exist. Creating..." New-AzResourceGroup -Name $ResourceGroupName -Location $Location | Out-Null Write-Success "Resource group created successfully" } else { Write-Success "Using existing resource group: $ResourceGroupName" $Location = $rg.Location } } # Generate unique OpenAI Service name if not provided if (-not $OpenAIServiceName) { $randomSuffix = Get-Date -Format "yyMMddHHmm" $OpenAIServiceName = "omg-psutilities-$randomSuffix" Write-Info "Generated Azure OpenAI Service name: $OpenAIServiceName" } # Create Azure OpenAI Service Write-Step "Creating Azure OpenAI Service: $OpenAIServiceName" $getAzCognitiveServicesParams = @{ ResourceGroupName = $ResourceGroupName Name = $OpenAIServiceName ErrorAction = 'SilentlyContinue' } $openAIService = Get-AzCognitiveServicesAccount @getAzCognitiveServicesParams if ($openAIService) { Write-Info "Azure OpenAI Service '$OpenAIServiceName' already exists" } else { Write-Info "Creating Azure OpenAI Service in $Location... (This may take 2-3 minutes)" $newAzCognitiveServicesParams = @{ ResourceGroupName = $ResourceGroupName Name = $OpenAIServiceName Type = "OpenAI" SkuName = "S0" Location = $Location CustomSubdomainName = $OpenAIServiceName } try { $openAIService = New-AzCognitiveServicesAccount @newAzCognitiveServicesParams Write-Success "Azure OpenAI Service created successfully" } catch { Write-ErrorMsg "Failed to create Azure OpenAI Service: $($_.Exception.Message)" Write-Info "Common issues:" Write-Info " - Azure OpenAI access not approved for your subscription (Request access at: https://aka.ms/oai/access)" Write-Info " - Name already taken (try a different name)" Write-Info " - Region not supporting Azure OpenAI (try: eastus, westeurope, or swedencentral)" throw } } # Get endpoint and keys Write-Step "Retrieving Azure OpenAI configuration..." $endpoint = $openAIService.Endpoint $keys = Get-AzCognitiveServicesAccountKey -ResourceGroupName $ResourceGroupName -Name $OpenAIServiceName $apiKey = $keys.Key1 Write-Success "Endpoint: $endpoint" Write-Success "API Key retrieved successfully" # Create model deployment Write-Step "Creating model deployment: $DeploymentName ($ModelName)" # Check if deployment already exists $deployments = az cognitiveservices account deployment list ` --resource-group $ResourceGroupName ` --name $OpenAIServiceName ` --query "[?name=='$DeploymentName'].name" ` --output tsv 2>$null if ($deployments -contains $DeploymentName) { Write-Info "Deployment '$DeploymentName' already exists" } else { Write-Info "Creating deployment... (This may take 1-2 minutes)" # Model version mapping - using latest non-deprecated versions $modelVersion = switch ($ModelName) { 'gpt-4' { 'turbo-2024-04-09' } 'gpt-4-turbo' { 'turbo-2024-04-09' } 'gpt-4o' { '2024-08-06' } 'gpt-35-turbo' { '0125' } default { 'turbo-2024-04-09' } } # Adjust model name for newer versions $actualModelName = switch ($ModelName) { 'gpt-4' { 'gpt-4' } 'gpt-4-turbo' { 'gpt-4' } 'gpt-4o' { 'gpt-4o' } 'gpt-35-turbo' { 'gpt-35-turbo' } default { 'gpt-4' } } $deployOutput = az cognitiveservices account deployment create ` --resource-group $ResourceGroupName ` --name $OpenAIServiceName ` --deployment-name $DeploymentName ` --model-name $actualModelName ` --model-version $modelVersion ` --model-format OpenAI ` --sku-capacity 1 ` --sku-name "Standard" 2>&1 # Check for errors in output if ($LASTEXITCODE -ne 0) { Write-ErrorMsg "Deployment creation failed!" Write-Host $deployOutput -ForegroundColor Red Write-Info "`nYou need to create the deployment manually in Azure Portal:" Write-Info " 1. Go to: https://portal.azure.com" Write-Info " 2. Navigate to: $ResourceGroupName > $OpenAIServiceName > Model deployments" Write-Info " 3. Click 'Create new deployment' or 'Manage Deployments'" Write-Info " 4. Select the latest available model version" Write-Info " 5. Name it: $DeploymentName" } elseif ($deployOutput -match 'ERROR:|deprecated') { Write-ErrorMsg "Deployment created with warnings:" Write-Host $deployOutput -ForegroundColor Yellow Write-Info "`nConsider updating the model version in Azure Portal if needed" } else { Write-Success "Model deployment created successfully" } } # Set environment variables Write-Step "Setting Environment Variables" Set-PSUUserEnvironmentVariable -Name 'API_KEY_AZURE_OPENAI' -Value $apiKey Set-PSUUserEnvironmentVariable -Name 'AZURE_OPENAI_ENDPOINT' -Value $endpoint Set-PSUUserEnvironmentVariable -Name 'AZURE_OPENAI_DEPLOYMENT' -Value $DeploymentName Write-Success "Environment variables set successfully (User level)" Write-Info "Variables are now available in this session and will persist for your user account" Write-Info "To use in new PowerShell sessions, restart PowerShell or open a new window" # Return configuration object [PSCustomObject]@{ ResourceGroupName = $ResourceGroupName ServiceName = $OpenAIServiceName Location = $Location DeploymentName = $DeploymentName ModelName = $ModelName Endpoint = $endpoint ApiKey = $apiKey SubscriptionId = $context.Subscription.Id SubscriptionName = $context.Subscription.Name PSTypeName = 'PSU.AzureOpenAI.Configuration' } } catch { $PSCmdlet.ThrowTerminatingError($_) } } } |