Change The MAC Address On Your Azure Virtual Machine

Today I’m going to show you how to add a second NIC to an Azure Virtual Machine and how to change the MAC Address on your Azure Virtual Machine.

I had this requirement while automating the deployment of a component that is license locked to the MAC address of a NIC. In itself this is not a problem but combined with Azure and our deployment workflow it presented some challenges. As part of the deployment workflow the Azure VM is deleted and restored from a VHD image. Since this process creates a new VM and new NICs you also get a new MAC address every time which caused the license check to fail.

To avoid interfering with the normal operation of the networking in Azure I thought it best to add a second NIC on its own subnet and use it for the license while leaving the default NIC intact.

So the first step was to create a new subnet and to give it a different IP address range from the default NIC.

Change The MAC Address On Your Azure Virtual Machine

The second step is to add another NIC to the VM when you create it:

Add-AzureNetworkInterfaceConfig -Name "LicenseNIC" -SubnetName "License" -VM $NewVM

Thirdly there is the PowerShell script to change the MAC address when the new VM is created. Credit to Jason Fossen for the original script. This script is executed on the VM itself not against Azure. You can use Invoke-Command for instance as part of your deployment script to execute it remotely on the VM.

In the script I identify the NIC  used for licencing based on it’s IP address 10.32.2.* and then I  retrieve the index number for this NIC. This index is the same one used to find this NIC in the registry.

$indexobj = Get-WmiObject win32_networkadapterconfiguration -Filter "ipenabled = 'true'" | Where-Object {$_.IPAddress -like "10.32.2.*" } | Select-Object -Property Index
$index = $indexobj.index

The registry key for the NIC always has four digits, so padleft, then get the key.

$index = $index.tostring().padleft(4,"0")
$regkey = get-item "hklm:\system\CurrentControlSet\control\class\{4D36E972-E325-11CE-BFC1-08002BE10318}\$index"

Set a new value for MAC address, in this case 30-D5-1E-DD-F2-A5.
$regpath = "hklm:\system\CurrentControlSet\control\class\{4D36E972-E325-11CE-BFC1-08002BE10318}\$index"
set-itemproperty -path $regpath -name "NetworkAddress" -value $("30-D5-1E-DD-F2-A5")

If the NIC is not refreshed the new MAC address is not picked up by the licensing component we used. This may not be neccesary depending on your use case.

ipconfig.exe /release """$($thenic.netconnectionid)""" | out-null
$thenic.disable() | out-null
$thenic.enable() | out-null
ipconfig.exe /renew """$($thenic.netconnectionid)""" | out-null

If you now look at your NIC properties you will see the new MAC address.

Change The MAC Address On Your Azure Virtual Machine

PS. On my Windows 10 machine it didn’t display properly on the NIC properties but you can use ipconfig /all to see the MAC address.

Francois Delport

Part 4: Restore Virtual Machine Endpoints And Virtual Network Settings

Last week I briefly mentioned you have to re-configure all the settings on your VM when you restore it from a VHD image, you basically only get the hard disk back. Today I’m going to show you a few more details around restoring your VM endpoints and virtual network settings.

If you are completely new to Azure Virtual Networks please read the intro here. Among other things you use them to assign DHCP pools, create VPN connections and setup security groups. The feature I found the most useful was connecting VMs from different cloud services to the same internal network by putting them all on the same VNet. It is a lot simpler than having multiple VMs in the same cloud service and mapping all those external endpoints with different port numbers to the VMs inside the cloud service. By using different cloud services you can also give each VM its own public DNS name.

You can add and remove endpoints after creating your VM but I could not find a way to change the VNet of a VM after it was created, apart from recreating the VM , so it is important to specify the VNet when you create the VM. For example in this script I pipe the VM config, subnet name and static IP address to the New-AzureVM command and I pass the -VNetName parameter with the name of my VNet.

New-AzureVMConfig -Name "TestVM" -InstanceSize "Standard_D2" -ImageName "VMImage" |
Set-AzureSubnet -SubnetNames "Subnet-1" |
Set-AzureStaticVNetIP -IPAddress "10.0.0.10" |
New-AzureVM -ServiceName "NewService" -VNetName "Test VNet"

If you don’t need a static IP you can omit the Set-AzureStaticVNetIP line.

Next up I’m going to map some endpoints to my VM.

Get-AzureVM -ServiceName "NewService" -Name "TestVM" |
Add-AzureEndpoint -Name "Remote Desktop" -Protocol "tcp" -PublicPort 3389 -LocalPort 3389 |
Add-AzureEndpoint -Name "PowerShell" -Protocol "tcp" -PublicPort 5986 -LocalPort 5986 |
Update-AzureVM

I used known port numbers but for a very small amount of extra security you can use different ports. This is a very simple example, I didn’t use load balancing for instance, if you read the documentation you will see how to do that.

Tip: In my environment while I was deleting the existing VM and creating a new one from the imaged VHD I sometimes received this error:

New-AzureVM : Networking.DeploymentVNetAddressAllocationFailure : Unable to allocate the required address spaces for the deployment in a new or predefined subnet that is contained within the specified virtual network.

It happened intermittently and it turned out sometimes Azure took a while to release the static IP address. To try and avoid the problem I stop and deprovision the VM first before deleting it and I also added a retry loop in my PowerShell script. I didn’t have time to test it exhaustively so I can’t confirm that it is working but it looks that way.

Keep in mind this can also happen if another VM is using the same IP address as the one you are trying to assign to your VM. If you look at the list of IP address assigned to your running VMs in the portal you can see if it is already in use.

I didn’t experience this one myself but when I was investigating this error message I came across posts where users received this error but the IP was not in use when they looked at the portal. It turned out that the static IP was assigned at the OS level, never do that, always assign the static IP in the Azure. Just out of interest, you will notice when you assign a static IP to the VM in Azure it doesn’t show in your NIC settings in Windows control panel, everything happens in Azure not the OS.

Francois Delport