Functions/Remove-AHVM.ps1
#Author: Adam Bertram #Link: https://github.com/adbertram/Random-PowerShell-Work/blob/master/Azure/Remove-AzrVirtualMachine.ps1 #Date: 10/16/2020 #Deletes the VM and the associated resources #I like the code that was provided but I did some modifying to get it up to date and working as desired for my needs function Remove-AHVM { <# .SYNOPSIS This function is used to remove any Azure VMs as well as any attached disks. By default, this function creates a job due to the time it takes to remove an Azure VM. .EXAMPLE PS> Get-AzVm -Name 'BAPP07GEN22' | Remove-AzrVirtualMachine This example removes the Azure VM BAPP07GEN22 as well as any disks attached to it. .PARAMETER VMName The name of an Azure VM. This has an alias of Name which can be used as pipeline input from the Get-AzureRmVM cmdlet. .PARAMETER ResourceGroupName The name of the resource group the Azure VM is a part of. .PARAMETER AsJob If you would rather have a job created to remove the VM in the background, use this switch parameter and specify credentials with the Credential switch. .PARAMETER Credential Credentials to create the job if using -AsJob #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [Alias('Name')] [string]$VMName, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [string]$ResourceGroupName, [Parameter()] [pscredential]$Credential, [Parameter()] [ValidateNotNullOrEmpty()] [switch]$AsJob ) process { $scriptBlock = { param ($VMName, $ResourceGroupName) $commonParams = @{ 'Name' = $VMName; 'ResourceGroupName' = $ResourceGroupName } $vm = Get-AzVm @commonParams #region Remove the boot diagnostics disk if ($vm.DiagnosticsProfile.bootDiagnostics) { Write-Verbose -Message 'Removing boot diagnostics storage container...' $diagSa = [regex]::match($vm.DiagnosticsProfile.bootDiagnostics.storageUri, '^http[s]?://(.+?)\.').groups[1].value Get-AzStorageAccount -Name $diagSa -ResourceGroupName $vm.ResourceGroupName | Remove-AzStorageAccount -Force } #endregion Write-Verbose -Message 'Removing the Azure VM...' $null = $vm | Remove-AzVM -Force Write-Verbose -Message 'Removing the Azure network interface...' foreach ($nicUri in $vm.NetworkProfile.NetworkInterfaces.Id) { $nic = Get-AzNetworkInterface -ResourceGroupName $vm.ResourceGroupName -Name $nicUri.Split('/')[-1] Remove-AzNetworkInterface -Name $nic.Name -ResourceGroupName $vm.ResourceGroupName -Force foreach ($ipConfig in $nic.IpConfigurations) { if ($Null -ne $ipConfig.PublicIpAddress) { Write-Verbose -Message 'Removing the Public IP Address...' Remove-AzPublicIpAddress -ResourceGroupName $vm.ResourceGroupName -Name $ipConfig.PublicIpAddress.Id.Split('/')[-1] -Force } } $nsg = Get-AzNetworkSecurityGroup | Where-Object { $_.Id -eq $nic.NetworkSecurityGroup.Id } If ($nsg.NetworkInterfaces.Count -eq 0) { Write-Verbose "No other VMs using $($nsg.name) - deleting $($nsg.name)" $nsg | Remove-AzNetworkSecurityGroup -Force } } ## Remove the OS disk Write-Verbose -Message 'Removing OS disk...' if ('Uri' -in $vm.StorageProfile.OSDisk.Vhd) { ## Not managed $osDiskId = $vm.StorageProfile.OSDisk.Vhd.Uri $osDiskContainerName = $osDiskId.Split('/')[-2] ## TODO: Does not account for resouce group $osDiskStorageAcct = Get-AzStorageAccount | Where-Object { $_.StorageAccountName -eq $osDiskId.Split('/')[2].Split('.')[0] } $osDiskStorageAcct | Remove-AzStorageBlob -Container $osDiskContainerName -Blob $osDiskId.Split('/')[-1] #region Remove the status blob Write-Verbose -Message 'Removing the OS disk status blob...' $osDiskStorageAcct | Get-AzStorageBlob -Container $osDiskContainerName -Blob "$($vm.Name)*.status" | Remove-AzStorageBlob #endregion } else { ## managed #Get-AzDisk | Where-Object { $_.ManagedBy -eq $vm.Id } | Remove-AzDisk -Force Get-AzDisk | Where-Object { $_.id -eq $vm.StorageProfile.OsDisk.ManagedDisk.Id } | Remove-AzDisk -Force } ## Remove any other attached disks if ('DataDiskNames' -in $vm.PSObject.Properties.Name -and @($vm.DataDiskNames).Count -gt 0) { Write-Verbose -Message 'Removing data disks...' foreach ($uri in $vm.StorageProfile.DataDisks.Vhd.Uri) { $dataDiskStorageAcct = Get-AzStorageAccount -Name $uri.Split('/')[2].Split('.')[0] $dataDiskStorageAcct | Remove-AzStorageBlob -Container $uri.Split('/')[-2] -Blob $uri.Split('/')[-1] } } Else { foreach ($disk in $vm.StorageProfile.DataDisks) { Remove-AzDisk -DiskName $Disk.name -ResourceGroupName $vm.ResourceGroupName -Force } } } if (!$AsJob) { & $scriptBlock -VMName $VMName -ResourceGroupName $ResourceGroupName } else { $initScript = { $null = Login-AzAccount -Credential $Credential } $jobParams = @{ 'ScriptBlock' = $scriptBlock 'InitializationScript' = $initScript 'ArgumentList' = @($VMName, $ResourceGroupName) 'Name' = "Azure VM $VMName Removal" } Start-Job @jobParams } } } |