DEV Community

Cover image for Create a Windows Server virtual machine with PowerShell
Ali MSELMI
Ali MSELMI

Posted on

Create a Windows Server virtual machine with PowerShell

In today blog post we are going to create and use an Azure VM with powershell, This blog post also shows you the steps to:

  • Connect to the virtual machine with a remote client.
  • Clean up resources.

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 to Azure with an interactive dialog for sign-in
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:


# Create variables to store the location and resource group names.
$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.


# Create variables to store the storage account name and the storage account SKU information
$StorageAccountName = "msstorage01"
$SkuName = "Standard_LRS"

# Create a new storage account
$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.


# Create a the subnet configuration
$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.

Create an inbound NSG rule for the 3389 port


# Create an inbound NSG rule for the 3389 port
# This rule will allow us to connect to the VM via an RDP connection
$nsgrdprule = New-AzureRmNetworkSecurityRuleConfig `
  -Name nsg-rdp-rule `
  -Protocol Tcp `
  -Direction Inbound `
  -Priority 1000 `
  -SourceAddressPrefix * `
  -SourcePortRange * `
  -DestinationAddressPrefix * `
  -DestinationPortRange 3389 `
  -Access Allow

Create an inbound network security group rule for port 80


# This rule will allow the VM to receive incoming web connections via the port 80
$nsgwebrule = New-AzureRmNetworkSecurityRuleConfig `
  -Name nsg-inbound-www-rule `
  -Protocol Tcp `
  -Direction Inbound `
  -Priority 1001 `
  -SourceAddressPrefix * `
  -SourcePortRange * `
  -DestinationAddressPrefix * `
  -DestinationPortRange 80 `
  -Access Allow

Create the NSG (network security group)


# This will wrap up previously created rules (nsg-web-rule and nsg-rdp-rule) within an NSG
$nsg = New-AzureRmNetworkSecurityGroup `
  -ResourceGroupName $ResourceGroupName `
  -Location $location `
  -Name nsg-1 `
  -SecurityRules $nsgrdprule,$nsgwebrule 

# This command will create a VNC (virtual network card) and associate it with public IP address and NSG
$nic = New-AzureRmNetworkInterface `
  -Name nic-1 `
  -ResourceGroupName $ResourceGroupName `
  -Location $location `
  -SubnetId $vnet.Subnets[0].Id `
  -PublicIpAddressId $publicip.Id `
  -NetworkSecurityGroupId $nsg.Id

# Define a credential object to store the username and password for the VM
$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"

# Sets the operating system disk properties on a VM.
$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.



# Create the VM.
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.

Top comments (0)