LW.

Glorified Notepad

Rename Azure VM with Powershell

Changes happen and sometimes there is a requirement to change the name of a virtual machine, be it from an error or a change of naming convention internally. Natively within Azure there is currently no way to rename a virtual machine, its virtual network or the disks attached too it, forcing users to either give up on name changes or build out new virtual machines and migrate disks.

Whilst there are some scripts available already that run through the process these did not meet my specific needs, primarily of retaining the internal private IP address. As when amended on mass it’s a sizeable task to manually adjust all network adapters.

This script completes the following actions;

  1. Collects VM variables
  2. Shuts down and deallocates VM
  3. Creates new VM
  4. Creates new network adapter
  5. Changes legacy network adapter IP to spare IP
  6. Creates IP configuation for new adapter
  7. Applies new adapter to new VM
  8. Creates snapshot of legacy OS disk and copies to new VM
  9. Creates snapshot of remaining disks and copies to new VM
  10. Finalises config and deploy machine

In order to roll back, simply shutdown the new VM, start the stopped/deallocated vm and reapply the static IP address needed

The below script is given without any guarantee and as such I would suggest you test first as Azure services often update. This script can be amended to include a foreach statement and import a CSV however I may update this later.

####Variables###
$vmname = "VMName"
$rgname = "ResourceGroupName"
$vmnewname = "NewVMName"
$SpareIP = "172.0.0.199"
###General###
    $VMsource = get-azvm -Name $vmname -ResourceGroupName $rgname
    #check offline
    $VMsourcestatus = (get-azvm -Name $VMsource.Name -ResourceGroupName $VMsource.ResourceGroupName -Status).Statuses | where-object code -like "PowerState*"
    if ($VMsourcestatus -ne "VM deallocated") {
        stop-azVm -Name $VMsource.Name -ResourceGroupName $VMsource.ResourceGroupName -Force
        Start-Sleep -Seconds 30
    }
    #creates new VM object#
        $NewVmObject = New-AzVMConfig -VMName $vmnewname -VMSize $VMsource.HardwareProfile.VmSize
###Networking###
#creates new network adapter#
        #network name#
        $networkID = (Get-AzNetworkInterface -ResourceId $VMsource.NetworkProfile.NetworkInterfaces[0].id).name
        #network ip#
        $IPAddress = (Get-AzNetworkInterface -ResourceId $VMsource.NetworkProfile.NetworkInterfaces[0].id).IpConfigurations.PrivateIpAddress
        #network subnetID#
        $subnetID = (Get-AzNetworkInterface -ResourceId $VMsource.NetworkProfile.NetworkInterfaces[0].id).IpConfigurations.Subnet.id     
    #Re-address legacy adapter#
        $Legnic = Get-AzNetworkInterface -ResourceGroupName $VMsource.ResourceGroupName -Name $networkID
        $Legnic.IpConfigurations[0].PrivateIpAddress = $SpareIP
        $Legnic.IpConfigurations[0].PrivateIpAllocationMethod = "Static"
        Set-AzNetworkInterface -NetworkInterface $Legnic
    #creates ipcofiguration#
        $IPconfig1 = New-AzNetworkInterfaceIpConfig `
        -Name "IPConfig1" `
        -PrivateIpAddressVersion IPv4 `
        -PrivateIpAddress $IPAddress `
        -SubnetId $SubnetId `
        -primary
    #creates new virtual nic#
        $nic = New-AzNetworkInterface `
        -Name "$($vmnewname.ToLower())-0-nic" `
        -ResourceGroupName $VMsource.ResourceGroupName  `
        -Location $VMsource.Location `
        -IpConfiguration $IPconfig1
    #adds virtual nic to VM#
        Add-AzVMNetworkInterface -VM $NewVmObject -Id $nic.Id
###Disks###
    #creates new OS disk#
        $VMsourcedisksku = (get-azdisk -ResourceGroupName $VMsource.ResourceGroupName -DiskName $VMsource.StorageProfile.OsDisk.name).Sku.Name
        $VMsourcedisksnap =  New-AzSnapshotConfig  -SourceUri $VMsource.StorageProfile.OsDisk.ManagedDisk.Id -Location $VMsource.Location -CreateOption copy
        $SourceOsDiskSnap = New-AzSnapshot -Snapshot $VMsourcedisksnap  -SnapshotName "$($VMsource.Name)-os-snap"  -ResourceGroupName $VMsource.ResourceGroupName
        $VMtargetdiskconf = New-AzDiskConfig -AccountType $VMsourcedisksku -Location $VMsource.Location -CreateOption Copy -SourceResourceId $SourceOsDiskSnap.Id
        $VMtargetdisk = New-AzDisk -Disk $VMtargetdiskconf -ResourceGroupName $VMsource.ResourceGroupName -DiskName "$($vmNewName.ToLower())-os-vhd"
        Set-AzVMOSDisk -VM $NewVmObject -ManagedDiskId $VMtargetdisk.Id -CreateOption Attach -Windows
    #creates remaing disks#
        Foreach ($SourceDataDisk in $VMsource.StorageProfile.DataDisks) { 
        $SourceDataDiskSku = (get-azdisk -ResourceGroupName $VMsource.ResourceGroupName -DiskName $SourceDataDisk.name).Sku.Name
        $SourceDataDiskSnapConfig =  New-AzSnapshotConfig  -SourceUri $SourceDataDisk.ManagedDisk.Id -Location $VMsource.Location -CreateOption copy
        $SourceDataDiskSnap = New-AzSnapshot -Snapshot $SourceDataDiskSnapConfig  -SnapshotName "$($VMsource.Name)-$($SourceDataDisk.name)-snap"  -ResourceGroupName $VMsource.ResourceGroupName
        $TargetDataDiskConfig = New-AzDiskConfig -AccountType $SourceDataDiskSku -Location $VMsource.Location -CreateOption Copy -SourceResourceId $SourceDataDiskSnap.Id
        $TargetDataDisk = New-AzDisk -Disk $TargetDataDiskConfig -ResourceGroupName $VMsource.ResourceGroupName -DiskName "$($vmNewName.ToLower())-$($SourceDataDisk.lun)-vhd"
    #create each new disk#
        Add-AzVMDataDisk -VM $NewVmObject -Name "$($vmnewname.ToLower())-$($SourceDataDisk.lun)-vhd" -ManagedDiskId $TargetDataDisk.Id -Lun $SourceDataDisk.lun -CreateOption "Attach"
    }
###Final Phase###
    #creates new VM with varibles#
        New-AzVM -VM $NewVmObject -ResourceGroupName $VMsource.ResourceGroupName -Location $VMsource.Location -Verbose