Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124

If you’ve ever logged into the Azure portal and clicked through the steps to create a virtual machine (VM), you know it works… but it can be slow and repetitive. Now imagine doing that for 10, 50, or even 100 VMs. That’s where PowerShell automation saves the day.
In this post, we’ll walk through how to create and configure an Azure VM using PowerShell, step by step. By the end, you’ll have a working VM deployed in your Azure subscription — all from your terminal.
Manual deployments in the Azure Portal are fine for quick experiments, but automation gives you:
Automation = fewer mistakes, less time wasted, and a lot more control.
Before we jump into the script, make sure you have:
Install-Module -Name Az -AllowClobber -Force
Logged into your account:
Connect-AzAccount
Every VM lives inside a resource group. Let’s create one:
New-AzResourceGroup -Name MyResourceGroup -Location eastus
This will create a container to hold all the resources we’ll build (VM, network, disks, etc.).
A VM needs a virtual network (VNet), a subnet, and a public IP. Let’s create them with a few commands:
# Create VNet
$subnetConfig = New-AzVirtualNetworkSubnetConfig -Name "mySubnet" -AddressPrefix "10.0.0.0/24"
$vnet = New-AzVirtualNetwork -ResourceGroupName MyResourceGroup -Location eastus `
-Name "myVNet" -AddressPrefix "10.0.0.0/16" -Subnet $subnetConfig
# Public IP
$pip = New-AzPublicIpAddress -ResourceGroupName MyResourceGroup -Location eastus `
-Name "myPublicIP" -AllocationMethod Dynamic
# Network Security Group (firewall rules)
$nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name "Allow-RDP" -Protocol Tcp -Direction Inbound `
-Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
-DestinationPortRange 3389 -Access Allow
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName MyResourceGroup -Location eastus `
-Name "myNSG" -SecurityRules $nsgRuleRDP
# NIC
$nic = New-AzNetworkInterface -ResourceGroupName MyResourceGroup -Location eastus `
-Name "myNic" -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id
This script creates a secure network for your VM with RDP (Remote Desktop) access enabled.
Now let’s configure the VM itself.
# VM credentials
$cred = Get-Credential -Message "Enter username and password for the VM"
# VM config
$vmConfig = New-AzVMConfig -VMName "myVM" -VMSize "Standard_B1s" |
Set-AzVMOperatingSystem -Windows -ComputerName "myVM" -Credential $cred -ProvisionVMAgent -EnableAutoUpdate |
Set-AzVMSourceImage -PublisherName "MicrosoftWindowsServer" -Offer "WindowsServer" `
-Skus "2019-Datacenter" -Version "latest" |
Add-AzVMNetworkInterface -Id $nic.Id
Here, we’re setting:
Standard_B1s = small, cost-effective)Finally, let’s deploy the VM:
New-AzVM -ResourceGroupName MyResourceGroup -Location eastus -VM $vmConfig
That’s it! In a few minutes, your VM will be up and running in Azure.
Head over to the Azure Portal → Resource Groups → MyResourceGroup. You should see:
You can now connect to your VM via Remote Desktop using the public IP and the credentials you provided earlier.
We’ve already seen how to automate a Windows VM deployment with PowerShell. But what if you want a Linux VM (for hosting apps, containers, or web servers)? The good news: the process is almost the same — except we’ll use SSH keys instead of passwords.
New-AzResourceGroup -Name LinuxRG -Location eastus
# Subnet & VNet
$subnetConfig = New-AzVirtualNetworkSubnetConfig -Name "linuxSubnet" -AddressPrefix "10.1.0.0/24"
$vnet = New-AzVirtualNetwork -ResourceGroupName LinuxRG -Location eastus `
-Name "linuxVNet" -AddressPrefix "10.1.0.0/16" -Subnet $subnetConfig
# Public IP
$pip = New-AzPublicIpAddress -ResourceGroupName LinuxRG -Location eastus `
-Name "linuxPublicIP" -AllocationMethod Dynamic
# Network Security Group (allow SSH)
$nsgRuleSSH = New-AzNetworkSecurityRuleConfig -Name "Allow-SSH" -Protocol Tcp -Direction Inbound `
-Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
-DestinationPortRange 22 -Access Allow
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName LinuxRG -Location eastus `
-Name "linuxNSG" -SecurityRules $nsgRuleSSH
# NIC
$nic = New-AzNetworkInterface -ResourceGroupName LinuxRG -Location eastus `
-Name "linuxNic" -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id
If you don’t already have SSH keys, generate them locally:
ssh-keygen -t rsa -b 2048
This creates id_rsa (private key) and id_rsa.pub (public key) in your ~/.ssh folder.
# Load SSH public key
$sshPublicKey = Get-Content -Path "$env:USERPROFILE\.ssh\id_rsa.pub"
# VM config
$vmConfig = New-AzVMConfig -VMName "linuxVM" -VMSize "Standard_B1s" |
Set-AzVMOperatingSystem -Linux -ComputerName "linuxVM" -Credential (New-Object System.Management.Automation.PSCredential("azureuser",(ConvertTo-SecureString "DummyPassword123!" -AsPlainText -Force))) -DisablePasswordAuthentication |
Set-AzVMSourceImage -PublisherName "Canonical" -Offer "UbuntuServer" `
-Skus "20_04-lts" -Version "latest" |
Add-AzVMNetworkInterface -Id $nic.Id
# Add SSH Key
$vmConfig = Add-AzVMSshPublicKey -VM $vmConfig -KeyData $sshPublicKey -Path "/home/azureuser/.ssh/authorized_keys"
Notice here:
New-AzVM -ResourceGroupName LinuxRG -Location eastus -VM $vmConfig
Once the deployment finishes, grab the public IP:
Get-AzPublicIpAddress -ResourceGroupName LinuxRG -Name linuxPublicIP | Select-Object IpAddress
Now connect via SSH:
ssh azureuser@<Public-IP>
With just a few tweaks to our PowerShell script, we’ve automated a Linux VM deployment in Azure.
Now you know how to:
This covers most real-world VM automation needs in Azure. From here, you can extend the script to: