看到标题估计很多人会觉得这玩意也要写个博客,能不能再水点


    哈哈哈,当然没这么简单,不过也不会太难,这回要介绍的确实是如何删除Azure中的虚拟机,删除虚拟机本身是个简单的不能再简单的任务


    直接在Portal上鼠标点一下不就删掉了,这是绝对没错的。but,因为Azure的计算和存储是分离的,删除虚拟机其实只是删除了Azure的计算能力,本身Azure的OS磁盘,数据磁盘,网卡这些都还会保留在Azure环境中


    这样做的好处是显而易见的,可以避免你的数据因为VM删除而丢失,生产环境删除VM之后也建议要保留磁盘,等待确认数据可以删除后再将磁盘从存储账户或者是托管磁盘里删除掉


    然而有些时候我们是很明确的要把VM以及相关的信息完全删除掉的,但是正常删除VM的流程我们需要手动删除VM,然后再删除磁盘,删除网卡,公网IP等等这些都需要手动进行,然而很多时候用户其实是没有这种习惯的


    很多用户也并不了解需要如何删除这些遗留的资源,往往以为删除VM就万事大吉了,这样的后果就是往往Azure环境中会遗留非常多的磁盘,网卡,公网IP等资源,一方面导致额外的成本,另一方面也让Azure环境看起来很凌乱


    今天分享的脚本就可以帮忙避免这个问题,它的功能很简单

    1.删除VM

    2.删除VM关联的网卡

    3.删除网卡关联的公网IP

    4.删除VM关联的OS磁盘

    5.删除VM关联的数据磁盘


    要注意的是目前还只支持非托管磁盘,另外注意数据盘这些东西脚本也会全部删除掉的,所以运行前要千万注意,请确保VM相关的东西你都不需要了再运行脚本!!


    以下是完整的代码

param (
	[parameter(Mandatory = $false)]
	[switch]$AzureMoonCake,
	[parameter(Mandatory = $false)]
	[switch]$DoNotLogin,
	[parameter(Mandatory = $true)]
	[string]$ResourceGroupName,
	[parameter(Mandatory = $true)]
	[string]$VMName
)




function Write-DateTimeMessage
{
	param (
		[parameter(Mandatory = $false)]
		[switch]$Warning,
		[parameter(Mandatory = $true)]
		[string]$Message,
		[parameter(Mandatory = $false)]
		[string]$ForegroundColor
		
	)
	
	
	if ($Warning)
	{
		Write-Warning ($(Get-Date -UFormat '%Y/%m/%d %H:%M:%S') + " * " + $Message)
	}
	else
	{
		if ($ForegroundColor)
		{
			Write-Host ($(Get-Date -UFormat '%Y/%m/%d %H:%M:%S') + " * " + $Message) -ForegroundColor $ForegroundColor
		}
		else
		{
			Write-Host ($(Get-Date -UFormat '%Y/%m/%d %H:%M:%S') + " * " + $Message)
		}
	}
	
}



function Write-Error0Message
{
	Write-DateTimeMessage -Message $Error[0].Exception.Message -ForegroundColor Red
}


function Remove-AzureDisk
{
	param (
		[parameter(Mandatory = $true)]
		[string]$DiskURI
		
	)
	
	
	$DiskURIWithHttps=$DiskURI
	if ($DiskURI.StartSWITH("https://"))
	{
		$DiskURI = $DiskURI.replace("https://", "")
		if ($AzureMoonCake)
		{
			$EndPoint = "blob.core.chinacloudapi.cn"
		}
		else
		{
			$EndPoint = "blob.core.windows.net"
		}
		
		$StorageAccountName = $DiskURI.substring(0, $DiskURI.indexof($EndPoint) - 1)
		
		$StorageAccount = Get-AzureRmStorageAccount | ? { $_.StorageAccountName -eq $StorageAccountName }
		if (($StorageAccount -eq $null) -or ($StorageAccount.count -gt 1))
		{
			
			Write-DateTimeMessage -Warning -Message "Can't find Storage Account $StorageAccountName, pls check"
		}
		else
		{
			$Context = $StorageAccount.Context
			$DiskName = $DiskURI.Substring($DiskURI.LastIndexOf("/") + 1, $DiskURI.Length - $DiskURI.LastIndexOf("/") - 1)
			if ($DiskName -eq $null)
			{
				Write-DateTimeMessage -Warning -Message "Can't get disk name from disk uri, pls check"
			}
			else
			{
				$ContainerName = $DiskURI.Replace("/$DiskName", "")
				$ContainerName= $ContainerName.Substring($ContainerName.LastIndexOf("/") + 1, $ContainerName.Length - $ContainerName.LastIndexOf("/") - 1)
				if ($ContainerName -eq $null)
				{
					Write-DateTimeMessage -Warning -Message "Can't get container name from disk uri, pls check"
				}
				else
				{
					$Blob = Get-AzureStorageBlob -Blob $DiskName -Container $ContainerName -Context $Context
					
					if ($Blob -eq $null)
					{
						Write-DateTimeMessage -Warning -Message "Can't get disk blob $DiskName, pls check"
					}
					else
					{
						try
						{
							$Error.clear()
							Remove-AzureStorageBlob -Blob $DiskName -Container $ContainerName -Context $Context -Force -ErrorAction 'Stop'
							Write-DateTimeMessage -Message "Remove disk $DiskURIWithHttps successfully!"
						}
						catch
						{
							Write-Error0Message	
						}
						
					}
					
					
				}
			}
			
		}
		
		
		
	}
	else
	{
		Write-DateTimeMessage -Warning -Message "Something wrong, the disk uri is not valid"
	}
	
	
}


