Home DevOps Microsoft Azure — Azure CLI & PowerShell
Beginner 3 min · July 12, 2026

Microsoft Azure — Azure CLI & PowerShell

Master Azure CLI and PowerShell for managing Azure resources.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 18, 2026
last updated
2,466
articles · all by Naren
Before you start⏱ 20 min
  • An Azure subscription (free tier works)
  • Basic command-line knowledge
  • Azure CLI installed or Cloud Shell access
✦ Definition~90s read
What is Azure CLI & PowerShell?

Azure CLI is a cross-platform command-line tool (Python-based) for managing Azure resources via bash/cmd/PowerShell. The Azure PowerShell Az module provides over 2,000 cmdlets for managing Azure through PowerShell scripting and desred state configuration.

Azure CLI and PowerShell are like remote controls for your Azure cloud.
Plain-English First

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.

install.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Install Azure CLI on macOS
brew update && brew install azure-cli

# Authenticate
az login

# Show current subscription
az account show

# Install PowerShell Az module
Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force
Output
[
{
"cloudName": "AzureCloud",
"id": "subscription-id",
"state": "Enabled"
}
]
🔥Use Cloud Shell for Quick Start
Azure Cloud Shell (portal.azure.com) has both Azure CLI and PowerShell Az pre-installed with free storage. Use it for quick scripts without local setup.
🎯 Key Takeaway
Azure CLI and PowerShell Az are complementary tools — use CLI for quick commands and scripting, PowerShell for complex automation and integration with existing Windows workflows.
azure-cli-powershell THECODEFORGE.IO Azure CLI & PowerShell Installation Flow Step-by-step process to install and configure Azure CLI and PowerShell Az module Install Azure CLI Run installer for Windows, macOS, or Linux Install PowerShell Az Module Execute Install-Module -Name Az -Force Authenticate to Azure Use az login or Connect-AzAccount Create Resource Group az group create or New-AzResourceGroup Deploy Resources Use az deployment group create or New-AzResourceGroupDeployment Verify and Clean Up Check resources and remove with az group delete or Remove-AzResourceGroup ⚠ Missing module dependencies can cause failures Always run Install-Module Az -Force in an elevated session THECODEFORGE.IO
thecodeforge.io
Azure Cli Powershell

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 [parameters]'. Use '--output table' for human-readable output, '--output json' for scripting. The '--query' parameter uses JMESPath for filtering.

resource-mgmt.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Create a resource group
az group create --name my-rg --location eastus

# Create a VM with default settings
az vm create --resource-group my-rg --name my-vm --image UbuntuLTS --generate-ssh-keys

# List all VMs in table format
az vm list --output table

# Query specific fields
az vm list --query "[].{Name:name, Location:location, Size:hardwareProfile.vmSize}" --output table
Output
Name Location Size
------ ---------- ----------
my-vm eastus Standard_DS1_v2

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.

az-module.ps1POWERSHELL
1
2
3
4
5
6
7
8
9
10
11
12
# Authenticate and set subscription
Connect-AzAccount
Set-AzContext -SubscriptionId "your-sub-id"

# Create a resource group
New-AzResourceGroup -Name "my-rg" -Location "eastus"

# Get all VMs in a resource group
Get-AzVM -ResourceGroupName "my-rg" | Format-Table Name, Location, VmSize

# Remove a resource (with confirmation)
Remove-AzResourceGroup -Name "my-rg" -Force -AsJob
Output
Name Location VmSize
---- -------- ------
my-vm eastus Standard_DS1_v2
azure-cli-powershell THECODEFORGE.IO Azure CLI & PowerShell Tool Stack Layered architecture of Azure management tools and authentication User Interface Command Line | PowerShell Console | Scripts Tooling Layer Azure CLI | PowerShell Az Module Authentication Service Principal | Managed Identity | User Login Azure Resource Manager REST API | Resource Providers | Deployments Azure Services Compute | Storage | Networking THECODEFORGE.IO
thecodeforge.io
Azure Cli Powershell

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.

sp-auth.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Create a service principal with Contributor role
az ad sp create-for-rbac --name my-sp --role Contributor --scopes /subscriptions/your-sub-id

