How To Set Dynamic MAC Address On a Hyper-V VM With PowerShell

4 min read

Introduction

Since Hyper-V inception back in 2008, you can configure a virtual machine to use a dynamic or a static MAC address for any given virtual network adapter.

Hyper-V by default uses dynamic MAC address – which means that Hyper-V will generate an initial MAC address for each network adapter, either for VM (vmNIC) or for the host (vNIC), and it will regenerate the MAC address if it believes it is necessary.

If you use static MAC addresses, you can use the MAC address which was generated initially for you, or you can manually specify the MAC address to use, but once a static MAC address is set on a VM, Hyper-V will never change it.

Each Hyper-V server has a MAC address range that it uses for generating new dynamic MAC addresses. You can also configure this range yourself if you want to. Each Hyper-V host generates a default pool. They all use the same first three octets: (00-15-5D), as Microsoft owns that prefix. The next 2 octets (14-22) are generated by the last two octets of the IP address that was first set up on the Hyper-V server. The last octet (FF) is generated from the range 0x00xFF.

I was working recently on a scenario where I want to change the default MAC address pool on each Hyper-V host, and then I want to force all virtual machines to get a new MAC address from the new pool. The challenge is, all virtual machines are already set to use a static MAC address.

To generate a new MAC address for the VM which is set to use static MAC address, you want to go through the following steps:

  1. Shutdown the VM if it’s running.
  2. Set the VM to use a dynamic MAC address. You can do this via Windows Admin Center, Hyper-V Manager or using PowerShell (script below).
  3. Turn On the VM. Hyper-V will then generate a new Dynamic MAC address from the newly defined pool range.
  4. If you want to set back static MAC address, then you can do this via Windows Admin Center, Hyper-V Manager or using Set-VMNetworkAdapter PowerShell cmdlet.

What if you have a lot of VMs? PowerShell to the rescue!

Set Dynamic MAC Address using PowerShell ⌨

If you want to set a static MAC address on a Hyper-V VM using PowerShell, then you can do this with a single command as follows:

Set-VMNetworkAdapter -VMName SRV-VM01 -StaticMacAddress "00155D62F44C"

However, Set-VMNetworkAdapter with -DynamicMacAddress parameter won’t work as you expect to set a Dynamic MAC address. For this, we need to leverage WMI and root\virtualization\v2 namespace.

Here is a PowerShell script that will do the job for you. You can develop around it and target a large number of VMs:

<#
.Synopsis
 A script used to set Dynamic MAC Address.

.DESCRIPTION
 A script used to set Dynamic MAC Address on a single Hyper-V VM.

.Notes
 Created   : 2019-12-17
 Version   : 1.0
 OS        : Windows Server 2016 Hyper-V or later
 Requires  : PowerShell 5.1
 Author    : Charbel Nemnom
 Twitter   : @CharbelNemnom
 Disclaimer: This script is provided "AS IS" with no warranties.

.LINK
 To provide feedback or for further assistance please visit: https://charbelnemnom.com
.EXAMPLE
.\Set-VMDynamicMACAddress -HostName <HyperV-HostName> -VMName <VMNAME> -Verbose 
#>
[CmdletBinding()]
Param(
[Parameter(Position = 0, Mandatory = $true, HelpMessage = 'Enter the Hyper-V Host Name')]
[Alias('hn')]
[string]$HostName,

[Parameter(Position = 1, Mandatory = $true, HelpMessage = 'Enter the VM Name')]
[Alias('vn')]
[string]$VMName
)

Invoke-Command -ComputerName $HostName -ScriptBlock {
Param ($VMName)

$adapter = Get-VMNetworkAdapter -VMName $VMName
$VerbosePreference = "continue"

Write-Verbose "Checking if VM: $VMName is set to use Dynamic MAC Address..."
$Msvm_VirtualSystemManagementService = Microsoft.PowerShell.Management\Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
$wmiPortSettingData = Microsoft.PowerShell.Management\Get-WmiObject -Namespace root\virtualization\v2 -Class "Msvm_SyntheticEthernetPortSettingData" | Where-Object {$_.instanceID -eq $adapter.id}

if ($wmiPortSettingData.StaticMacAddress -eq $true) {
if ($adapter.Status) {
Write-Verbose "Stop the VM: $VMName"
Stop-VM -Name $VMName -Force | Out-Null
}
$wmiPortSettingData.StaticMacAddress = $false
$wmiPortSettingData.Address = ""
$result = $Msvm_VirtualSystemManagementService.ModifyResourceSettings($wmiPortSettingData.GetText(2))
Write-Verbose "Dynamic MAC Address is set on VM: $VMName"
}
else {
Write-Verbose "The VM: $VMName is already set to use Dynamic MAC Address..."
}

if (!$adapter.Status) {
Write-Verbose "Start the VM: $VMName"
Start-VM -Name $VMName | Out-Null
}

} -ArgumentList $VMName

Here is the output when you run the script:

If you have any feedback or changes that everyone should receive, please feel free to leave a comment below.

That’s it there you have it.

Learn more 📕

Do you want to learn about Windows Server Hyper-V, I highly encourage you to check Windows Server 2016 Hyper-V Cookbook for in-depth details about Hyper-V and automation tasks.

__
Thank you for reading my blog.

If you have any questions or feedback, please leave a comment.

-Charbel Nemnom-

About Charbel Nemnom 550 Articles
Charbel Nemnom is a Cloud Architect, ICT Security Expert, Microsoft Most Valuable Professional (MVP), and Microsoft Certified Trainer (MCT), totally fan of the latest's IT platform solutions, accomplished hands-on technical professional with over 17 years of broad IT Infrastructure experience serving on and guiding technical teams to optimize the performance of mission-critical enterprise systems. Excellent communicator is adept at identifying business needs and bridging the gap between functional groups and technology to foster targeted and innovative IT project development. Well respected by peers through demonstrating passion for technology and performance improvement. Extensive practical knowledge of complex systems builds, network design, business continuity, and cloud security.

Be the first to comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.