Thursday, December 15, 2011

Changing a VM vNIC MAC from dynamic to static

Through my VM creation exercise I am taking advantage of Hyper-V and its practice of assigning MAC address from a pool so that I don’t need to manage all that in my script.

Well, if you have not noticed, I have Provisioning Server in my environment.  And that means that I need to have static MAC addresses.  And I am using Export and Import to copy my MasterVM.

This means that I cannot set the MasterVM with a static MAC.  I would at least have to modify it to have a dynamic and then still set the individual VMs to static.

So, I just set the MasterVM to dynamic and do the rest when I assign the MAC to the VM by powering it on and off (I power the VM on to cause Hyper-V to assign the MAC to the vNIC – again, taking advantage of what the system does for me).

I have this array of new virtual machine names; $arrNewVms that I want to loop through.  I then power on each VM (I have to wait for the power on to complete), then I power off, then I modify the MAC.

Here is where things get tricky.  To discover the MAC of the VM I had previously used an association class this does not return a modifiable object.  So I have to actually get the VM vNIC, modify it, and then send it back to the ModifyVirtualSystemResources method.

foreach ($vmName in $arrNewVms) {
    $vm = Get-WmiObject Msvm_ComputerSystem -Filter "ElementName='$vmName'" -Namespace "root\virtualization" -ComputerName $hypervHost
    $Result = $vm.RequestStateChange(2) # start
    ProcessWMIJob $Result
    $vssd = $vm.getRelated("Msvm_VirtualSystemSettingData") | where {$_.SettingType -eq 3}
    $vmLegacyEthernet = $vssd.getRelated("Msvm_EmulatedEthernetPortSettingData") #This returns information not an actionable object
    foreach ($e in $vmLegacyEthernet) {
        $mac = $e.Address
        $macDash = $mac.Substring(0,2) + "-" + $mac.Substring(2,2) + "-" + $mac.Substring(4,2) + "-" + $mac.Substring(6,2) + "-" + $mac.Substring(8,2) + "-" + $mac.Substring(10,2)
        $arrUpdatedVms += ($vmName + "," + $macDash)
    $vm.RequestStateChange(3) # stop
    #Set the MAC to static by first getting the vNIC object
    $vnic = Get-WmiObject Msvm_EmulatedEthernetPortSettingData -Filter "Address='$mac'" -Namespace "root\virtualization" -ComputerName $hypervHost
    $vnic.StaticMacAddress = 1
    $VMManagementService.ModifyVirtualSystemResources($vm.__PATH, $vnic.psbase.gettext(1))

No comments: