Continuing with my series on Hyper-v 3.0 PowerShell, I wrote a script to rename the the Virtual Hard Disks (VHD) attached to a Virtual Machine (VM).

The script will query the VM to determine the attached VHDs. It will then rename the VHDs using the naming convention:

<VM Name>_<Controller Type>_<Controller Number>_<Controller Location>
e.g. TestVM1_IDE_0_0.vhd

After renaming the VHD files, the script will update the VM’s configuration to reflect the new VHD names. It will retain the same controller and location of the VHD.

This script will work for VMs with single or multiple VHDs. Also, it will work with both vhd and vhdx disks. The VM must be powered down, and any snapshots should be removed before running.

To run this script all you need to do is to update the variable $VM with the name of the VM that you want to change the VHD names for.


#Enter Name for new VM

$VM = "TestRenameVM1"

 

#Do not make any changes below this line

$vhd = Get-VMHardDiskDrive VMName $vm

Foreach ($vhd in $vhd)

{

    $oldName = $vhd.Path

    $newName = $oldName.Substring(0,$oldName.LastIndexOf("\"))

                + "\" + $vhd.VMName + "_" + $vhd.ControllerType

                + "_" + $vhd.ControllerNumber + "_"

                + $vhd.ControllerLocation

                + $oldName.Substring($oldName.LastIndexOf("."))

    Rename-Item $oldName $newName

    Set-VMHardDiskDrive VMName $vhd.VMName Path $newName

        -ControllerType $vhd.ControllerType -ControllerNumber

        $vhd.ControllerNumber ControllerLocation

        $vhd.ControllerLocation

}


In addition to changing a single VM’s VHD, the code above can be added to the script from my previous post Hyper-v 3.0 PowerShell - Import a VM. This would rename the VHDs during the import process. The full script is listed below.


#Enter Name for new VM

$VM = "RenameTest"

 

#Enter location to save VM files

$Path = "E:\HVMachines\" + $VM

 

#Enter the path to the exported virtual machine to be imported.

$Source = 'E:\Exports\Win08R2\Virtual Machines\A2424B9A-97C0-422C-A567-49857A454412.XML'

 

#Runs Import command

$Import = Import-VM -Path $Source –Copy -GenerateNewId -VirtualMachinePath $Path -VhdDestinationPath $Path -SnapshotFilePath $Path

 

#Renames VM

Foreach ($Import in $Import)

{

    $oldName = $Import.Name

    Rename-VM $oldName –NewName $VM

}

 

#Rename VHDs

$vhd = Get-VMHardDiskDrive -VMName $vm

Foreach ($vhd in $vhd)

{

    $oldName = $vhd.Path

    $newName = $oldName.Substring(0,$oldName.LastIndexOf("\"))

                + "\" + $vhd.VMName + "_" + $vhd.ControllerType

                + "_" + $vhd.ControllerNumber + "_"

                + $vhd.ControllerLocation

                + $oldName.Substring($oldName.LastIndexOf("."))

    Rename-Item $oldName $newName

    Set-VMHardDiskDrive -VMName $vhd.VMName -Path $newName

        ControllerType $vhd.ControllerType ControllerNumber

        $vhd.ControllerNumber -ControllerLocation

        $vhd.ControllerLocation

}


 

As with anything that make changes to systems I would recommend only using this in a lab, or development environment. If you want to use it on a production VM,  I would suggest making a good backup beforehand.