12.1 Azure PowerShell, Azure CLI, and Deployment Monitoring

Key Takeaways

  • The Az.Sql module cmdlets (New-AzSqlServer, New-AzSqlDatabase, Set-AzSqlDatabase, New-AzSqlElasticPool) provision and manage Azure SQL; Azure CLI mirrors them with az sql server create, az sql db create, and az sql db update
  • Choose Azure PowerShell for Windows/PowerShell ecosystems and rich object pipelines; choose Azure CLI for cross-platform Bash, Linux CI runners, or Cloud Shell one-liners
  • Connect-AzAccount and az login support interactive, service-principal, and managed-identity auth; service principals fit headless CI/CD, managed identities fit Azure-hosted runbooks
  • Deployment failures are diagnosed through Get-AzDeployment or az deployment group show plus activity-log and deployment operations filtered by correlationId; common causes are quota, names, region/SKU, NSG, and locks
  • Use -Force to suppress confirmation prompts in scripts, wrap cmdlets in try/catch, and use -AsJob for long-running deployments so the script can poll rather than block
Last updated: August 2026

Why PowerShell and CLI Matter for DP-300

Domain 4 of the DP-300 exam ("Configure and manage automation of tasks", weighted 15-20%) explicitly tests your ability to automate deployment by using Azure PowerShell and automate deployment by using Azure CLI, and to monitor and troubleshoot deployments. You will not be asked to memorize every flag, but you must recognize the right cmdlet or command for a scenario, know how to authenticate a script non-interactively, and know where to look when a deployment fails. Treat this section as the scripting vocabulary you need to read and write infrastructure-as-code for Azure SQL.

The Az.Sql Module: Core Cmdlets

Azure PowerShell organizes SQL management in the Az.Sql module. The verbs follow PowerShell's standard verb-noun convention, so once you internalize a handful of verbs you can predict most cmdlets. The table below covers the ones the exam draws from:

CmdletPurposeCommon parameters
New-AzSqlServerCreate a logical server-ResourceGroupName, -ServerName, -Location, -SqlAdministratorCredentials
New-AzSqlDatabaseCreate a database on a server-ServerName, -DatabaseName, -RequestedServiceObjectiveName / -Edition / -VCore
Get-AzSqlDatabaseRetrieve a database object-ServerName, -DatabaseName, -ResourceGroupName
Set-AzSqlDatabaseModify a database (scale tier, rename, move pool)-DatabaseName, -Edition, -VCore, -ElasticPoolName
New-AzSqlElasticPoolCreate an elastic pool-ElasticPoolName, -Edition, -Dtu / -VCore
Set-AzSqlElasticPoolResize an elastic pool-VCore, -DatabaseDtuMin, -DatabaseDtuMax
New-AzSqlDatabaseCopyCreate a geo-secondary or copy-CopyResourceGroupName, -PartnerServerName
Get-AzSqlDatabaseActivityWatch an async database operation-DatabaseName, -State

Two operational facts are worth highlighting. First, New-AzSqlServer requires credentials for the server admin in PSCredential form (a username plus a strongly typed SecureString password), so the usual pattern is $cred = Get-Credential interactively or constructed from a stored secret in automation. Second, scaling a database is a Set-AzSqlDatabase call with the new service objective - it is an online operation that ends in a brief connection drop, exactly as covered in Chapter 3.

Azure CLI: az sql Commands

The Azure CLI exposes the same operations through the az sql command group, which is cross-platform (Windows, macOS, Linux) and especially at home in Bash and CI pipelines. The core commands:

CommandPurpose
az sql server create --name --resource-group --location --admin-user --admin-passwordCreate a logical server
az sql server show / list / updateRetrieve or modify a server
az sql db create --server --name --resource-group --service-objectiveCreate a database at a given SKU
az sql db show / list / updateInspect or modify a database
az sql db update --service-objective GP_Gen5_8Scale a database
az sql elastic-pool create / updateCreate or resize an elastic pool
az sql server firewall-rule create / updateManage server-level firewall rules

Service objective names (GP_Gen5_8, BC_Gen5_16, HS_Gen5_2, S3, P1) are the same string vocabulary the cmdlets and T-SQL ALTER DATABASE accept. A typical one-liner:

az sql db create \
  --resource-group rg-sql --server sql-prod \
  --name SalesDB --service-objective GP_Gen5_4

PowerShell vs CLI: Selection Criteria

The exam will present scenarios that lean toward one tool. Use this decision table:

CriterionPick PowerShellPick CLI
Existing Windows / PowerShell ecosystem, staff skillYes
Object pipeline, rich .NET objects in variablesYes
Linux/macOS developers, Bash heredocs, jqYes
Cross-platform CI runners (GitHub Actions on ubuntu-latest)Yes
Cloud Shell one-liners you can paste from docsEitherEither
DSC, Azure Policy guest config integrationsYes

Both tools are first-class and idempotent when you add -Force (PowerShell) or run create commands that return the existing resource if it already exists. Neither is deprecated; the exam does not penalize choosing either, only choosing the wrong authentication or the wrong cmdlet for a scenario.

Test Your Knowledge

A team runs their deployment pipeline on GitHub Actions hosted ubuntu-latest runners and wants to provision an Azure SQL logical server and database in Bash. Which approach best fits the runner and ecosystem?

