Using PowerShell to rename, move or reconnect an Azure VM
Tags: azure, iaas, powershell
Published: 2019-08-15 17:05:31

---
title: Using PowerShell to rename, move or reconnect an Azure VM 
published: true
description: How to perform copy or rename operation using PowerShell
tags: Azure, IaaS, PowerShell
---


Sometimes you need to change something on a VM. You may want to rename it for compliance reasons, change the network, change the disk name, etc 

Once you create a VM in Azure there is no way to rename it or one of its components. Also, if you want to reconnect a VM to a different Virtual Network, you can’t. You can look in the portal, you can search the Azure PowerShell Cmdlet list or try with AZ CLI, you can’t.  

Some will say that you can use a backup vault to recreate the VM but it takes times and it doesn’t scale. You can’t manage multiple VM like this.  

We can automate this with PowerShell and the Azure PowerShell module.  

Imagine if you need to rename a VM and its disk in the same resource group and the same Azure region 

The first step is to create an object with the current VM configuration 


```powershell
$SourceVmObject = get-azvm -Name dsc-dns01 -ResourceGroupName MyRG 
```

If the VM uses Azure Backup Vault, before continuing we need to remove the VM's recovery point. 

When you create a Backup Vault, Azure will add an extra resource group named AzureBackupRF_RegionName_1, there is nothing visible inside (if you use the portal), but this where you can find the VM recovery point.  

There are named after the VM name, AzureBackup_vmname_XXXXXXX and it needs to be deleted before any copy operation on the VM. 

The problem is that it may fail sometime and you may need to do it again.  


```powershell
$LoopCondition = $false
$Count = 0
do { 
    try {
        Remove-AzResource -ResourceId $SourceVmRecoveryPoint.ResourceId -Force
        $LoopCondition = $true
    }
    catch {
        write-debug "Fail to delete recovery point $($SourceVmRecoveryPoint.Name) after $($Count) attentds"
    }
    $count +=1 
    if ($count -gt 5) { 
        $LoopCondition = $true
    }
} until ($LoopCondition)
```

We need to make sure the VM is deallocated. 

```powershell
$SourceVmPowerStatus = (get-azvm -Name $SourceVmObject.Name -ResourceGroupName $SourceVmObject.ResourceGroupName -Status).Statuses | where-object code -like "PowerState*"

if ($SourceVmPowerStatus -ne "VM deallocated") {
    stop-azVm -Name $SourceVmObject.Name -ResourceGroupName $SourceVmObject.ResourceGroupName -Force
    Start-Sleep -Seconds 30
}
```

Let’s define the VM new name  
```powershell
$vmNewName = "dsc-lab-dns01" 
```

One thing I love with the Azure PowerShell module is you can create a VM object and later, use this object to create a VM. 

```powershell
$NewVmObject = New-AzVMConfig -VMName $vmNewName -VMSize $SourceVmObject.HardwareProfile.VmSize 
```
We can now create VM components. 

We need to create a new network interface for the VM. We can attach it to the original network or to any other available network. 

```powershell
$subnetID = (Get-AzNetworkInterface -ResourceId $SourceVmObject.NetworkProfile.NetworkInterfaces[0].id).IpConfigurations.Subnet.id

$nic = New-AzNetworkInterface -Name "$($vmNewName.ToLower())-0-nic" -ResourceGroupName $SourceVmObject.ResourceGroupName  -Location $SourceVmObject.Location -SubnetId $SubnetId 

Add-AzVMNetworkInterface -VM $NewVmObject -Id $nic.Id
```

Now we have to deal with disks. In the VM Object perspective there two types of disks, OS and data disk. Information about disks is located in the StorageProfile property.  

To copy the VM, we need to create a snapshot for each disk and use snapshots to create new disks.  


Let's start with the OS disk.  

```powershell
$SourceOsDiskSku = (get-azdisk -ResourceGroupName $SourceVmObject.ResourceGroupName -DiskName $SourceVmObject.StorageProfile.OsDisk.name).Sku.Name

$SourceOsDiskSnapConfig =  New-AzSnapshotConfig  -SourceUri $SourceVmObject.StorageProfile.OsDisk.ManagedDisk.Id -Location $SourceVmObject.Location -CreateOption copy

$SourceOsDiskSnap = New-AzSnapshot -Snapshot $SourceOsDiskSnapConfig  -SnapshotName "$($SourceVmObject.Name)-os-snap"  -ResourceGroupName $SourceVmObject.ResourceGroupName

$TargetOsDiskConfig = New-AzDiskConfig -AccountType $SourceOsDiskSku -Location $SourceVmObject.Location -CreateOption Copy -SourceResourceId $SourceOsDiskSnap.Id

$TargetOsDisk = New-AzDisk -Disk $TargetOsDiskConfig -ResourceGroupName $SourceVmObject.ResourceGroupName -DiskName "$($vmNewName.ToLower())-os-vhd"

Set-AzVMOSDisk -VM $NewVmObject -ManagedDiskId $TargetOsDisk.Id -CreateOption Attach -Windows

```

We can now copy data disks. An Azure VM can have 0 to multiple data disk (it depends on de VM Size). 

For that, we need to parse the  DataDisks List. We need to take care of the Lun number so we will not run into problems after the restart  

```powershell
Foreach ($SourceDataDisk in $SourceVmObject.StorageProfile.DataDisks) { 
    
    $SourceDataDiskSku = (get-azdisk -ResourceGroupName $SourceVmObject.ResourceGroupName -DiskName $SourceDataDisk.name).Sku.Name

    $SourceDataDiskSnapConfig =  New-AzSnapshotConfig  -SourceUri $SourceDataDisk.ManagedDisk.Id -Location $SourceVmObject.Location -CreateOption copy

    $SourceDataDiskSnap = New-AzSnapshot -Snapshot $SourceDataDiskSnapConfig  -SnapshotName "$($SourceVmObject.Name)-$($SourceDataDisk.name)-snap"  -ResourceGroupName $SourceVmObject.ResourceGroupName

    $TargetDataDiskConfig = New-AzDiskConfig -AccountType $SourceDataDiskSku -Location $SourceVmObject.Location -CreateOption Copy -SourceResourceId $SourceDataDiskSnap.Id

    $TargetDataDisk = New-AzDisk -Disk $TargetDataDiskConfig -ResourceGroupName $SourceVmObject.ResourceGroupName -DiskName "$($vmNewName.ToLower())-$($SourceDataDisk.lun)-vhd"


    Add-AzVMDataDisk -VM $NewVmObject -Name "$($vmNewName.ToLower())-$($SourceDataDisk.lun)-vhd" -ManagedDiskId $TargetDataDisk.Id -Lun $SourceDataDisk.lun -CreateOption "Attach"

}
```

Now that we have completed the VM configuration, we can create the VM.  

```powershell
 New-AzVM -VM $NewVmObject -ResourceGroupName $SourceVmObject.ResourceGroupName -Location $SourceVmObject.Location 
```

This is one of the methods to rename a VM. You can use it also to reconnect a VM from one virtual network to another.