1. 程式人生 > >使用PowerShell 刪除Azure VM

使用PowerShell 刪除Azure VM

Azure POWERSHELL VM 虛擬機 OS

看到標題估計很多人會覺得這玩意也要寫個博客,能不能再水點


哈哈哈,當然沒這麽簡單,不過也不會太難,這回要介紹的確實是如何刪除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