Create and manage a Windows virtual machine that has multiple NICs

Virtual machines (VMs) in Azure can have multiple virtual network interface cards (NICs) attached to them. A common scenario is to have different subnets for front-end and back-end connectivity, or a network dedicated to a monitoring or backup solution. This article details how to create a VM that has multiple NICs attached to it. You also learn how to add or remove NICs from an existing VM. Different VM sizes support a varying number of NICs, so size your VM accordingly.

Prerequisites

Make sure that you have the latest Azure PowerShell version installed and configured.

In the following examples, replace example parameter names with your own values. Example parameter names include myResourceGroup, myVnet, and myVM.

Create a VM with multiple NICs

First, create a resource group. The following example creates a resource group named myResourceGroup in the EastUs location:

New-AzureRmResourceGroup -Name "myResourceGroup" -Location "EastUS"

Create virtual network and subnets

A common scenario is for a virtual network to have two or more subnets. One subnet may be for front-end traffic, the other for back-end traffic. To connect to both subnets, you then use multiple NICs on your VM.

  1. Define two virtual network subnets with New-AzureRmVirtualNetworkSubnetConfig. The following example defines the subnets for mySubnetFrontEnd and mySubnetBackEnd:

    $mySubnetFrontEnd = New-AzureRmVirtualNetworkSubnetConfig -Name "mySubnetFrontEnd" `
        -AddressPrefix "192.168.1.0/24"
    $mySubnetBackEnd = New-AzureRmVirtualNetworkSubnetConfig -Name "mySubnetBackEnd" `
        -AddressPrefix "192.168.2.0/24"
    
  2. Create your virtual network and subnets with New-AzureRmVirtualNetwork. The following example creates a virtual network named myVnet:

    $myVnet = New-AzureRmVirtualNetwork -ResourceGroupName "myResourceGroup" `
        -Location "EastUs" `
        -Name "myVnet" `
        -AddressPrefix "192.168.0.0/16" `
        -Subnet $mySubnetFrontEnd,$mySubnetBackEnd
    

Create multiple NICs

Create two NICs with New-AzureRmNetworkInterface. Attach one NIC to the front-end subnet and one NIC to the back-end subnet. The following example creates NICs named myNic1 and myNic2:

$frontEnd = $myVnet.Subnets|?{$_.Name -eq 'mySubnetFrontEnd'}
$myNic1 = New-AzureRmNetworkInterface -ResourceGroupName "myResourceGroup" `
    -Name "myNic1" `
    -Location "EastUs" `
    -SubnetId $frontEnd.Id

$backEnd = $myVnet.Subnets|?{$_.Name -eq 'mySubnetBackEnd'}
$myNic2 = New-AzureRmNetworkInterface -ResourceGroupName "myResourceGroup" `
    -Name "myNic2" `
    -Location "EastUs" `
    -SubnetId $backEnd.Id

Typically you also create a network security group to filter network traffic to the VM and a load balancer to distribute traffic across multiple VMs.

Create the virtual machine

