Mini Azure Project – Deploy a Windows VM via Azure CLI
This mini-lab demonstrates how to deploy a Windows and a Linux Server virtual machine fully via Azure CLI, without using the Azure Portal.
It is part of my AZ-104 learning path and builds the foundation for later networking and security projects.
- Create a Resource Group
- Deploy a Windows Server VM via Azure CLI
- Automatically create NIC, NSG, Public IP
- Open RDP (3389) via CLI
- Connect to the VM via Remote Desktop
-
Azure Subscription
-
Azure CLI or Azure Cloud Shell
-
Basic understanding of regions & SKUs
az group create --name app-grp --location westeurope --output tableaz vm create \
--resource-group app-grp \
--name firstvm01 \
--image Win2022Datacenter \
--size Standard_B2s \
--admin-username username \
--admin-password 'password' \
--location westeurope \
--public-ip-sku Standard \
--output tableaz vm open-port \
--resource-group app-grp \
--name firstvm01 \
--port 3389 \
--priority 1001az vm show \
--resource-group app-grp \
--name firstvm01 \
--show-details \
--query publicIps \
-o tsvOpen the Remote Desktop client (mstsc on Windows),
enter the public IP from Step 4, and log in using:
- Username: the admin username you specified
- Password: the secure password you created
az group delete --name app-grp --yes --no-wait-
Understanding Azure regions & capacity constraints
-
Deploying VMs purely via CLI
-
Working with NSGs and inbound rules
-
Handling errors like unavailable SKUs
-
First full compute deployment without portal usage
This mini-lab shows how to resize an existing VM using the Azure CLI.
The VM was created in Section 1 and is resized within the same VM family.
az vm deallocate \
--resource-group app-grp \
--name firstvm01az vm list-vm-resize-options \
--resource-group app-grp \
--name firstvm01 \
-o tableaz vm resize \
--resource-group app-grp \
--name firstvm01 \
--size Standard_B2msaz vm start \
--resource-group app-grp \
--name firstvm01az vm show \
--resource-group app-grp \
--name firstvm01 \
--query "hardwareProfile.vmSize" \
-o tsv-
A VM must be deallocated before resizing.
-
az vm list-vm-resize-options shows only compatible SKUs for the existing VM.
-
Not every VM size can be converted to every other size (resource disk vs. non-resource disk).
-
Resizing within the same family (e.g. B1s → B2ms) is the typical real-world scenario.
This mini-lab extends the VM deployment by installing a basic IIS web server on the Windows Server VM created in Section 1. The installation is performed remotely using Azure CLI with Run Command.
az vm start \
--resource-group app-grp \
--name firstvm01az vm run-command invoke \
--resource-group app-grp \
--name firstvm01 \
--command-id RunPowerShellScript \
--scripts "Install-WindowsFeature -name Web-Server -IncludeManagementTools"az vm open-port \
--resource-group app-grp \
--name firstvm01 \
--port 80 \
--priority 1002az vm show \
--resource-group app-grp \
--name firstvm01 \
--show-details \
--query publicIps \
-o tsvOpen a browser and enter the public IP:
http://PUBLIC-IPaz group delete --name app-grp --yes --no-wait-
Installing software/workloads on VMs remotely
-
Using az vm run-command for automation
-
Opening additional NSG ports securely
-
Understanding IIS as a sample web workload
-
Seeing workload availability through public access
-
Note: Port 80 is used here only for demonstration. in production environments, HTTPS and certificates should be used.
This mini-lab demonstrates how to deploy an Ubuntu Linux virtual machine using SSH key authentication instead of a password. The VM is created via the Azure CLI and accessed securely using a locally generated SSH key pair.
ssh-keygen -t rsa -b 4096 -f ~/.ssh/azure_keyNo passphrase required for this lab. This generates: Private key: ~/.ssh/azure_key Public key: ~/.ssh/azure_key.pub
PUBLIC_KEY="$(cat ~/.ssh/azure_key.pub)"az vm create \
--resource-group app-grp \
--name linuxvm01 \
--image Ubuntu2204 \
--size Standard_B1s \
--admin-username azureuser \
--authentication-type ssh \
--ssh-key-values "$PUBLIC_KEY" \
--public-ip-sku Standard \
--output tableNote: The VM must be deployed in the same region as the Resource Group
az vm open-port \
--resource-group app-grp \
--name linuxvm01 \
--port 22 \
--priority 1003az vm show \
--resource-group app-grp \
--name linuxvm01 \
--show-details \
--query publicIps \
-o tsvssh -i ~/.ssh/azure_key azureuser@PUBLIC-IPsuccessful login confirms:
- SSH-key authentication
- Linux VM reachable
- Inbound NSG rules work
sudo sshd -T | grep passwordauthenticationExpected Output:
passwordauthentication noaz group delete --name app-grp --yes --no-wait- Generating and handling SSH keypairs
- secure authentication without passwords
- Logging into Linux VM via SSH
- Understanding NSG access requirements
- Comfort inside a Linux terminal in Azure
- Recognising default security posture in cloud images
- Cleanup Resource Group removes all dependent resources (VM, NIC, NSG, Disk, Public IP)
This mini-lab demonstrates how to attach an additional managed data disk to an existing Windows virtual machine using the Azure CLI and how to initialize and format it within the VM.
It builds directly on Section 1 (Windows VM deployment) and reinforces essential Azure compute + storage administration skills.
az disk create \
--resource-group app-grp \
--name datadisk01 \
--size-gb 16 \
--sku Standard_LRS \
--output tableaz vm disk attach \
--resource-group app-grp \
--vm-name firstvm01 \
--name datadisk01 \
--newIf successful, Azure automatically assigns a LUN (Logical Unit Number) and the disk appears as Offline / Uninitialized inside Windows.
mstsc.exeYou can just enter the public IP from Section 1 and log in with your admin credentials.
Inside the VM:
Open Disk Management → Win + X → Disk Management
Locate the new disk:
Status: Unknown
State: Offline / Not Initialized
Size: 16 GB
Right-click → Initialize Disk
Partition style: GPT
Right-click unallocated area → New Simple Volume
Quick Format
Assign drive letter (default: F:)
File System: NTFS
After this, the disk appears under This PC as a new volume.
az vm show \
--resource-group app-grp \
--name firstvm01 \
--query "storageProfile.dataDisks[*].{Name:name,Size:diskSizeGb,LUN:lun}" \
-o tableYou should see:
Name Size LUN
----------- ------ ----
datadisk01 16 0
Deleting the resource group removes:
- VM
- OS Disk
- Data Disk
- NIC
- NSG
- Public IP
- VNet
- Everything else
az group delete --name app-grp --yes --no-wait- Create and attach managed disks via Azure CLI
- Understand LUN assignment and disk presentation to the OS
- Disk initialization, partitioning and formatting (Windows Server)
- Separation of OS disk vs. temporary disk vs. data disk
- Ability to extend VM storage without redeployment
- Real-world admin scenario (very common in Azure jobs)
This mini-lab demonstrates how to create a snapshot of an Azure VM OS disk and use it to deploy a new virtual machine. This scenario is common for backup, recovery, malware isolation, or cloning a baseline VM.
az vm show \
--resource-group app-grp \
--name firstvm01 \
--query "storageProfile.osDisk.name" \
-o tsvSave this value (e.g., firstvm01_OsDisk_1_xxxxx).
az snapshot create \
--resource-group app-grp \
--name firstvm01-snap01 \
--source <OS_DISK_NAME> \
--output tableA successful snapshot appears as:
Name DiskSizeGB ProvisioningState
firstvm01-snap01 127 Succeeded
az disk create \
--resource-group app-grp \
--name restored-osdisk01 \
--source firstvm01-snap01 \
--output tableThis converts the snapshot into a bootable managed disk. The disk SKU is inherited from the snapshot source, unless it is explicitly overridden.
az vm create \
--resource-group app-grp \
--name restoredvm01 \
--attach-os-disk restored-osdisk01 \
--os-type Windows \
--public-ip-sku Standard \
--output tableAzure automatically creates new:
- NIC
- NSG
- Public IP
- VNET + Subnet (if none exist)
az vm show \
--resource-group app-grp \
--name restoredvm01 \
--query "storageProfile.osDisk" \
-o tableExample expected output:
OsType Name CreateOption DiskSizeGb
Windows restored-osdisk01 Attach 127
You can now RDP into the VM using the username/password from the original VM.
This lab creates many dependent resources. Deleting the VM does not delete the disk, NIC, NSG, or public IP.
To remove everything:
az group delete --name app-grp --yes --no-wait- Creating OS disk snapshots
- Restoring a VM from a snapshot
- Converting a snapshot → managed disk → bootable VM
- Understanding resource dependencies (NIC, NSG, Public IP, Disk)
- Typical Azure DR / forensics workflow
- Confident use of CLI for disaster-recovery operations