AZ-104: Azure Administrator — PowerShell Prep
PowerShell skills for the AZ-104 exam, organized by the official exam domains. Every command is shown with its parameters, a runnable example, and the traps the exam actually tests.
Exam facts
AZ-104 is a scenario-heavy exam. Expect roughly 40–60 questions in about 120 minutes, with a passing score of 700 out of 1000. Question formats include multiple choice, case studies, drag-and-drop, and yes/no statements. The exam tests the Az PowerShell module, not the retired AzureRM module — if you see AzureRM cmdlets in old blog posts, ignore them.
PowerShell is one tool the exam tests, not the whole exam. Many tasks are also doable in the Azure portal and Azure CLI. This track covers the PowerShell side thoroughly, but you should still know where each task lives in the portal, because some questions ask you to pick the right tool, not just the right command.
How to use this track
Work through the domains in the order below, but if you have not installed the Az module yet, start with Domain 6 first — it covers installation, sign-in, and subscription context, which every other domain assumes. Each domain section follows the same pattern: what the exam tests, a command table, runnable examples, an exercise, and the exam traps.
Suggested study order: Domain 6 (setup) → Domain 1 (governance) → Domain 4 (networking) → Domain 3 (compute) → Domain 2 (storage) → Domain 5 (monitoring). Networking before compute matters because every VM you deploy needs a virtual network, a subnet, and a network security group first.
Domain 1: Manage Microsoft Entra users and groups and governance — 20–25%
This is the highest-value domain per question. The exam tests role-based access control (RBAC) more than any other PowerShell topic: who can do what, at which scope, and how to verify it. Scope is the concept that trips up most candidates. An assignment at subscription scope applies to everything in that subscription; an assignment at resource group scope applies only to that group; an assignment at resource scope applies to one resource. The exam loves questions where the correct answer changes because the scope is wrong.
Governance also covers Azure Policy, resource locks, tags, and management groups. Policy enforces rules (for example, only certain VM sizes allowed). Locks prevent accidental deletion or modification. Tags organize resources for cost tracking and ownership. Management groups sit above subscriptions and let you apply policy and RBAC across many subscriptions at once. Know the difference: policy prevents non-compliant resources from being created, while a lock prevents an existing resource from being changed or deleted.
Exam trap — lock inheritance: Locks are inherited down the hierarchy. A ReadOnly lock on a resource group locks every resource inside it, even if those resources have no lock of their own. And a lock on a parent does not block a lock on a child — but the most restrictive lock wins. If a question says "a user cannot delete a VM even though they are Owner," check for a CanNotDelete lock on the resource group before anything else.
| Cmdlet | What it does | Key parameters |
|---|---|---|
| Get-AzRoleAssignment | Lists who holds which role, at which scope | -ObjectId, -SignInName, -Scope, -RoleDefinitionName |
New-AzRoleAssignment | Grants a role to a user, group, or service principal | -ObjectId or -SignInName, -RoleDefinitionName, -Scope |
Remove-AzRoleAssignment | Revokes a role assignment | -ObjectId, -RoleDefinitionName, -Scope |
Get-AzRoleDefinition | Lists built-in and custom role definitions | -Name (e.g. "Owner", "Contributor", "Reader") |
New-AzPolicyAssignment | Assigns an Azure Policy to a scope | -Name, -PolicyDefinition, -Scope |
Get-AzPolicyDefinition | Lists available policy definitions | -Builtin, -Custom |
New-AzResourceLock | Creates a CanNotDelete or ReadOnly lock | -LockName, -LockLevel, -ResourceGroupName, -ResourceName, -ResourceType |
New-AzManagementGroup | Creates a management group above subscriptions | -GroupName, -DisplayName, -ParentId |
New-AzTag | Applies tags to a resource or resource group | -ResourceId, -Tag (hashtable) |
# Assign Reader at resource group scope, then verify it New-AzRoleAssignment -SignInName "priya@contoso.com" -RoleDefinitionName "Reader" -ResourceGroupName "rg-web" Get-AzRoleAssignment -SignInName "priya@contoso.com" -ResourceGroupName "rg-web" | Select-Object DisplayName, RoleDefinitionName, Scope
# Protect a production resource group from deletion, then tag it
New-AzResourceLock -LockName "NoDelete" -LockLevel CanNotDelete -ResourceGroupName "rg-prod"
New-AzTag -ResourceId (Get-AzResourceGroup -Name "rg-prod").ResourceId `
-Tag @{ Environment = "Production"; Owner = "platform-team" }
Exercise: Scoped RBAC
- Create a resource group named
rg-rbac-lab. - Assign the Contributor role to a test user at that resource group scope only.
- Run
Get-AzRoleAssignmentfor that user and confirm the Scope ends atrg-rbac-lab, not at the subscription. - Remove the assignment, then try assigning Reader at subscription scope and compare the Scope value. Explain why the subscription-scope assignment is the riskier choice.
Domain 2: Implement and manage storage — 15–20%
Storage questions focus on the blob lifecycle: create an account, create a container, upload blobs, control access, and manage keys. The exam tests the difference between storage account kinds (StorageV2 is the current general-purpose kind), access tiers (Hot, Cool, Cold, Archive), and redundancy options (LRS, GRS, ZRS). Know that changing the access tier does not move data instantly for Archive — rehydration takes hours, and the exam uses that as a distractor.
Shared access signatures (SAS tokens) are the most-tested storage security topic. A SAS token grants time-limited, permission-limited access to a container or blob without sharing account keys. The exam tests which permissions a SAS token needs (read, write, list, delete) and what happens when it expires. Key rotation is the other security topic: when a key is compromised, regenerate it, and remember that applications using the old key break until they are updated.
Exam trap — storage account naming: Storage account names must be 3–24 characters, lowercase letters and numbers only, and globally unique across all of Azure. A name with uppercase letters, hyphens, or underscores fails at creation. If a question shows a storage account creation failing, check the name first — it is the most common cause and the easiest to miss.
| Cmdlet | What it does | Key parameters |
|---|---|---|
New-AzStorageAccount | Creates a storage account | -ResourceGroupName, -Name, -Location, -SkuName, -Kind |
| Get-AzStorageAccount | Lists storage accounts and their properties | -ResourceGroupName, -Name |
New-AzStorageContainer | Creates a blob container | -Name, -Context, -Permission (Off, Blob, Container) |
Set-AzStorageBlobContent | Uploads a file as a blob | -File, -Container, -Blob, -Context |
Get-AzStorageBlob | Lists blobs in a container | -Container, -Context |
New-AzStorageBlobSASToken | Creates a time-limited SAS token for a blob | -Container, -Blob, -Permission, -ExpiryTime, -Context |
Get-AzStorageAccountKey | Retrieves the account access keys | -ResourceGroupName, -Name |
New-AzStorageAccountKey | Regenerates an account key (key rotation) | -ResourceGroupName, -Name, -KeyName (key1 or key2) |
New-AzStorageShare | Creates an Azure Files share | -Name, -Context |
Set-AzStorageAccount | Updates account properties (tier, kind, access) | -ResourceGroupName, -Name, -AccessTier, -SkuName |
# Create a storage account, container, and upload a file New-AzStorageAccount -ResourceGroupName "rg-web" -Name "stwebapp001" ` -Location "East US" -SkuName "Standard_LRS" -Kind "StorageV2" $ctx = (Get-AzStorageAccount -ResourceGroupName "rg-web" -Name "stwebapp001").Context New-AzStorageContainer -Name "uploads" -Context $ctx -Permission Off Set-AzStorageBlobContent -File "C:\data\report.pdf" -Container "uploads" ` -Blob "report.pdf" -Context $ctx
# Generate a read-only SAS token valid for one hour New-AzStorageBlobSASToken -Container "uploads" -Blob "report.pdf" ` -Permission r -ExpiryTime (Get-Date).AddHours(1) -Context $ctx
Exercise: Storage with lifecycle
- Create a StorageV2 account with Standard_LRS redundancy.
- Create a container with private (Off) access and upload a file to it.
- Generate a SAS token with read-only permission and a 1-hour expiry, then use the SAS URL to download the file.
- Rotate key2 with
New-AzStorageAccountKeyand confirm the old key2 value no longer works. Explain why key rotation must be coordinated with applications.
Domain 3: Deploy and manage Azure compute resources — 20–25%
Compute is the largest hands-on domain. The exam tests the full VM lifecycle: create, start, stop, restart, resize, snapshot, and delete. It also tests managed disks, availability sets versus availability zones, Virtual Machine Scale Sets, App Service plans, and container instances. The single most important distinction in this domain is the difference between stopping a VM from inside the operating system and stopping it with PowerShell — they are not the same, and the billing consequence is the exam's favorite trap.
Disk management is the second pillar. Know the disk SKUs (Standard HDD, Standard SSD, Premium SSD, Ultra Disk) and when each fits. Know that you attach data disks with Add-AzVMDataDisk and that snapshots capture a point-in-time copy for backup or for creating new disks. For App Service, know the plan tiers (Free, Shared, Basic, Standard, Premium) and that deployment slots exist only on Standard and above — a question that asks for a staging slot on a Free plan is testing whether you know that limit.
Exam trap — stopped versus deallocated: Stop-AzVM deallocates the VM: Azure releases the hardware, stops billing for compute, and the VM loses its dynamic public IP unless it is static. Stopping from inside the OS (Start menu shutdown) only stops the OS — Azure still reserves the hardware and still bills you for compute. If a question says "a VM is stopped but still incurring compute charges," the answer is almost always that it was stopped from inside the OS, not deallocated.
| Cmdlet | What it does | Key parameters |
|---|---|---|
New-AzVM | Creates a virtual machine | -ResourceGroupName, -Name, -Location, -Image, -Size, -VirtualNetworkName, -SubnetName |
| Get-AzVM | Lists VMs; add -Status for power state | -ResourceGroupName, -Name, -Status |
Start-AzVM | Starts a stopped or deallocated VM | -ResourceGroupName, -Name |
Stop-AzVM | Stops and deallocates a VM (stops compute billing) | -ResourceGroupName, -Name, -Force |
Restart-AzVM | Restarts a running VM | -ResourceGroupName, -Name |
Remove-AzVM | Deletes a VM (disks and NICs are not deleted by default) | -ResourceGroupName, -Name, -Force |
Update-AzVM | Applies changes such as a new VM size | -ResourceGroupName, -VM (the modified VM object) |
New-AzDisk | Creates a managed disk | -ResourceGroupName, -DiskName, -Location, -DiskSizeGB, -SkuName |
| Get-AzDisk | Lists managed disks | -ResourceGroupName, -DiskName |
New-AzSnapshot | Creates a snapshot of a disk | -ResourceGroupName, -SnapshotName, -SourceUri or -SourceResourceId |
New-AzVmss | Creates a Virtual Machine Scale Set | -ResourceGroupName, -VMScaleSetName, -Location, -VirtualNetworkName, -SubnetName |
New-AzAppServicePlan | Creates an App Service plan | -ResourceGroupName, -Name, -Location, -Tier |
New-AzWebApp | Creates a web app in a plan | -ResourceGroupName, -Name, -Location, -AppServicePlan |
New-AzContainerGroup | Creates a container instance group | -ResourceGroupName, -Name, -Image, -Cpu, -MemoryInGB |
# Create a VM, then check its power state (the -Status flag is required) New-AzVM -ResourceGroupName "rg-web" -Name "web01" -Location "East US" ` -Image "Win2022Datacenter" -Size "Standard_B2s" ` -VirtualNetworkName "vnet-web" -SubnetName "subnet-web" Get-AzVM -ResourceGroupName "rg-web" -Name "web01" -Status | Select-Object Name, PowerState
# Stop (deallocate) a VM, resize it, and restart it Stop-AzVM -ResourceGroupName "rg-web" -Name "web01" -Force $vm = Get-AzVM -ResourceGroupName "rg-web" -Name "web01" $vm.HardwareProfile.VmSize = "Standard_B4ms" Update-AzVM -ResourceGroupName "rg-web" -VM $vm Start-AzVM -ResourceGroupName "rg-web" -Name "web01"
Exercise: VM lifecycle
- Deploy a VM with a public IP and confirm it is running with
Get-AzVM -Status. - Stop it with
Stop-AzVMand confirm the PowerState shows deallocated. - Resize it to a larger SKU with
Update-AzVM, then start it again. - Take a snapshot of its OS disk, then delete the VM. Check whether the disk and NIC still exist — explain why
Remove-AzVMdoes not delete them by default.
Domain 4: Implement and manage virtual networking — 20–25%
Networking questions test whether you can build a working topology: a virtual network with address space, subnets, a network security group with rules, a public IP, a network interface, and the VM that ties them together. The exam also tests DNS (Azure DNS zones and records), VNet peering, VPN Gateway, load balancers, and private endpoints. The rule that governs almost every NSG question is priority order, and the rule that governs peering questions is that peering is non-transitive.
NSG rules are evaluated by priority number, lowest first, and the first matching rule wins. Default rules exist at the bottom (priority 65000 and above) and allow VNet-to-VNet traffic while denying all other inbound traffic. A custom allow rule at priority 100 beats a custom deny rule at priority 200, even if the deny rule is listed first in the portal. Subnet changes are another trap: you modify a subnet object in memory, then you must call Set-AzVirtualNetwork to persist the change — without that call, nothing is saved.
Exam trap — NSG priority and persistence: Lower priority number wins, and evaluation stops at the first match. A deny rule at priority 4096 never fires if an allow rule at priority 100 already matched the same traffic. Separately, adding a subnet configuration to a VNet object in memory does nothing until you run Set-AzVirtualNetwork. If a question says "the subnet was added but does not appear in the portal," the missing Set-AzVirtualNetwork call is the answer.
| Cmdlet | What it does | Key parameters |
|---|---|---|
New-AzVirtualNetwork | Creates a virtual network | -ResourceGroupName, -Name, -Location, -AddressPrefix |
New-AzVirtualNetworkSubnetConfig | Defines a subnet configuration (in memory) | -Name, -AddressPrefix |
Set-AzVirtualNetwork | Persists VNet changes, including new subnets | -VirtualNetwork (the modified VNet object) |
New-AzNetworkSecurityGroup | Creates an NSG | -ResourceGroupName, -Name, -Location |
Add-AzNetworkSecurityRuleConfig | Adds a rule to an NSG (in memory) | -NetworkSecurityGroup, -Name, -Priority, -Direction, -Access, -Protocol, -SourceAddressPrefix, -DestinationPortRange |
Set-AzNetworkSecurityGroup | Persists NSG changes | -NetworkSecurityGroup |
New-AzPublicIpAddress | Allocates a public IP | -ResourceGroupName, -Name, -Location, -AllocationMethod (Static or Dynamic), -Sku |
New-AzNetworkInterface | Creates a NIC attached to a subnet | -ResourceGroupName, -Name, -Location, -SubnetId, -PublicIpAddressId |
New-AzDnsZone | Creates an Azure DNS zone | -ResourceGroupName, -Name |
Add-AzVirtualNetworkPeering | Peers two VNets (must be created from both sides) | -Name, -VirtualNetwork, -RemoteVirtualNetworkId, -AllowForwardedTraffic |
New-AzLoadBalancer | Creates a load balancer | -ResourceGroupName, -Name, -Location, -FrontendIpConfiguration, -BackendAddressPool, -LoadBalancingRule |
New-AzPrivateEndpoint | Creates a private endpoint for a PaaS service | -ResourceGroupName, -Name, -Location, -Subnet, -PrivateLinkServiceConnection |
# Build a VNet with two subnets, then persist it $vnet = New-AzVirtualNetwork -ResourceGroupName "rg-web" -Name "vnet-web" ` -Location "East US" -AddressPrefix "10.0.0.0/16" Add-AzVirtualNetworkSubnetConfig -Name "subnet-web" -AddressPrefix "10.0.1.0/24" -VirtualNetwork $vnet Add-AzVirtualNetworkSubnetConfig -Name "subnet-db" -AddressPrefix "10.0.2.0/24" -VirtualNetwork $vnet $vnet | Set-AzVirtualNetwork
# Create an NSG that allows HTTP and denies everything else inbound $nsg = New-AzNetworkSecurityGroup -ResourceGroupName "rg-web" -Name "nsg-web" -Location "East US" $nsg | Add-AzNetworkSecurityRuleConfig -Name "AllowHTTP" -Priority 100 ` -Direction Inbound -Access Allow -Protocol Tcp ` -SourceAddressPrefix "*" -SourcePortRange "*" ` -DestinationAddressPrefix "*" -DestinationPortRange 80 $nsg | Add-AzNetworkSecurityRuleConfig -Name "DenyAllInbound" -Priority 4096 ` -Direction Inbound -Access Deny -Protocol "*" ` -SourceAddressPrefix "*" -SourcePortRange "*" ` -DestinationAddressPrefix "*" -DestinationPortRange "*" $nsg | Set-AzNetworkSecurityGroup
Exercise: NSG lockdown audit
- Create an NSG with an allow rule for port 3389 from your corporate range only, and a deny-all-inbound rule at priority 4096.
- Add a second allow rule for port 3389 from 0.0.0.0/0 at priority 200. Explain which rule wins for traffic from outside the corporate range, and why.
- Remove the overly broad rule and verify the NSG only allows 3389 from the corporate range.
- Peer two VNets and confirm that a third VNet peered to only one of them cannot reach the other — proving peering is non-transitive.
Domain 5: Monitor and maintain Azure resources — 10–15%
Monitoring is the smallest domain by weight but the easiest to score points in, because the workflow is consistent: collect data into a Log Analytics workspace, set diagnostic settings on resources to send logs there, create action groups that define who gets notified, and create alert rules that fire when a metric crosses a threshold. The exam tests which piece does which job — a common distractor is confusing an action group (the notification target) with an alert rule (the condition that triggers).
Backup is the other half of this domain. Azure Backup uses Recovery Services vaults. You create a vault, enable backup protection on a VM, and the backup policy controls schedule and retention. The exam tests the difference between an on-demand backup (triggered manually) and a scheduled backup (triggered by policy), and what happens to a VM's backup data when the VM itself is deleted (the backup data remains in the vault until the vault is deleted or the backup item is explicitly removed).
Exam trap — action group versus alert rule: An action group does not detect anything. It only defines what happens when an alert fires (email, SMS, webhook, ITSM ticket). An alert rule defines the condition (for example, CPU above 80 percent for 5 minutes) and points at an action group. If a question says "no notification was sent even though CPU exceeded the threshold," check whether the alert rule exists and is enabled — the action group alone never fires.
| Cmdlet | What it does | Key parameters |
|---|---|---|
New-AzOperationalInsightsWorkspace | Creates a Log Analytics workspace | -ResourceGroupName, -Name, -Location, -Sku |
Set-AzDiagnosticSetting | Sends resource logs and metrics to a destination | -ResourceId, -WorkspaceId, -Enabled, -Category |
New-AzActionGroup | Creates a notification target (email, SMS, webhook) | -ResourceGroupName, -Name, -ShortName, -Receiver |
Add-AzMetricAlertRuleV2 | Creates a metric alert rule | -Name, -ResourceGroupName, -TargetResourceId, -Condition, -ActionGroupId |
Get-AzMetric | Queries metric values for a resource | -ResourceId, -MetricName, -TimeGrain |
New-AzRecoveryServicesVault | Creates a Recovery Services vault for backup | -ResourceGroupName, -Name, -Location |
Enable-AzRecoveryServicesBackupProtection | Enables backup on a VM or workload | -ResourceGroupName, -Name (vault), -Policy, -Item (the VM) |
Get-AzRecoveryServicesBackupJob | Checks backup job status | -VaultId, -Status |
# Create a Log Analytics workspace and send VM diagnostics to it New-AzOperationalInsightsWorkspace -ResourceGroupName "rg-web" -Name "law-web" ` -Location "East US" -Sku "PerGB2018" $vmId = (Get-AzVM -ResourceGroupName "rg-web" -Name "web01").Id $wsId = (Get-AzOperationalInsightsWorkspace -ResourceGroupName "rg-web" -Name "law-web").ResourceId Set-AzDiagnosticSetting -ResourceId $vmId -WorkspaceId $wsId -Enabled $true
# Create an action group and a CPU alert that notifies it $receiver = New-AzActionGroupReceiver -Name "OnCall" -EmailReceiver -EmailAddress "oncall@contoso.com" New-AzActionGroup -ResourceGroupName "rg-web" -Name "ag-oncall" -ShortName "oncall" -Receiver $receiver Add-AzMetricAlertRuleV2 -Name "HighCPU" -ResourceGroupName "rg-web" ` -TargetResourceId $vmId -Condition (New-AzMetricAlertRuleV2Criteria -MetricName "Percentage CPU" -TimeAggregation Average -Operator GreaterThan -Threshold 80) ` -ActionGroupId (Get-AzActionGroup -ResourceGroupName "rg-web" -Name "ag-oncall").Id
Exercise: Backup enablement
- Create a Recovery Services vault in the same region as your VM.
- Enable backup protection on the VM with the default policy.
- Trigger an on-demand backup and check its job status with
Get-AzRecoveryServicesBackupJob. - Explain what happens to the backup data if you delete the VM but keep the vault.
Domain 6: Setup and context — Az module, subscriptions, and resource groups
Every other domain assumes this foundation, so learn it first even though it is listed last. Install the Az module from the PowerShell Gallery, sign in with Connect-AzAccount, and confirm which subscription and tenant you are operating in before running any command that creates or modifies resources. Most "I created a resource but cannot find it" problems are subscription-context problems: the resource went to a different subscription than the one showing in the portal.
Contexts are how PowerShell tracks which subscription you are working in. Get-AzContext shows the current context; Set-AzContext switches it. When you work with multiple subscriptions, save contexts with Save-AzContext so you can switch back without signing in again. Resource groups are the deployment and lifecycle boundary: deleting a resource group deletes everything in it, which is both the fastest cleanup tool and the most dangerous command in this track.
Exam trap — AzureRM versus Az: The AzureRM module was retired. The exam expects Az cmdlets, and any question mentioning AzureRM is either historical or a distractor. If a script uses Login-AzureRmAccount or New-AzureRmResourceGroup, it will not run on a current system. The Az equivalents are Connect-AzAccount and New-AzResourceGroup. Also note that Get-AzVM without -Status does not show power state — the exam tests that flag explicitly.
| Cmdlet | What it does | Key parameters |
|---|---|---|
Install-Module Az | Installs the Az module from the PowerShell Gallery | -Scope (CurrentUser or AllUsers), -Repository, -AllowClobber |
Update-Module Az | Updates the Az module to the latest version | -Scope |
| Connect-AzAccount | Signs in to Azure (interactive, device code, or service principal) | -TenantId, -SubscriptionId, -ServicePrincipal, -Credential |
| Get-AzContext | Shows the current subscription and tenant context | -ListAvailable (to see all contexts) |
| Set-AzContext | Switches to a different subscription context | -SubscriptionId or -SubscriptionName |
| Get-AzSubscription | Lists subscriptions you can access | -SubscriptionId, -TenantId |
Select-AzSubscription | Sets the active subscription (alias-style context switch) | -SubscriptionId or -SubscriptionName |
Save-AzContext | Saves the current context to a file for reuse | -Path |
New-AzResourceGroup | Creates a resource group | -Name, -Location, -Tag |
| Get-AzResourceGroup | Lists resource groups | -Name, -Location, -Tag |
| Get-AzResource | Lists resources, optionally filtered by group or type | -ResourceGroupName, -ResourceType, -TagName |
# Install the Az module, sign in, and confirm your context Install-Module Az -Scope CurrentUser -Repository PSGallery -Force Connect-AzAccount Get-AzContext | Select-Object Name, Account, Tenant
# Switch subscriptions, create a resource group, and verify it
Get-AzSubscription | Select-Object Name, Id, State
Select-AzSubscription -SubscriptionName "Visual Studio Enterprise"
New-AzResourceGroup -Name "rg-web" -Location "East US" -Tag @{ Project = "AZ104Lab" }
Get-AzResourceGroup -Name "rg-web" | Select-Object ResourceGroupName, Location, Tags
Exercise: End-to-end lab — deploy a 2-tier web app
This single scenario exercises four domains at once and is the closest thing on this page to an exam simulation.
- Create a resource group
rg-2tierin East US. - Build a VNet
vnet-2tier(10.1.0.0/16) with two subnets:subnet-web(10.1.1.0/24) andsubnet-db(10.1.2.0/24). Persist withSet-AzVirtualNetwork. - Create an NSG that allows HTTP (80) and HTTPS (443) inbound, denies all other inbound traffic, and associate it with
subnet-web. - Deploy a VM into
subnet-webwith a public IP, then confirm its power state withGet-AzVM -Status. - Create a StorageV2 account and a container, upload a file, and generate a read-only SAS token for it.
- Assign Reader at the
rg-2tierscope to a test user and verify withGet-AzRoleAssignment. - Clean up by removing the resource group — and confirm that the VNet, VM, storage account, and role assignment scope all disappear with it.
Exam tips
Read every question twice and underline the scope, the SKU, and the verb. AZ-104 questions are precise: "at the resource group scope" versus "at the subscription scope" changes the answer, "Standard_B2s" versus "Standard_D2s_v3" changes the answer, and "create" versus "list" changes the cmdlet entirely. When two answers look similar, the one that matches the stated scope and the stated permission level is usually correct.
For scenario questions, work backwards from the constraint. If the scenario says "minimize cost," the answer involves deallocation, a lower tier, or LRS redundancy. If it says "minimize downtime," the answer involves availability zones, scale sets, or a load balancer. If it says "least privilege," the answer is the narrowest role at the narrowest scope — Reader at resource group scope beats Contributor at subscription scope every time.
Time management matters. Flag case studies and come back to them after the short questions. A single case study can eat ten minutes if you let it, and the short questions are worth the same marks. If you finish early, use the remaining time to re-check questions where you hesitated between two cmdlets — those are the ones where a second read catches a scope or parameter mistake.
Commands quick reference
All cmdlets on this page, grouped by domain, for night-before revision.
| Domain | Cmdlets |
|---|---|
| Governance | Get-AzRoleAssignment, New-AzRoleAssignment, Remove-AzRoleAssignment, Get-AzRoleDefinition, New-AzPolicyAssignment, Get-AzPolicyDefinition, New-AzResourceLock, New-AzManagementGroup, New-AzTag |
| Storage | New-AzStorageAccount, Get-AzStorageAccount, New-AzStorageContainer, Set-AzStorageBlobContent, Get-AzStorageBlob, New-AzStorageBlobSASToken, Get-AzStorageAccountKey, New-AzStorageAccountKey, New-AzStorageShare, Set-AzStorageAccount |
| Compute | New-AzVM, Get-AzVM, Start-AzVM, Stop-AzVM, Restart-AzVM, Remove-AzVM, Update-AzVM, New-AzDisk, Get-AzDisk, New-AzSnapshot, New-AzVmss, New-AzAppServicePlan, New-AzWebApp, New-AzContainerGroup |
| Networking | New-AzVirtualNetwork, New-AzVirtualNetworkSubnetConfig, Set-AzVirtualNetwork, New-AzNetworkSecurityGroup, Add-AzNetworkSecurityRuleConfig, Set-AzNetworkSecurityGroup, New-AzPublicIpAddress, New-AzNetworkInterface, New-AzDnsZone, Add-AzVirtualNetworkPeering, New-AzLoadBalancer, New-AzPrivateEndpoint |
| Monitoring | New-AzOperationalInsightsWorkspace, Set-AzDiagnosticSetting, New-AzActionGroup, Add-AzMetricAlertRuleV2, Get-AzMetric, New-AzRecoveryServicesVault, Enable-AzRecoveryServicesBackupProtection, Get-AzRecoveryServicesBackupJob |
| Setup | Install-Module Az, Update-Module Az, Connect-AzAccount, Get-AzContext, Set-AzContext, Get-AzSubscription, Select-AzSubscription, Save-AzContext, New-AzResourceGroup, Get-AzResourceGroup, Get-AzResource |
Keep going
After this track, work through the Azure PowerShell track for deeper hands-on lessons, and the Entra PowerShell track for identity topics that overlap with Domain 1. Each command page linked above has its own examples and exercises — use them to drill the cmdlets you are weakest on before booking the exam.