Azure Fundamentals

Working with Azure: Portal, CLI, PowerShell & Cloud Shell

Every action you take in Azure — clicking a button in the web portal, running an az command, or executing a PowerShell cmdlet — ends up as the same API call. Once you understand that, the four tools you’ll meet in this lesson stop feeling like four separate products and start feeling like four steering wheels bolted to one engine. Pick whichever suits the moment.

In this lesson you’ll learn what the Portal, Azure CLI, Azure PowerShell, and Cloud Shell each are, when to reach for which, and the small set of skills — signing in, setting your subscription, reading JSON output — that make you fast and confident in all of them. Then you’ll prove it in a hands-on lab using only your browser: no installs, nothing to configure on your laptop.

Learning objectives

By the end of this lesson you can:

Prerequisites & where this fits

You need a Microsoft account with access to an Azure subscription (a billing-and-isolation boundary that holds your resources) — the free account from What Is Azure? Accounts, Subscriptions, Regions & Resource Groups is perfect. If “subscription” and “resource group” are new words, read that lesson first; this one assumes you know that resources live inside resource groups inside a subscription. This is Lesson 2 of the Fundamentals module of the Azure Zero-to-Hero course, and it gives you the tooling you’ll use in every lesson after it.

Four steering wheels, one engine

Azure gives you four front doors. They differ in ergonomics, not in power — almost anything you can do in one, you can do in the others.

Tool What it is Best for Trade-off
Portal The web GUI at portal.azure.com Learning, exploring, one-off changes, dashboards, reading metrics Manual; not repeatable; easy to forget what you clicked
Azure CLI (az) Cross-platform command-line tool Scripting, automation, CI/CD, day-to-day operations You must learn command names; text in, text out
Azure PowerShell (Az module) A set of PowerShell cmdlets Windows-centric shops, scripts that pass rich objects between commands Best inside PowerShell; verbose for quick one-liners
Cloud Shell A browser-based shell with az and Az pre-installed Anything, from any device, with nothing installed Needs internet; session is temporary

A useful rule of thumb: the Portal is for understanding; the CLI/PowerShell are for repeating. If you’ll do something once, click it. If you’ll do it twice — or want a teammate to do it identically — script it. The Portal even helps you make that jump: many blades have a “Download a template for automation” link that hands you the equivalent infrastructure-as-code.

They all call the same API: Azure Resource Manager

Here’s the idea that ties the whole lesson together. Azure Resource Manager (ARM) is the single control plane — the management API and engine — in front of every Azure resource. When you click Create in the Portal, the Portal sends an HTTPS request to ARM. When you run az group create, the CLI sends the same kind of request to ARM. PowerShell’s New-AzResourceGroup does too. ARM authenticates you, checks your RBAC permissions (role-based access control — what you’re allowed to do), applies any Azure Policy rules, then carries out the change and records it.

Portal, Azure CLI, Azure PowerShell, and Cloud Shell all route through Azure Resource Manager to reach your resources

The diagram shows all four tools funnelling into ARM, which then talks to the actual resource providers (Compute, Storage, Network, and so on). Three consequences fall out of this, and they matter every day:

Signing in and choosing your subscription

Before any tool can talk to ARM on your behalf, it has to know who you are (authentication) and which subscription you mean (context). In Microsoft Entra ID — Azure’s identity service, formerly Azure AD — your sign-in is what ARM checks permissions against.

With the CLI you authenticate once per session with az login. In Cloud Shell you’re already signed in, so you can usually skip it. After signing in, confirm your context:

# Who am I, and which subscription am I pointed at right now?
az account show -o table

Many people have access to more than one subscription (say, a personal sandbox and a work subscription). Commands act on whichever subscription is active, so always check before you create or delete anything:

# List every subscription you can see; the active one is marked IsDefault = True
az account list -o table

# Switch the active subscription (use the name or the subscription ID)
az account set --subscription "My Sandbox Subscription"