Now start to build your VM configuration. Each VM size has a limit for the total number of NICs that you can add to a VM. For more information, see Windows VM sizes.

  1. Set your VM credentials to the $cred variable as follows:

    $cred = Get-Credential
    
  2. Define your VM with New-AzureRmVMConfig. The following example defines a VM named myVM and uses a VM size that supports more than two NICs (Standard_DS3_v2):

    $vmConfig = New-AzureRmVMConfig -VMName "myVM" -VMSize "Standard_DS3_v2"
    
  3. Create the rest of your VM configuration with Set-AzureRmVMOperatingSystem and Set-AzureRmVMSourceImage. The following example creates a Windows Server 2016 VM:

    $vmConfig = Set-AzureRmVMOperatingSystem -VM $vmConfig `
        -Windows `
        -ComputerName "myVM" `
        -Credential $cred `
        -ProvisionVMAgent `
        -EnableAutoUpdate
    $vmConfig = Set-AzureRmVMSourceImage -VM $vmConfig `
        -PublisherName "MicrosoftWindowsServer" `
        -Offer "WindowsServer" `
        -Skus "2016-Datacenter" `
        -Version "latest"
    
  4. Attach the two NICs that you previously created with Add-AzureRmVMNetworkInterface:

    $vmConfig = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $myNic1.Id -Primary
    $vmConfig = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id $myNic2.Id
    
  5. Finally, create your VM with New-AzureRmVM:

    New-AzureRmVM -VM $vmConfig -ResourceGroupName "myResourceGroup" -Location "EastUs"
    

Add a NIC to an existing VM

To add a virtual NIC to an existing VM, you deallocate the VM, add the virtual NIC, then start the VM. Different VM sizes support a varying number of NICs, so size your VM accordingly. If needed, you can resize a VM.

  1. Deallocate the VM with Stop-AzureRmVM. The following example deallocates the VM named myVM in myResourceGroup:

    Stop-AzureRmVM -Name "myVM" -ResourceGroupName "myResourceGroup"
    
  2. Get the existing configuration of the VM with Get-AzureRmVm. The following example gets information for the VM named myVM in myResourceGroup:

    $vm = Get-AzureRmVm -Name "myVM" -ResourceGroupName "myResourceGroup"
    
  3. The following example creates a virtual NIC with New-AzureRmNetworkInterface named myNic3 that is attached to mySubnetBackEnd. The virtual NIC is then attached to the VM named myVM in myResourceGroup with Add-AzureRmVMNetworkInterface:

    # Get info for the back end subnet
    $myVnet = Get-AzureRmVirtualNetwork -Name "myVnet" -ResourceGroupName "myResourceGroup"
    $backEnd = $myVnet.Subnets|?{$_.Name -eq 'mySubnetBackEnd'}
    
    # Create a virtual NIC
    $myNic3 = New-AzureRmNetworkInterface -ResourceGroupName "myResourceGroup" `
        -Name "myNic3" `
        -Location "EastUs" `
        -SubnetId $backEnd.Id
    
    # Get the ID of the new virtual NIC and add to VM
    $nicId = (Get-AzureRmNetworkInterface -ResourceGroupName "myResourceGroup" -Name "MyNic3").Id
    Add-AzureRmVMNetworkInterface -VM $vm -Id $nicId | Update-AzureRmVm -ResourceGroupName "myResourceGroup"
    

    Primary virtual NICs

    One of the NICs on a multi-NIC VM needs to be primary. If one of the existing virtual NICs on the VM is already set as primary, you can skip this step. The following example assumes that two virtual NICs are now present on a VM and you wish to add the first NIC ([0]) as the primary:

    # List existing NICs on the VM and find which one is primary
    $vm.NetworkProfile.NetworkInterfaces
    
    # Set NIC 0 to be primary
    $vm.NetworkProfile.NetworkInterfaces[0].Primary = $true
    $vm.NetworkProfile.NetworkInterfaces[1].Primary = $false
    
    # Update the VM state in Azure
    Update-AzureRmVM -VM $vm -ResourceGroupName "myResourceGroup"
    
  4. Start the VM with Start-AzureRmVm:

    Start-AzureRmVM -ResourceGroupName "myResourceGroup" -Name "myVM"
    

Remove a NIC from an existing VM

