Microsoft Azure — Azure CLI & PowerShell
Master Azure CLI and PowerShell for managing Azure resources.
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
- ✓An Azure subscription (free tier works)
- ✓Basic command-line knowledge
- ✓Azure CLI installed or Cloud Shell access
Azure CLI and PowerShell are like remote controls for your Azure cloud. Instead of clicking through web pages, you type commands to create, update, and delete resources — faster, repeatable, and scriptable.
Clicking through the Azure portal works for a one-off setup. For production, you need automation. Azure CLI and PowerShell are the two primary command-line tools that let you script every aspect of Azure management — from provisioning VMs to configuring network security groups. This article covers both tools in depth: installation, core commands, scripting patterns, error handling, and production automation workflows.
Installing Azure CLI and PowerShell Az Module
Azure CLI can be installed on macOS (brew install azure-cli), Windows (MSI installer), and Linux (apt/dnf). PowerShell Az module installs via Install-Module Az from the PowerShell Gallery. Both tools use Azure AD for authentication. Run 'az login' or 'Connect-AzAccount' to authenticate interactively. For automation, use service principals with certificate or secret-based authentication.
Azure CLI Core Commands: Resource Management
Azure CLI organizes commands by Azure resource type. Key command groups include: 'az group' for resource groups, 'az vm' for virtual machines, 'az network' for networking, 'az storage' for storage accounts, and 'az aks' for Kubernetes. Commands follow a consistent pattern: 'az
PowerShell Az Module: Working with Resources
The Az module follows PowerShell conventions with Get-/New-/Remove-/Set- verb-noun patterns. Common cmdlets: 'Get-AzResourceGroup', 'New-AzVM', 'Remove-AzResource'. PowerShell leverages the pipeline for chaining commands. The Az module supports what-if (-WhatIf) and confirm (-Confirm) flags for safe execution. Use 'Set-AzContext' to switch between subscriptions.
Service Principal Authentication for Automation
For CI/CD pipelines and unattended scripts, use service principal authentication. Create a service principal with 'az ad sp create-for-rbac' or 'New-AzADServicePrincipal'. Assign RBAC roles at the desired scope. Store credentials in Azure Key Vault or environment variables. For GitHub Actions, use 'azure/login' action with a service principal secret. For Azure DevOps, use Azure Resource Manager service connection.
Scripting Patterns: Idempotent Automation
Production scripts must be idempotent — running them multiple times produces the same result. Check resource existence before creating: 'az resource show --name my-resource' and only create if not found. Use '--no-wait' for long-running operations and poll with 'az resource wait'. Use '--only-show-errors' for cleaner output. PowerShell native error handling with try/catch/finally and $ErrorActionPreference='Stop' ensures scripts fail fast on errors.
Error Handling and Troubleshooting
Azure CLI returns exit code 0 for success, non-zero for failure. Set 'set -e' in bash scripts to stop on first error. Use 'az account show --output tsv --query id || az login' to auto-reauthenticate. For PowerShell, set '$ErrorActionPreference = "Stop"' and implement retry logic with Start-Sleep for throttling (HTTP 429). Use '--debug' flag on CLI commands for verbose output. Enable resource logs and use 'az monitor diagnostic-settings' to capture management operations.
Azure CLI vs PowerShell: When to Use Each
Azure CLI excels at quick operations, Linux/macOS workflows, and simple scripting. PowerShell Az module shines in complex automation, Windows-native environments, and when working with .NET libraries. For CI/CD pipelines, both work equally well. Many teams use CLI for ad-hoc operations and PowerShell for scheduled automation runbooks. The choice often depends on team expertise — use what your team knows best while maintaining consistent patterns.
Azure CLI Extensions: Dynamic Install and Extension Management
Azure CLI extensions provide access to experimental, preview, and specialized commands not included in the base CLI. Extensions are Python wheels that run as CLI commands. Use az extension list-available to see Microsoft-maintained extensions. Install by name with az extension add --name . Starting with CLI 2.12.0, dynamic install is enabled by default -- when you run an unrecognized command, the CLI auto-installs the required extension. Control this with az config set extension.use_dynamic_install=yes_without_prompt. Key extensions for Azure management include: azure-devops (Azure Boards, Repos, Pipelines from CLI), managementpartner (Azure Partner management), resource-graph (Azure Resource Graph queries), and account (subscription management). Update extensions with az extension update --name . List installed extensions with az extension list. For production scripts, pin extension versions to avoid unexpected breaking changes from auto-updates. Extensions are stored in $HOME/.azure/cliextensions on Linux/macOS. For CI/CD pipelines with restricted outbound access, pre-install required extensions in the agent image. Note that extensions are updated independently from the CLI -- always test extension upgrades in a non-production environment.
az extension list-available --show-details for version info.Deploying ARM and Bicep with CLI and PowerShell
Both Azure CLI and PowerShell Az can deploy infrastructure-as-code templates. For CLI, use az deployment group create --template-file main.bicep for resource groups or az deployment sub create for subscriptions. Preview changes with az deployment group what-if. Pass parameters inline (--parameters storageName=mystorage) or via parameter files (--parameters @params.json). For PowerShell, use New-AzResourceGroupDeployment -TemplateFile main.bicep. Bicep files are compiled to ARM JSON automatically during deployment. For CI/CD, store parameter files per environment under version control. Use --no-wait for long-running deployments and poll with az deployment group show. PowerShell supports -WhatIf and -Confirm for safe execution. For subscription-scoped deployments (policy definitions, role assignments), use az deployment sub create. Manage resource lifecycles with deployment stacks: az stack group create to create, az stack group list to detect drift, and az stack group delete --detach-all for cleanup. Always use --output tsv in CLI scripts for machine-parseable results. For PowerShell, use Select-Object -Property to extract specific values.
what-if before production deployments. It shows resource changes (including deletions) without applying them. We once had a template that deleted a storage account -- what-if caught it before the deployment.az deployment group what-if for change preview and az deployment group create for deployment; PowerShell provides equivalent cmdlets with WhatIf safety.Advanced PowerShell: Parallel Execution, Modules, and Error Handling Patterns
PowerShell Az supports advanced patterns beyond simple scripts. Use ForEach-Object -Parallel (PowerShell 7+) to run Azure operations concurrently -- critical for bulk operations like starting 50 VMs simultaneously. Create custom PowerShell modules to wrap common Azure management tasks into reusable functions with proper help, parameter validation, and pipeline support. Use #Requires -Modules Az to enforce module availability. For error handling, go beyond try/catch: use trap for global error handling, -ErrorVariable to capture errors without stopping, and $PSItem for rich error inspection. Implement retry with exponential backoff using a custom function or the Microsoft.PowerShell.Utility\Restart-Computer pattern. Use ShouldProcess in advanced functions to support -WhatIf and -Confirm. For long-running operations, use Register-AzResourceProvider and wait with a polling loop. For state management, persist data to Azure Table Storage or a JSON file. Use PowerShell classes for complex state objects. Always validate parameters with ValidateSet, ValidateRange, and ValidateScript attributes. For performance, use -NoWait on Azure cmdlets and poll asynchronously.
| File | Command / Code | Purpose |
|---|---|---|
| install.sh | brew update && brew install azure-cli | Installing Azure CLI and PowerShell Az Module |
| resource-mgmt.sh | az group create --name my-rg --location eastus | Azure CLI Core Commands |
| az-module.ps1 | Connect-AzAccount | PowerShell Az Module |
| sp-auth.sh | az ad sp create-for-rbac --name my-sp --role Contributor --scopes /subscriptions... | Service Principal Authentication for Automation |
| idempotent.sh | set -euo pipefail | Scripting Patterns |
| retry.ps1 | $ErrorActionPreference = "Stop" | Error Handling and Troubleshooting |
| extensions.sh | az extension list-available --output table | Azure CLI Extensions |
| deploy-bicep.sh | set -euo pipefail | Deploying ARM and Bicep with CLI and PowerShell |
| parallel-vm.ps1 | function Start-MyVMs { | Advanced PowerShell |
Key takeaways
Interview Questions on This Topic
What is Azure CLI and how does it authenticate?
Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.
That's Azure. Mark it forged?
3 min read · try the examples if you haven't