Often you might receive a request to Delete multiple VMs from Azure. its little cumbersome to delete VM and its components from portal. Automation minimize the time and avoid human errors.

This could cover the below scenarios:

  • Delete VM, its associated NICs and disks.

The following guide assumes that the user has basic knowledge of using Windows and PowerShell.

Although some familiarity with the Azure Portal would be beneficial, it is absolutely not necessary, as a step by step approach will be provided.

Script workflow:

  • Collects all the input from csv
  • Select subscription
  • Validate VM name exist in the subscription if does exists then script stops.
  • Fetch Resource Group, NICs and Storage account
  • Deletes the VM configuration
  • Deletes NIC card
  • Deletes OS and Data disk VHDs.
  1. Pre-requisites

The following prerequisites must be met, before performing the Core capacity check steps.

  1. Internet connection
  2. Valid Azure Subscription
  3. The person who will perform the below steps must have one of the following roles in the Azure subscription
    • Owner
    • Contributor
  4. Some familiarity with the Azure Portal would be beneficial, although not necessary
  5. Latest version of Microsoft .NET Framework (download link)
  6. Latest version of Microsoft Windows Management Framework (download link)
  7. Latest version of Microsoft PowerShell (download link including detailed installation guide)
  8. Latest version of Azure cmdlets (installation guide), although steps are provided below
  9. Some familiarity with PowerShell ISE, although not necessary (documentation)
  10. Some familiarity with the Azure Portal would be beneficial, although not necessary
  11. Some familiarity with PowerShell scripting would be beneficial, although not necessary
  12. Deletion Script

Windows PowerShell scripts can also be used for automating the VM Deletion process. It minimizes the human efforts and errors. It can be used to Delete multiple VM’s at once, therefore saving a lot of time. Windows Azure PowerShell module should be installed to use azure based commend lets (as mentioned in pre requisites). Follow the following link to download and configure the module – https://azure.microsoft.com/en-in/documentation/articles/powershell-install-configure

  • The script is provided at the end of this blog. For using this script,
    1. Open PowerShell ISE and type below command
Add-AzureRmAccount   # connecting your azure account to powershell

It gives the following popup

    1. Enter your credentials and click sign in. Once your account is added, just open the CSV file attached with script you downloaded.
    2. Add the VM details as required and save the file before closing it
    3. Now go back to the PowerShell and execute the script
    4. Once the VM are deleted, you will find the details in the log and also on the PowerShell console window

#Script to Delete the VM
#Import the VM details from CSV files
$CurrentPath = Split-Path -path $myInvocation.MyCommand.Definition -Parent 
$ErrorActionPreference = "STOP"
$serverList = Import-Csv "$currentpath\deletion.csv" 

FOREACH ($server in $serverList) {
 $vmName = $server.hostname
 $ResourceGroup = $server.resourceGroupName
 $subscription = $server.subscriptionName
 $storageaccRG = $server.StorageaccRG
 Select-AzureRmSubscription -SubscriptionName $subscription | Out-Null
 #get all resources to remove
 $vm = get-azureRMvm -Name $vmname -ResourceGroupName $ResourceGroup
 #if ($vm -eq $null) {continue}

 $osDisk = $vm.StorageProfile.OSDisk.Vhd.Uri
 $dataDisks = $vm.StorageProfile.DataDisks

 $nic = $vm.NetworkProfile.NetworkInterfaces
 $nicString = ([uri]$nic.id).OriginalString
 $nicName = $nicString.Split("/")[-1]
 $nicObject = Get-AzureRmNetworkInterface -ResourceGroupName $vm.ResourceGroupName -Name $nicName

 #stop vm
 stop-azureRmvm -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -force
 write-host "VM is getting stopped"
 Start-Sleep -Seconds 120 

 #remove Vm
 Write-Host "Removing VM $($vm.Name) in Resource Group $($vm.ResourceGroupName)"
 Remove-AzureRmVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force -Verbose
 Start-sleep -seconds 120
 #remove osdisk
 $ErrorActionPreference = "silentlycontinue"
 Write-Host "Removing osDisk $osDisk"

 $osDiskSourceStorageAccount = ([System.Uri]$osDisk).Host.Split('.')[0]
 $osDiskSourceContainer = ([System.Uri]$osDisk).Segments[-2] -replace '/'
 $osDiskBlob = ([System.Uri]$osDisk).Segments[-1]
 $osDiskStorageKey = Get-AzureRmStorageAccountKey -Name $osDiskSourceStorageAccount -ResourceGroupName $ResourceGroup 
 $osDiskContext = New-AzureStorageContext -StorageAccountName $osDiskSourceStorageAccount -StorageAccountKey ($osDiskStorageKey.value)[-1]
 Remove-AzureStorageBlob -Blob $osDiskBlob -Container $osDiskSourceContainer -Context $osDiskContext
 $ErrorActionPreference = "Stop"
 #remove datadisks
 foreach ($dataDisk in $dataDisks) {
 $dataDiskUri = $dataDisk.Vhd.Uri
 $dataDiskSourceStorageAccount = ([System.Uri]$dataDiskUri).Host.Split('.')[0]
 $dataDiskSourceContainer = ([System.Uri]$dataDiskUri).Segments[-2] -replace '/'
 $dataDiskBlob = ([System.Uri]$dataDiskUri).Segments[-1]
 $dataDiskRG = $vm.ResourceGroupName
 $dataDiskStorageKey = Get-AzureRmStorageAccountKey -ResourceGroupName $dataDiskRG -Name $dataDiskSourceStorageAccount
 $dataDiskContext = New-AzureStorageContext -StorageAccountName $dataDiskSourceStorageAccount -StorageAccountKey ($dataDiskstoragekey.value)[-1]
 Write-Host "Removing dataDisk $dataDiskBlob"
 Remove-AzureStorageBlob -Blob $dataDiskBlob -Container $dataDiskSourceContainer -Context $dataDiskContext
 #remove nic
 Write-host "Removing NIC $nicName"
 Remove-AzureRmNetworkInterface -ResourceGroupName $vm.ResourceGroupName -Name $nicName -Force
 Write-Host "Script execution stopped" $_.exception.message

 " $vmname Could not be deleted because $_.exception.message" |out-file "$CurrentPath\Error.txt" -Append

Input File format to be as below and saved as .CSV

<VM Name as in Portal>,<VM Resource Group>,<Azure Subscription where VM hosted>,<Storage Account Name>


Leave a Reply

Your email address will not be published. Required fields are marked *