You can script all the vm creation process via powershell, this include the creation of resource group, the subnet, the vnet, the public ip, network security group, the storage and much more.
You can attach all vm resources to one resource group and by doing this you can easly delete the vm and realted resources by executing one command line.
Install and import AzureRM
In order to use and execute the below commands we need to install and import the AzureRM powershell module if we don't already have it, if you already have it you can skip this section.
PS: You need elevated privileges to install modules from PowerShell Gallery
`Install-Module -Name AzureRM -AllowClobber`
By default, the PowerShell gallery is not configured as a trusted repository for PowerShellGet. The first time you use PSGallery, the following message is displayed:
Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change
its InstallationPolicy value by running the Set-PSRepository cmdlet.
Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"):
So, don't worry about this message.
Once installed, you can import AzureRM by running the following command:
Import-Module AzureRM
Finnaly, to finish with this section we need to connect to Azure account, simply execute this command and you we be prompted:
Connect-AzureRmAccount


Create a resource group
A resource group is a logical container in which Azure resources are deployed and managed.
From your SDK, run the following code block to create a resource group:
$location = "francecentral"
$ResourceGroupName = "resource-group-1"
New-AzureRmResourceGroup -Name $ResourceGroupName -Location $location
Create storage resources
Create a storage account to store the output of boot diagnostics.
$StorageAccountName = "msstorage01"
$SkuName = "Standard_LRS"
$StorageAccount = New-AzureRMStorageAccount `
-Location $location `
-ResourceGroupName $ResourceGroupName `
-Type $SkuName `
-Name $StorageAccountName
Set-AzureRmCurrentStorageAccount `
-StorageAccountName $storageAccountName `
-ResourceGroupName $resourceGroupName
Create networking resources
Create a VNet (virtual network), subnet, and a public IP address. Creating these Azure resources help us providing the network connectivity to our VM.
$subnetConfig = New-AzureRmVirtualNetworkSubnetConfig `
-Name subNet-1 `
-AddressPrefix 192.168.1.0/24
Create the virtual network
$vnet = New-AzureRmVirtualNetwork `
-ResourceGroupName $ResourceGroupName `
-Location $location `
-Name vNet-1 `
-AddressPrefix 192.168.0.0/16 `
-Subnet $subnetConfig
Create a public IP address and specify a DNS name
$publicip = New-AzureRmPublicIpAddress `
-ResourceGroupName $ResourceGroupName `
-Location $location `
-AllocationMethod Static `
-IdleTimeoutInMinutes 4 `
-Name "mypublicdns$(Get-Random)"
Create a NSG (network security group ) and a NSG rule
The NSG secures our VM by using inbound and outbound rules.
Now, we need to create an inbound rule for port 3389 to allow incoming RDP (Remote Desktop) connections and an inbound rule for port 80 to let our VM receive the incoming web traffic.
$nsgrdprule = New-AzureRmNetworkSecurityRuleConfig `
-Name nsg-rdp-rule `
-Protocol Tcp `
-Direction Inbound `
-Priority 1000 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 3389 `
-Access Allow
$nsgwebrule = New-AzureRmNetworkSecurityRuleConfig `
-Name nsg-inbound-www-rule `
-Protocol Tcp `
-Direction Inbound `
-Priority 1001 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 80 `
-Access Allow
$nsg = New-AzureRmNetworkSecurityGroup `
-ResourceGroupName $ResourceGroupName `
-Location $location `
-Name nsg-1 `
-SecurityRules $nsgrdprule,$nsgwebrule
$nic = New-AzureRmNetworkInterface `
-Name nic-1 `
-ResourceGroupName $ResourceGroupName `
-Location $location `
-SubnetId $vnet.Subnets[0].Id `
-PublicIpAddressId $publicip.Id `
-NetworkSecurityGroupId $nsg.Id
$UserName='ali.mselmi'
$Password='P@ssword123'| ConvertTo-SecureString -Force -AsPlainText
$Credential=New-Object PSCredential($UserName,$Password)
Create the VM configuration object
$VmName = "VirtualMachinelatest"
$VmSize = "Standard_A1"
$VirtualMachine = New-AzureRmVMConfig `
-VMName $VmName `
-VMSize $VmSize
$VirtualMachine = Set-AzureRmVMOperatingSystem `
-VM $VirtualMachine `
-Windows `
-ComputerName "MainComputer" `
-Credential $Credential -ProvisionVMAgent
$VirtualMachine = Set-AzureRmVMSourceImage `
-VM $VirtualMachine `
-PublisherName "MicrosoftWindowsServer" `
-Offer "WindowsServer" `
-Skus "2016-Datacenter" `
-Version "latest"
$VirtualMachine = Set-AzureRmVMOSDisk `
-VM $VirtualMachine `
-CreateOption FromImage | `
Set-AzureRmVMBootDiagnostics -ResourceGroupName $ResourceGroupName `
-StorageAccountName $StorageAccountName -Enable |`
Add-AzureRmVMNetworkInterface -Id $nic.Id
Create the VM
Finnaly we can create the VM deployment configuration.
New-AzureRmVM `
-ResourceGroupName $ResourceGroupName `
-Location $location `
-VM $VirtualMachine
We can check the VM creation via the Azure portal:

Connect to the VM
To do a remote access into the VM that we created in the previous step, we need its public IP address also previously set up.
To do that, we just need to run the following command and get the public IP address:
Get-AzureRmPublicIpAddress `
-ResourceGroupName $ResourceGroupName | Select IpAddress

Now, we can do a remote desktop access after creating a Remote Desktop session with the VM, just you need replace the IP address with the publicIPAddress of your VM.
When prompted, you can login by using your credentials used when creating the VM.
`mstsc /v publicIpAddress`

Connect to the Azure VM with an RDP, SSH or Bastion
You can connect to the VM via RDP, SSH or Bastion, you just need to click to the created VM via Azure portal and then click connect.

Delete the VM
We can use the following command to remove the resource group that contains the VM and its related resources:
Remove-AzureRmResourceGroup `
-Name $ResourceGroupName
Final words...
The advantage of scripting the entire VM creation process is that often we don't need to create a single VM, but to create several, creating a script for the process gives us the flexibility to customize the VMs creation at large-scale.
Original blog post
Create a Windows Server virtual machine with PowerShell