#Login Azure with ARM Mode
Import-Module AzureRM.Profile
$Error.Clear()

if (!$DoNotLogin)
{
	if ($AzureMoonCake)
	{
		Write-DateTimeMessage -Warning -Message "Current environment is Azure China(Mooncake)"
		Login-AzureRmAccount -EnvironmentName AzureChinaCloud
	}
	else
	{
		Write-DateTimeMessage -Warning -Message "Current environment is Azure Global"
		Login-AzureRmAccount
	}
	
	if ($? -eq $true)
	{
		Write-DateTimeMessage -Message "Login succeeded!" -ForegroundColor Cyan
	}
	else
	{
		Write-Error0Message
		break
	}
	
	
}
else
{
	$CurrentSubscription = Get-AzureRmSubscription
	if ($CurrentSubscription -eq $null)
	{
		Write-DateTimeMessage -Warning -Message "Didn't find any subscription for now! Please login"
		break
		
	}
}









#$Subscriptions = Get-AzureRmSubscription
#Get All PublicIP,VNET,NetworkInterfaces
$AllPublicIPs = Get-AzureRMPublicipaddress
$AllVirtualNetworks = Get-AzureRMVirtualnetwork
$AllNetworkInterfaces = Get-AzureRmNetworkInterface

try
{
	$Error.clear()
	
	
	
	$VM = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName -ErrorAction 'Stop'
	
	if ($VM -eq $null)
	{
		Write-DateTimeMessage -Warning -Message "No VM named $VMName found in resource group $ResourceGroupName"
		exit
	}
	else
	{
		$VMNics = $VM.NetworkProfile.NetworkInterfaces
		$VMOSDisk = $VM.StorageProfile.OsDisk
		$VMDataDisks = $vm.StorageProfile.DataDisks
		
		Write-DateTimeMessage -Message "Trying to remove VM $VMName..."
		Remove-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName -Force -ErrorAction 'Stop'|Out-Null
		Write-DateTimeMessage -Message "Remove VM $VMName successfully!"
		Write-DateTimeMessage -Message "Trying to remove VM Nic(s)..."
		
		foreach ($VMNic in $VMNics)
		{
			$Nic = $AllNetworkInterfaces | ? { $_.id -eq $VMNic.id }
			if ($Nic -eq $null)
			{
				
				Write-DateTimeMessage -Warning -Message "Can't find Nic ID $($VMNic.id)"
				break
			}
			else
			{
				$PublicIPID = $Nic.IpConfigurations.PublicIpAddress.Id
				Remove-AzureRmNetworkInterface -ResourceGroupName $Nic.ResourceGroupName -Name $Nic.Name -Force -ErrorAction 'Stop'
				Write-DateTimeMessage -Message "Remove NIC $($Nic.Name) successfully!"
				if ($PublicIPID -ne $null)
				{
					$PublicIP = $AllPublicIPs | ? { $_.id -eq $PublicIPID }
					if ($PublicIP -eq $null)
					{
						Write-DateTimeMessage -Warning -Message "Something wrong, can't find public ip with id $PublicIPID"
					}
					else
					{
						Write-DateTimeMessage -Message ("Find Public IP {0} associated with Nic {1}, trying to remove it..." -f $PublicIP.Name, $Nic.Name)
						Remove-AzureRmPublicIpAddress -ResourceGroupName $PublicIP.ResourceGroupName -Name $PublicIP.Name -Force -ErrorAction 'Stop'
						Write-DateTimeMessage -Message "Remove Public IP $($PublicIP.Name) successfully!"
					}
				}
				
			}
			
			
		}
		
		
		Write-DateTimeMessage -Message "Trying to remove OS disk..."
		
		
		if ($VMOSDisk.vhd -eq $null)
		{
			
			Write-DateTimeMessage -Message "VM $VMName is using managed disk"
			
		}
		else
		{
			
			$VMOSDiskURI = $VMOSDisk.vhd.URI
			
			Remove-AzureDisk -DiskURI $VMOSDiskURI
			
			
			Write-DateTimeMessage -Message "Trying to remove data disk..."
			
			if ($VMDataDisks -ne $null)
			{
				
				foreach ($VMDataDisk in $VMDataDisks)
				{
					
					Remove-AzureDisk -DiskURI $VMDataDisk.vhd.uri
				}
				
			}
		}
		
		Write-DateTimeMessage -Message "All done. Thanks"
		
		
	}
	
	
	
}
catch
{
	Write-Error0Message
}

    

    附上运行的截图,参数一共也没两个就不一一介绍了哈,都看得懂的

    使用PowerShell 删除Azure VM_VM