Forgetting to set the subscription is the single most common beginner mistake — you create a resource and then “can’t find it” because it landed in a different subscription. Make az account show a reflex.

Idempotency: why re-running is safe

Idempotency means an operation produces the same end state no matter how many times you run it. Many Azure operations are declarative: you describe the state you want, and ARM makes reality match. Run az group create --name rg-demo --location eastus once and it creates the group; run it again and ARM sees the group already exists in that state and simply reports success — it does not create a second group or throw an error.

This is what makes scripts trustworthy. A deployment that half-failed can be re-run from the top without fear of duplicates, and infrastructure-as-code tools (Bicep, ARM templates, Terraform) lean entirely on this property. Not every command is idempotent — az group delete on an already-deleted group will tell you it can’t find it, and “create a new randomly-named key” is creative by design — but the declarative create/update pattern you’ll use most is. When you write automation, prefer the idempotent path so reruns are boring.

Reading the output: JSON, tables, and --query

By default the Azure CLI returns JSON — a structured, machine-readable format. JSON is perfect for scripts but noisy for humans, so the CLI gives you two levers: -o (or --output) to change the format, and --query to filter and reshape the data using JMESPath, a small query language for JSON.

The -o formats you’ll use most:

Format When to use
-o json Default; feeding another tool, or you want every field
-o table Quick, readable scan in the terminal
-o tsv Capturing a single value into a shell variable (no quotes, no header)

--query is where the CLI gets powerful. JMESPath lets you pluck one field, select several into a tidy shape, or filter a list:

# Pull a single value (great with -o tsv to drop it straight into a variable)
SUB_ID=$(az account show --query id -o tsv)
echo "Active subscription: $SUB_ID"

# Reshape a list: pick just name + location for every resource group, as a table
az group list --query "[].{Name:name, Location:location}" -o table

# Filter: only resource groups whose location is eastus
az group list --query "[?location=='eastus'].name" -o tsv

Read those queries as: [] means “for each item in the list”, {Name:name, ...} builds a new object with the fields you want, and [?...] keeps only items matching a condition. You don’t need to memorise JMESPath today — just know it exists, because once you do, you’ll stop copying values out of JSON by hand and start letting --query do it. (Azure PowerShell achieves the same with object pipelines: Get-AzResourceGroup | Select-Object ResourceGroupName, Location.)

Hands-on lab: drive Azure from Cloud Shell

You’ll create a tagged resource group, query it with --query, then delete it — using Azure Cloud Shell, so there’s nothing to install. A resource group is just a logical container, so this whole lab is free.

1. Open Cloud Shell

Go to portal.azure.com, sign in, and click the Cloud Shell icon (>_) in the top toolbar. If it’s your first time, choose Bash when prompted. Cloud Shell may ask to create a small storage account to persist files — for this lab you can pick No storage account required (ephemeral) if offered, or accept the default; either works.

2. Confirm who and where you are

az account show -o table

Expected output (your values will differ):

Name                     CloudName    SubscriptionId                        State    IsDefault
-----------------------  -----------  ------------------------------------  -------  -----------
My Sandbox Subscription  AzureCloud   00000000-0000-0000-0000-000000000000  Enabled  True

If IsDefault isn’t the subscription you want, switch with az account set --subscription "<name>".

3. Create a tagged resource group

Set a couple of variables so the commands are easy to read and re-run:

RG="rg-tooling-lab"
LOC="eastus"

az group create \
  --name "$RG" \
  --location "$LOC" \
  --tags course=azure-zero-to-hero lesson=L2 owner=learner

Expected output (trimmed):

{
  "id": "/subscriptions/0000.../resourceGroups/rg-tooling-lab",
  "location": "eastus",
  "name": "rg-tooling-lab",
  "properties": { "provisioningState": "Succeeded" },
  "tags": { "course": "azure-zero-to-hero", "lesson": "L2", "owner": "learner" }
}