# Output:
{
  "appId": "client-id",
  "displayName": "my-sp",
  "password": "client-secret",
  "tenant": "tenant-id"
}

# Login with service principal (non-interactive)
az login --service-principal -u client-id -p client-secret --tenant tenant-id

# For PowerShell:
$sp = New-AzADServicePrincipal -DisplayName "my-sp" -Role Contributor
$sp.PasswordCredentials.SecretText | ConvertFrom-SecureString
Output
[
{
"cloudName": "AzureCloud",
"id": "sub-id",
"isDefault": true
}
]

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.

idempotent.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
set -euo pipefail

RG_NAME="my-rg"
LOCATION="eastus"

# Check and create resource group if needed
if ! az group exists --name "$RG_NAME"; then
    az group create --name "$RG_NAME" --location "$LOCATION" --only-show-errors
fi

# Conditional VM creation
VM_EXISTS=$(az vm list --resource-group "$RG_NAME" --query "[?name=='my-vm'] | length(@)" --output tsv)
if [ "$VM_EXISTS" -eq 0 ]; then
    az vm create --resource-group "$RG_NAME" --name my-vm \
        --image UbuntuLTS --generate-ssh-keys --no-wait
fi
⚠ Always Use --output tsv for Scripting
Default JSON output contains metadata that breaks bash scripts. Use --output tsv (tab-separated) or --query with JMESPath for machine-parseable output.

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.

retry.ps1POWERSHELL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ErrorActionPreference = "Stop"
$maxRetries = 3
$retryDelay = 10 # seconds

for ($i = 0; $i -lt $maxRetries; $i++) {
    try {
        New-AzResourceGroup -Name "my-rg" -Location "eastus" -ErrorAction Stop
        Write-Host "Resource group created successfully"
        break
    }
    catch {
        if ($i -eq $maxRetries - 1) {
            throw "Failed after $maxRetries attempts: $_"
        }
        Write-Warning "Attempt $($i+1) failed. Retrying in ${retryDelay}s..."
        Start-Sleep -Seconds $retryDelay
    }
}
Output
Resource group created successfully

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.

🔥Hybrid Approach
You can mix both: use CLI commands inside PowerShell with 'az' command, or call PowerShell from bash. Both authenticate through the same Azure AD tenant.
🎯 Key Takeaway
Choose Azure CLI for simplicity and cross-platform scripting. Choose PowerShell Az for deep integration, complex error handling, and Windows-centric environments.

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.

extensions.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# List available extensions
az extension list-available --output table

# Install Azure DevOps extension
az extension add --name azure-devops --allow-preview false

# Configure Azure DevOps CLI
az devops configure --defaults organization=https://dev.azure.com/myorg project=MyProject

# Use it: list pipelines
az pipelines list --output table

# Update an extension
az extension update --name azure-devops

# List installed
az extension list --query "[].{Name:name, Version:version}" --output table
Output
Name Version
--------------- ---------
azure-devops 0.26.0
resource-graph 2.1.0
Pipeline ID Name Status
----------- -------------- --------
42 my-app-ci succeeded
🔥Extension Lifecycle
Preview commands often start as extensions before moving to the base CLI. When commands graduate, uninstall the old extension to avoid conflicts. Check az extension list-available --show-details for version info.
🎯 Key Takeaway
Use CLI extensions for preview and specialized commands; enable dynamic install for productivity, but pin versions for production scripts.

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.

deploy-bicep.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash
set -euo pipefail

# What-if preview
az deployment group what-if \
  --resource-group my-rg \
  --template-file main.bicep \
  --parameters env=prod sku=Standard_GRS

# Deploy
az deployment group create \
  --resource-group my-rg \
  --template-file main.bicep \
  --parameters env=prod sku=Standard_GRS

# Get output
storageEndpoint=$(az deployment group show \
  --resource-group my-rg \
  --name main \
  --query properties.outputs.storageEndpoint.value \
  --output tsv)
