legacy/Rename-VM/Rename-VM.ps1 (163 lines of code) (raw):
<#
.SYNOPSIS
Renames a VM
.DESCRIPTION
The script deletes the VM and recreates it preserving networking and storage configuration. THe script will snapshot each disk, create a new disk from the
snapshot, and create the new VM with the new disks attached.
There is no need to reinstall the operating system.
IMPORTANT: the script does not VM extensions or any identities assigned to the Virtual Machine. Also, the script will not work for VMs with public IP addresses.
.EXAMPLE
./Rename-VM.ps1 -SubscriptionName testsubscription -ResourceGroupName test-rg -VirtualMachineName vm1 -NewVirtualMachineName vm2 -Diskmapping diskmap
.LINK
https://github.com/Azure/SAP-on-Azure-Scripts-and-Utilities
.NOTES
v0.1 - Initial version
#>
#Requires -Modules Az.Compute
#Requires -Modules Az.Network
#Requires -Version 5.1
param(
#Azure Subscription Name
[Parameter(Mandatory = $true)][string]$SubscriptionName,
#Resource Group Name that will be created
[Parameter(Mandatory = $true)][string]$ResourceGroupName,
#Virtual Machine name
[Parameter(Mandatory = $true)][string]$VirtualMachineName,
#New Virtual Machine name
[Parameter(Mandatory = $true)][string]$NewVirtualMachineName,
#Disk mapping
[Parameter(Mandatory = $true)][hashtable]$diskmap,
#Delete Old Items
[Parameter(Mandatory = $false)][bool]$DeleteVM = $false
)
# select subscription
Write-Verbose "setting azure subscription"
$Subscription = Get-AzSubscription -SubscriptionName $SubscriptionName
if (-Not $Subscription) {
Write-Host -ForegroundColor Red -BackgroundColor White "Sorry, it seems you are not connected to Azure or don't have access to the subscription. Please use Connect-AzAccount to connect."
exit
}
Select-AzSubscription -Subscription $SubscriptionName -Force
# Get the details of the VM
Write-Verbose ""
Write-Verbose "getting VM config"
$originalVM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName
$Resources = New-Object -TypeName "System.Collections.ArrayList"
$diskErrors = $false
# Validate the disk mapping
foreach ($disk in $originalVM.StorageProfile.DataDisks) {
if (-Not $diskmap.ContainsKey($disk.Name)) {
Write-Warning -Message ("Disk: " + $disk.name + " does not exist in the disk map.")
$diskErrors = $true
}
}
$targetVM = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $NewVirtualMachineName -ErrorAction SilentlyContinue
if ($targetVM) {
Write-Warning -Message ("Virtual Machine: " + $NewVirtualMachineName + " already exists.")
exit
}
if ($diskErrors) {
exit
}
$Resources = New-Object -TypeName "System.Collections.ArrayList"
$IPConfig = $null
$thenic = $null
$Newnics = New-Object -TypeName "System.Collections.ArrayList"
foreach ($nic in $originalVM.NetworkProfile.NetworkInterfaces) {
$thenic = $nic.id
$nicname = $thenic.substring($thenic.LastIndexOf("/") + 1)
$othernic = Get-AzNetworkInterface -Name $nicname -ResourceGroupName $ResourceGroupName
$IPConfig = $othernic.IpConfigurations
$newNic = New-AzNetworkInterface -Name ($NewVirtualMachineName + "-nic") -ResourceGroupName $ResourceGroupName -IpConfiguration $IPconfig -Location $originalVM.Location
$Newnics.Add($newNic.Id)
}
[string]$osType = $originalVM.StorageProfile.OsDisk.OsType
[string]$location = $originalVM.Location
[string]$storageType = $originalVM.StorageProfile.OsDisk.ManagedDisk.StorageAccountType
$tags = $originalVM.Tags
# Shutdown or remove the original VM
# Stop-AzVM -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName -force
if ($DeleteVM) {
Write-Verbose "removing existing VM"
Remove-AzVM -ResourceGroupName $ResourceGroupName -Name $VirtualMachineName -force
}
else {
$Resources.Add([string]$originalVM.Id)
$Resources.Add([string]$thenic)
}
# Create the basic configuration for the replacement VM
$newVM = New-AzVMConfig -VMName $NewVirtualMachineName -VMSize $originalVM.HardwareProfile.VmSize -Tags $tags -AvailabilitySetId $originalVM.AvailabilitySetReference.Id -Zone $originalVM.Zones -ProximityPlacementGroupId $originalVM.ProximityPlacementGroup.Id
# Snap and copy the os disk
Write-Verbose "snapshotting disks"
$snapshotcfg = New-AzSnapshotConfig -Location $location -CreateOption copy -SourceResourceId $originalVM.StorageProfile.OsDisk.ManagedDisk.Id
$Resources.Add($originalVM.StorageProfile.OsDisk.ManagedDisk.Id)
$osdiskname = $originalVM.StorageProfile.OsDisk.Name
$snapshotName = $osdiskname + "-snap"
$snapshot = New-AzSnapshot -Snapshot $snapshotcfg -SnapshotName $snapshotName -ResourceGroupName $ResourceGroupName
$newdiskConfig = New-AzDiskConfig -AccountType $storageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id
$Resources.Add([string]$snapshot.Id)
$newdiskName = $NewVirtualMachineName + "-osdisk"
$newdisk = New-AzDisk -Disk $newdiskConfig -ResourceGroupName $ResourceGroupName -DiskName $newdiskName
if ($osType -eq "Linux") {
Write-Verbose "OS Type is Linux"
Set-AzVMOSDisk -VM $newVM -CreateOption Attach -ManagedDiskId $newdisk.Id -Name $newdisk.Name -Linux
}
if ($osType -eq "Windows") {
Write-Verbose "OS Type is Windows"
Set-AzVMOSDisk -VM $newVM -CreateOption Attach -ManagedDiskId $newdisk.Id -Name $newdisk.Name -Windows
}
# Snapshot & copy all of the drives
foreach ($disk in $originalVM.StorageProfile.DataDisks) {
#snapshot & copy the data disk
$snapshotcfg = New-AzSnapshotConfig -Location $location -CreateOption copy -SourceResourceId $disk.ManagedDisk.Id
$snapshotName = $disk.Name + "-snap"
$snapshot = New-AzSnapshot -Snapshot $snapshotcfg -SnapshotName $snapshotName -ResourceGroupName $ResourceGroupName
$Resources.Add([string]$disk.ManagedDisk.Id)
$Resources.Add([string]$snapshot.Id)
[string]$thisdiskStorageType = $disk.ManagedDisk.StorageAccountType
$diskName = $diskmap[$disk.Name]
$diskConfig = New-AzDiskConfig -SkuName $thisdiskStorageType -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id
$newdisk = New-AzDisk -Disk $diskConfig -ResourceGroupName $ResourceGroupName -DiskName $diskName
Add-AzVMDataDisk -VM $newVM `
-Name $diskName `
-ManagedDiskId $newdisk.Id `
-Caching $disk.Caching `
-Lun $disk.Lun `
-DiskSizeInGB $newdisk.DiskSizeGB `
-CreateOption Attach
}
# Adding the network card(s)
$nicCount = 0
foreach ($nic in $Newnics) {
if ($nicCount -eq 0) {
Add-AzVMNetworkInterface `
-VM $newVM `
-Id $nic -Primary
}
else {
{
Add-AzVMNetworkInterface `
-VM $newVM `
-Id $nic
}
}
$nicCount = $nicCount + 1
}
Write-Verbose "Creating the new VM"
New-AzVM -ResourceGroupName $ResourceGroupName -Location $originalVM.Location -VM $newVM -DisableBginfoExtension
Write-Host ("The new Virtual Machine " + $NewVirtualMachineName + " is created")
if ($DeleteVM) {
$confirmation = Read-Host "Are you sure you want to delete the old Virtual Machine info? y/n?"
if ($confirmation -eq 'y') {
foreach ($Resource in $Resources) {
Write-Host ("Removing " + $Resource)
Remove-AzResource -ResourceId $Resource -Force
}
}
}
else {
Set-Content -Path ".\removeresources.ps1" -Value "# This script can be used to delete the unused resources" -Force
foreach ($resource in $Resources) {
Add-Content -Path ".\removeresources.ps1" -Value ("Remove-AzResource -ResourceId " + $resource)
}
}