To remove a virtual NIC from an existing VM, you deallocate the VM, remove the virtual NIC, then start the VM.

  1. Deallocate the VM with Stop-AzureRmVM. The following example deallocates the VM named myVM in myResourceGroup:

    Stop-AzureRmVM -Name "myVM" -ResourceGroupName "myResourceGroup"
    
  2. Get the existing configuration of the VM with Get-AzureRmVm. The following example gets information for the VM named myVM in myResourceGroup:

    $vm = Get-AzureRmVm -Name "myVM" -ResourceGroupName "myResourceGroup"
    
  3. Get information about the NIC remove with Get-AzureRmNetworkInterface. The following example gets information about myNic3:

    # List existing NICs on the VM if you need to determine NIC name
    $vm.NetworkProfile.NetworkInterfaces
    
    $nicId = (Get-AzureRmNetworkInterface -ResourceGroupName "myResourceGroup" -Name "myNic3").Id   
    
  4. Remove the NIC with Remove-AzureRmVMNetworkInterface and then update the VM with Update-AzureRmVm. The following example removes myNic3 as obtained by $nicId in the preceding step:

    Remove-AzureRmVMNetworkInterface -VM $vm -NetworkInterfaceIDs $nicId | `
        Update-AzureRmVm -ResourceGroupName "myResourceGroup"
    
  5. Start the VM with Start-AzureRmVm:

    Start-AzureRmVM -Name "myVM" -ResourceGroupName "myResourceGroup"
    

Create multiple NICs with templates

Azure Resource Manager templates provide a way to create multiple instances of a resource during deployment, such as creating multiple NICs. Resource Manager templates use declarative JSON files to define your environment. For more information, see overview of Azure Resource Manager. You can use copy to specify the number of instances to create:

"copy": {
    "name": "multiplenics",
    "count": "[parameters('count')]"
}

For more information, see creating multiple instances by using copy.

You can also use copyIndex() to append a number to a resource name. You can then create myNic1, MyNic2 and so on. The following code shows an example of appending the index value:

"name": "[concat('myNic', copyIndex())]", 

You can read a complete example of creating multiple NICs by using Resource Manager templates.

Configure guest OS for multiple NICs

Azure assigns a default gateway to the first (primary) network interface attached to the virtual machine. Azure does not assign a default gateway to additional (secondary) network interfaces attached to a virtual machine. Therefore, you are unable to communicate with resources outside the subnet that a secondary network interface is in, by default. Secondary network interfaces can, however, communicate with resources outside their subnet, though the steps to enable communication are different for different operating systems.

  1. From a Windows command prompt, run the route print command, which returns output similar to the following output for a virtual machine with two attached network interfaces:

    ===========================================================================
    Interface List
    3...00 0d 3a 10 92 ce ......Microsoft Hyper-V Network Adapter #3
    7...00 0d 3a 10 9b 2a ......Microsoft Hyper-V Network Adapter #4
    ===========================================================================
    

    In this example, Microsoft Hyper-V Network Adapter #4 (interface 7) is the secondary network interface that doesn't have a default gateway assigned to it.

  2. From a command prompt, run the ipconfig command to see which IP address is assigned to the secondary network interface. In this example, 192.168.2.4 is assigned to interface 7. No default gateway address is returned for the secondary network interface.

  3. To route all traffic destined for addresses outside the subnet of the secondary network interface to the gateway for the subnet, run the following command:

    route add -p 0.0.0.0 MASK 0.0.0.0 192.168.2.1 METRIC 5015 IF 7
    

    The gateway address for the subnet is the first IP address (ending in .1) in the address range defined for the subnet. If you don't want to route all traffic outside the subnet, you could add individual routes to specific destinations, instead. For example, if you only wanted to route traffic from the secondary network interface to the 192.168.3.0 network, you enter the command:

    route add -p 192.168.3.0 MASK 255.255.255.0 192.168.2.1 METRIC 5015 IF 7
    
  4. To confirm successful communication with a resource on the 192.168.3.0 network, for example, enter the following command to ping 192.168.3.4 using interface 7 (192.168.2.4):

    ping 192.168.3.4 -S 192.168.2.4
    

    You may need to open ICMP through the Windows firewall of the device you're pinging with the following command:

    netsh advfirewall firewall add rule name=Allow-ping protocol=icmpv4 dir=in action=allow
    
  5. To confirm the added route is in the route table, enter the route print command, which returns output similar to the following text:

    ===========================================================================
    Active Routes:
    Network Destination        Netmask          Gateway       Interface  Metric
              0.0.0.0          0.0.0.0      192.168.1.1      192.168.1.4     15
              0.0.0.0          0.0.0.0      192.168.2.1      192.168.2.4   5015
    

    The route listed with 192.168.1.1 under Gateway, is the route that is there by default for the primary network interface. The route with 192.168.2.1 under Gateway, is the route you added.

Next steps

Review Windows VM sizes when you're trying to create a VM that has multiple NICs. Pay attention to the maximum number of NICs that each VM size supports.