echo "Storage endpoint: $storageEndpoint"
Output
{
"properties": {
"provisioningState": "Succeeded",
"outputs": {
"storageEndpoint": "https://mystorage.blob.core.windows.net/"
}
}
}
Storage endpoint: https://mystorage.blob.core.windows.net/
💡What-If Is Mandatory
Always run 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.
🎯 Key Takeaway
Use az deployment group what-if for change preview and az deployment group create for deployment; PowerShell provides equivalent cmdlets with WhatIf safety.
Azure CLI vs PowerShell Az Module Key differences for resource management and automation Azure CLI PowerShell Az Module Syntax Style az group create --name myRG New-AzResourceGroup -Name myRG Output Format JSON by default, supports table/tsv PowerShell objects with properties Scripting Integration Best for bash/zsh and cross-platform Native to PowerShell, supports .NET Idempotent Operations Use --no-wait and az resource tag Use -ErrorAction Stop and try/catch Error Handling Exit codes and stderr messages PowerShell exceptions and $Error variabl Use Case Quick ad-hoc queries and automation Complex scripts and DSC configurations THECODEFORGE.IO
thecodeforge.io
Azure Cli Powershell

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.

parallel-vm.ps1POWERSHELL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#Requires -Modules Az.Compute, Az.Resources

function Start-MyVMs {
    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string[]]$VMName,
        [string]$ResourceGroupName = "rg-prod"
    )
    process {
        if ($PSCmdlet.ShouldProcess($VMName, "Start VM")) {
            $VMName | ForEach-Object -Parallel {
                $vm = $_
                Write-Output "Starting $vm..."
                Start-AzVM -Name $vm -ResourceGroupName $using:ResourceGroupName -NoWait
            } -ThrottleLimit 10
        }
    }
}

"web-01", "web-02", "web-03" | Start-MyVMs -WhatIf
Output
What if: Starting VM 'web-01'
What if: Starting VM 'web-02'
What if: Starting VM 'web-03'
⚠ Throttling in Parallel Operations
Azure API has rate limits (1200 writes/hour per subscription). Use -ThrottleLimit to control concurrency. For bulk operations (>100 resources), add retry logic with exponential backoff.
🎯 Key Takeaway
Use ForEach-Object -Parallel for bulk operations, custom modules for reusable automation, and ShouldProcess for safe destructive operations.
⚙ Quick Reference
9 commands from this guide
FileCommand / CodePurpose
install.shbrew update && brew install azure-cliInstalling Azure CLI and PowerShell Az Module
resource-mgmt.shaz group create --name my-rg --location eastusAzure CLI Core Commands
az-module.ps1Connect-AzAccountPowerShell Az Module
sp-auth.shaz ad sp create-for-rbac --name my-sp --role Contributor --scopes /subscriptions...Service Principal Authentication for Automation
idempotent.shset -euo pipefailScripting Patterns
retry.ps1$ErrorActionPreference = "Stop"Error Handling and Troubleshooting
extensions.shaz extension list-available --output tableAzure CLI Extensions
deploy-bicep.shset -euo pipefailDeploying ARM and Bicep with CLI and PowerShell
parallel-vm.ps1function Start-MyVMs {Advanced PowerShell

Key takeaways

1
Azure CLI and PowerShell Az are essential tools for Azure automation
2
Service principals enable secure CI/CD integration without user credentials
3
Idempotent scripts check before creating
avoid duplicate resource errors
4
Choose the right tool
CLI for simplicity, PowerShell for complex automation
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is Azure CLI and how does it authenticate?
Q02JUNIOR
Explain the difference between Azure CLI and PowerShell Az.
Q03JUNIOR
How do you handle errors in Azure automation scripts?
Q04JUNIOR
What is a service principal and why use it?
Q01 of 04JUNIOR

What is Azure CLI and how does it authenticate?

ANSWER
Azure CLI is a cross-platform command-line tool for managing Azure resources. It authenticates via Azure AD using interactive login, device code, or service principal credentials.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
Does Azure CLI work on macOS?
02
Can I use Azure CLI without installing it?
03
How do I switch between subscriptions in Azure CLI?
04
Is Azure CLI free?
05
What's the difference between AzureRM and Az modules?
06
How do I pass output from one CLI command to another?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 18, 2026
last updated
2,466
articles · all by Naren
🔥

That's Azure. Mark it forged?

3 min read · try the examples if you haven't

Previous
Azure Container Registry (ACR)
45 / 55 · Azure
Next
ARM Templates & Bicep