A
B
C
D

Authentication: Service Principals and Managed Identities

Both tools authenticate through Microsoft Entra ID (formerly Azure AD). Interactive Connect-AzAccount and az login are fine for a human at a workstation, but automation needs a non-interactive identity:

  • Service principal: an Entra app registration with a client ID and either a client secret or a certificate. Authenticate with Connect-AzAccount -ServicePrincipal -Credential $sp -TenantId $tenant (PowerShell) or az login --service-principal -u $appId -p $secret --tenant $tenant (CLI). Grant it the minimum RBAC role needed - typically SQL Server Contributor (or a custom role) on the resource group. Service principals are the right answer for CI/CD pipelines running outside Azure.
  • Managed identity: a system-assigned or user-assigned identity tied to an Azure resource (Automation account, VM, App Service, Function). No secret to rotate; the platform issues short-lived tokens. Authenticate with Connect-AzAccount -Identity or az login --identity. Managed identities are the right answer when the script itself runs inside Azure.

A common exam trap: storing the service principal secret in plaintext inside a runbook or pipeline variable. The correct pattern is to store it in Azure Key Vault (or a CI secret store) and retrieve it at runtime, or to eliminate the secret entirely by using a managed identity.

Scripting Patterns: Loops, Error Handling, Async

Production automation must be idempotent and observable. Three patterns show up repeatedly:

  1. Wrap cmdlets in try/catch so a failed resource creation does not silently continue. Azure PowerShell throws terminating errors you can catch; Azure CLI returns a non-zero exit code you can test with $? or if ! az ... in Bash.
  2. Use -Force to suppress confirmation prompts (-Force on New-AzSqlServer, Remove-AzSqlDatabase, etc.) so scripts do not hang waiting for a human.
  3. Use -AsJob / Start-Job for long-running deployments. New-AzSqlDatabase -AsJob returns a job object you poll with Get-Job | Wait-Job so the script can proceed, log progress, or parallelize. The CLI equivalent is appending & in Bash or using --no-wait on supported commands.

A typical idempotent provisioning loop that creates several tenant databases from an array:

$tenants = 'northwind','contoso','fabrikam'
foreach ($t in $tenants) {
  try {
    New-AzSqlDatabase -ResourceGroupName rg-sql -ServerName sql-prod `
      -DatabaseName \"db-$t\" -Edition GeneralPurpose -VCore 2 -Force -ErrorAction Stop
    Write-Output \"Provisioned db-$t\"
  } catch {
    Write-Warning \"Failed to provision db-$t: $($_.Exception.Message)\"
  }
}

Notice -Force (no prompt), -ErrorAction Stop (so the catch fires), and the loop-friendly structure. The CLI equivalent uses a Bash for-loop and relies on the shell exit code.

Monitoring and Troubleshooting Deployments

Once you kick off a deployment, you need to watch it. Azure Resource Manager (ARM) records every deployment at three levels: subscription, resource group, and (for some resources) resource. The key inspection commands:

  • Get-AzDeployment -ResourceGroupName rg-sql lists deployments in a resource group; Get-AzDeployment -Name <deployment> -ResourceGroupName rg-sql returns one deployment's details.
  • az deployment group show -g rg-sql -n <deployment> is the CLI equivalent; az deployment operation group list -g rg-sql -n <deployment> lists the deployment operations - the individual resource-level steps inside that deployment.
  • The Activity Log (Portal: Monitor > Activity log, or Get-AzActivityLog, az monitor activity-log list) shows every control-plane write operation across the subscription and is the place to look for operations that never produced a deployment record at all.

Every deployment carries a correlationId. Filtering the activity log by that correlationId returns every operation that belonged to the same deployment - invaluable when a deployment created five resources, three succeeded, and two failed and you need to see them together.

The most common deployment failures and their signatures:

SymptomLikely root causeFix
Resource type 'Microsoft.Sql/servers' is not available in location <x>Unsupported region for the resource/SKUPick a supported region or SKU
Sql server name 'sql-prod' is already takenGlobally unique name collisionUse a unique suffix (random, hash, or prefix)
The subscription has reached its quota for total server capacityRegional quota exhaustedRequest a quota increase or clean up unused servers
Cannot create server because subnet is not delegated / NSG blocksNetwork/NSG/subnet misconfigurationAdd Microsoft.Sql delegation, open NSG rules
Cannot perform operation because resource is lockedResource lock (CanNotDelete / ReadOnly)Remove or scope the lock before the operation
The client has authorization to perform action but the scope is invalidRBAC role not scoped to the resourceRe-scope the service principal role assignment

A troubleshooting workflow to internalize: (1) read the error message from the cmdlet/CLI output - it is specific; (2) az deployment operation group list or Get-AzDeploymentOperation to see which step failed; (3) if the deployment says "Accepted" but the resource never appears, filter the activity log by correlationId for the operation's status; (4) check for resource locks, NSG rules, and quota via the portal or az resource list --query. The exam pattern: a scenario describes a deployment that partially succeeded, and the correct answer is to inspect deployment operations (not just the deployment's overall status) to find the failing step.

Test Your Knowledge

An ARM template deployment in a CI pipeline reported overall success, but one of three databases the template was supposed to create is missing from the resource group. What is the most direct way to identify which step failed and why?

A
B
C
D