See idempotency for yourself: run the exact same az group create command again. It succeeds with the same output — no duplicate, no error.

4. Validate with --query

Confirm the group exists and read just the fields you care about:

# Is it there, and did it provision cleanly?
az group show --name "$RG" --query "{Name:name, State:properties.provisioningState, Region:location}" -o table

# Read the tags as a clean key=value list
az group show --name "$RG" --query "tags" -o json

Expected:

Name            State      Region
--------------  ---------  --------
rg-tooling-lab  Succeeded  eastus

You just used the Portal-equivalent of opening the resource group blade — but in one repeatable line. To also see it in the GUI, search for rg-tooling-lab in the Portal search bar; remember, it’s the same ARM object.

5. Cleanup

Delete the resource group. Deleting a group deletes everything inside it, so this is the one-command way to clean up a lab:

az group delete --name "$RG" --yes --no-wait

--yes skips the confirmation prompt and --no-wait returns immediately while Azure deletes in the background. Verify it’s gone (the value will flip to false):

az group exists --name "$RG"

Cost note: an empty resource group is free, and Cloud Shell’s compute is free — this lab costs nothing. (The optional Cloud Shell storage account, if you created one, costs a few rupees a month for the small file share; delete that storage account too if you won’t use Cloud Shell again.)

Common mistakes & troubleshooting

Symptom Likely cause Fix
Resource created but “missing” from the Portal Wrong active subscription az account show; if needed az account set --subscription "<name>", then recreate
(AuthorizationFailed) error Your account lacks the RBAC role for that action at that scope Ask an Owner to grant the right role; see the RBAC lesson (L3)
az: command not found (local machine) Azure CLI not installed Use Cloud Shell (nothing to install), or install the CLI locally
--query returns null or nothing JMESPath path is wrong, or list vs object mismatch Run the command with -o json first to see the real shape, then build the query
az login opens no browser / hangs (remote box) No local browser available Use az login --use-device-code and enter the code on another device
Re-running a script errors on “already exists” A non-idempotent command, or a name collision Prefer create/update commands; for globally-unique names (storage, etc.) add a random suffix

Best practices

Security notes

Quick check

  1. You need to do the same setup across three subscriptions, identically. Portal or CLI — and why?
  2. True or false: a resource group created with az group create behaves differently from one created in the Portal.
  3. Your az group create succeeded but you can’t see the group in the Portal. What’s the first thing to check?
  4. What does idempotency mean, and why does it make scripts safe to re-run?
  5. Which -o format would you use to capture a single subscription ID into a shell variable, and why?

Answers

  1. CLI (or PowerShell). It’s repeatable and identical every time, and you can loop over the three subscriptions or run the same script with a different az account set. The Portal would be three rounds of manual clicking, easy to get subtly wrong.
  2. False. Both tools call the same ARM API and produce the same resource — there’s no per-tool variant.
  3. Your active subscription (az account show). The group most likely landed in a different subscription than the one open in the Portal.
  4. Idempotency means re-running an operation lands you in the same end state — no duplicates, no errors from “already exists”. It lets you safely re-run a half-finished script from the top.
  5. -o tsv. It returns the raw value with no quotes, no JSON braces, and no header row, so it drops cleanly into VAR=$(... -o tsv).

Exercise

In Cloud Shell, create a resource group named rg-tooling-exercise in a region of your choice, tagged purpose=practice. Then, using a single az command with --query, list all of your resource groups showing only their name and location as a table. Finally, use --query to print just the tags of rg-tooling-exercise, and clean up with az group delete. Bonus: write the create command using variables for the name and location, and run it twice to confirm it’s idempotent.

Interview questions

Certification mapping

Glossary

Next steps

Now that you can drive Azure from any tool, the next lesson covers who gets to do what — identity and permissions:

AzureAzure CLICloud ShellARMJMESPath
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments

Keep Reading