Rename the guest OS to match the virtual machine name on Hyper-V

Rename the guest OS to match the virtual machine name on Hyper-V

Rate This
  • Comments 10

When you are managing a large number of virtual machines, it can get tricky to keep track of everything.  One thing that I see many people doing to help with this is to make sure that the guest operating system has the same network name as the virtual machine name.  This makes life a lot easier when moving between different tools.

However, I tend to rename and copy virtual machines a lot, which makes it difficult to keep the virtual machine and guest operating system name synchronized.  To handle this I wrote the following script:

# Get the virtual machine name from the parent partition
$vmName = (Get-ItemProperty –path “HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters”).VirtualMachineName
# Replace any non-alphanumeric characters with an underscore
$vmName = [Regex]::Replace($vmName,"\W","_")
# Trim names that are longer than 15 characters
$vmName = $vmName.Substring(0,[System.Math]::Min(15, $vmName.Length))
 
# Check the trimmed and cleaned VM name against the guest OS name
# If it is different, change the guest OS name and reboot
if ($env:computername -ne $vmName) {(gwmi win32_computersystem).Rename($vmName); shutdown -r -t 0}

What this script does is:

  • Read the virtual machine name from the registry inside the virtual machine
  • Clean up the virtual machine name and check it against the guest OS name
  • If they match, move along
  • If they do not match, rename the guest operating system and reboot

I have this script inside my virtual machines, configured to run automatically when the guest operating system boots.

Cheers,
Ben

Attachment: namecheck.zip
Leave a Comment
  • Please add 1 and 2 and type the answer here:
  • Post
  • Ben, this seems backward to me. I could see this breaking applications like SharePoint. Wouldn't it be better to have the script rename the Hyper-V VM name according to the OS name?

  • Totally agree with Wes , if this mechanism - script - is used for Exchange server VMs it will be a disaster !!

  • This has never been a problem for me, but you make an interesting point.  I will have to see if I can think of a way to make this script work in reverse :-)

    Cheers,

    Ben

  • Damian Flynn has written an excellent script that retrieves guest OS details: www.damianflynn.com/.../query-virtual-machines-details-using-powershell

  • Totally agree with the previous comments. You would never do this in a production environment as renaming the guest OS can have very unpredictable and/or disastrous effect with many apps like exchange/SQL etc. As a virtualization admin, you would rather track when/if the app owner did a rename in the guest and match the hypervisor name description to match.

  • Hi Ben,

    Great post. I do something similar, I like my VM host names to match the VM name in Hyper-V but I do this from my host. I've been meaning to publish the script that does this for a while and I have here: simon-may.com/powershell-to-rename-a-vm-from-the-host essentially I use PowerShell to query the VM on the hypervisor, ask the VM for it's IP address, run an invoke command to rename the VM.

    We could do it in reverse real easy too.

  • I can see this being useful for cloned throwaway machines so that you avoid having duplicate names on the network.  Something that runs on startup and then flags that it's done a rename on this machine once would at least be safe, and if it later finds the names mismatch then you could raise a warning in the event log.  Thanks for the script :)

    I do agree with the others and the first thing that came to mind was SQL, although it's not as cranky with server renames these days compared to back in the SQL 2000 days.  

  • Getting hostname from VM via KVP exchange is better solution instead of dns query.

    That should be something like this:

    $HyperVHost = "MyHyperV"

    filter Import-CimXml

    {

       $CimXml = [Xml]$_

       $CimObj = New-Object -TypeName System.Object

       foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY"))

       {

           $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE

       }

       $CimObj

    }

    $VMs = Get-VM -ComputerName $HyperVHost

    foreach ($VM in $VMs)

    {

    $VMInfo = Get-WmiObject -ComputerName $HyperVHost -Namespace root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='$VM'"

    $KVPData = Get-WmiObject -ComputerName $HyperVHost -Namespace root\virtualization -Query "Associators of {$VMInfo} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"

    $KVPExport = $KVPData.GuestIntrinsicExchangeItems

    $Hostname = ($KVPExport | where {$_.Name -eq "FullyQualifiedDomainName"}).Data

    $VM | Rename-VM -NewName $Hostname

    }

    I don't have test environment to test this script, so that might not work, but at least you will get to idea :)

  • How to get the details of Linux(Redhat) guest VM, like hostname and ip address

  • This is exactly what I was looking for for my private cloud setup with windows azure pack. I am using SetupComplete.cmd to run the script which works as expected but doing so the VM deployment gets stuck at customizing virtual machine stage. Though the actual VM finishes deploying including the name change task. Could you help with how you have set this script to run.

Page 1 of 1 (10 items)