In Windows Server 2012 and Windows Server 2012 R2, we can remove a VM by Hyper-V Manager or PowerShell, "Remove-VM". However, it just deleted the VM and a configuration file of that VM. It hasn't deleted the related virtual hard disk files so we need to delete the virtual hard disk files by ourself. I intended to create a PowerShell script to remove VMs and related virtual hard disk files.
Disclaimer: Make sure you do understand the script and test it in lab environment. You use this script at your own risk. If you don't understand what this script does, please don't use it in any environment.
This posting is provided “ AS IS” with no warranties, and confers no rights!
Disclaimer: Make sure you do understand the script and test it in lab environment. You use this script at your own risk. If you don't understand what this script does, please don't use it in any environment.
Function Delete-VM { <# .Synopsis Delete virtual machines with related virtual hard disk files in a Hyper-V server. .DESCRIPTION This function is intended to delete virtual machines with all related virtual hard disk files in a Hyper-V Server which is installed Windows Server 2012 and Windows Server 2012 R2. If a virtual machine is not in "Off" state , this script shows a pop-up window for Administrator deciding shut down the VM or not. After that, the script continue deleting the VM. There is a "Force" option to shut down and delete virtual machines without confirmation for this script. Before you using this function, it requires the Hyper-V Module for Windows PowerShell which is installed in your computer. .Notes Name : Delete-VM.ps1 Last Updated: 22-Nov-2013 Version : 1.0 Requires : PowerShell version 3.0 or above with Hyper-V Module for Windows PowerShell .Link http://terrytlslau.tls1.cc/2013/11/delete-vms-in-windows-server-2012-and.html .Parameter Name The virtual machine name in a Hyper-V Server. .Parameter ComputerName The computer name of a Hyper-V Server. .Parameter Force Shut down and delete virtual machines with related virtual hard disk files without confirmation window. .EXAMPLE Delete-VM -Name server01 Delete a VM named server01 in current Hyper-V host. .EXAMPLE Delete-VM -Name server02 -ComputerName HV02 Delete a VM named server02 in the Hyper-V host, HV02. .EXAMPLE Delete-VM -Name server03 -Force Shut down and delete a VM named server03 with related virtual hard disk files without any confirmation. .EXAMPLE Get-VM -Name Server04 | Delete-VM Get-VM and then pass the value from pipeline to Delete-VM. #> [CmdletBinding(ConfirmImpact='High')] Param ( [Parameter(Position=0,Mandatory=$True,ValueFromPipelineByPropertyName=$True,HelpMessage="Enter the VM name")] [String[]]$Name, [Parameter(ValueFromPipelineByPropertyName=$True)] [String[]]$ComputerName = $env:COMPUTERNAME, [Switch]$Force ) Process { ForEach ($Comp in $ComputerName) { ForEach ($VMName in $Name) { Try { $VMlist_OK = $True $VMlist = Get-VM -Name $VMName -ComputerName $Comp -ErrorAction Stop } Catch { $VMlist_OK = $False Write-Warning "The VM $VMName in the server $Comp cannot be found" } If ($VMlist_OK) { $VMHostPath = $((Get-VMHost -ComputerName $Comp).VirtualMachinePath) $VMState = $((Get-VM -Name $VMName -ComputerName $Comp).state) $VMPath = $((Get-VM -Name $VMName -ComputerName $Comp).path) $VHD = $((Get-VMHardDiskDrive -VMName $VMName -ComputerName $Comp).path) if ($Force) { Try { if (($VMState -eq 'Running') -or ($VMState -eq 'Paused')) { Stop-VM -Name $VMName -ComputerName $Comp -Force Remove-VM $VMName -ComputerName $Comp -Force Invoke-command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VHD -Force} Remove-Variable VHD if ($VMHostPath -ne $VMPath) { Invoke-command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VMPath -Recurse -Force} Remove-Variable VMPath } Write-Output "The VM $VMName in the server $Comp was deleted completely!!!" } else { Remove-VM $VMName -ComputerName $Comp -Force Invoke-command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VHD -Force} Remove-Variable VHD if ($VMHostPath -ne $VMPath) { Invoke-command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VMPath -Recurse -Force} Remove-Variable VMPath } Write-Output "The VM $VMName in the server $Comp was deleted completely!!!" } } Catch { Write-Warning "Force deleted $VMName error" } } else { if (($VMState -eq 'Running') -or ($VMState -eq 'Paused')) { Stop-VM -Name $VMName -ComputerName $Comp if ((Get-VM -Name $VMName -ComputerName $Comp).uptime -gt "00:00:00") { Write-Warning "The VM $VMName in $Comp hasn't been stopped!!! Cancel to delete VM $VMName" Continue } else { Write-Verbose "The VM $VMName in $Comp has been stopped!" Remove-VM -Name $VMName -ComputerName $Comp Try { Get-VM -Name $VMName -ComputerName $Comp -ErrorAction Stop | Select -First 0 Write-Warning "The VM $VMName in the server $Comp hasn't been deleted!!! Cancel to delete VM $VMName" Continue } Catch { Invoke-Command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VHD} Remove-Variable VHD if ($VMHostPath -ne $VMPath) { Invoke-Command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VMPath -Recurse} Remove-Variable VMPath } Write-Output "The VM $VMName in $Comp was deleted completely!!!" } } } else { Write-Verbose "The VM $VMName in $Comp has been stopped!" Remove-VM -Name $VMName -ComputerName $Comp Try { Get-VM -Name $VMName -ComputerName $Comp -ErrorAction Stop | Select -First 0 Write-Warning "The VM $VMName in $Comp hasn't been deleted!!! Cancel to delete $VMName" Continue } Catch { Invoke-Command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VHD} Remove-Variable VHD if ($VMHostPath -ne $VMPath) { Invoke-Command -ComputerName $Comp -ScriptBlock {Remove-Item -Path $Using:VMPath -Recurse} Remove-Variable VMPath } Write-Output "The VM $VMName in $Comp was deleted completely!!!" } } } } } } } # End Process } # End function
This posting is provided “ AS IS” with no warranties, and confers no rights!
No comments:
Post a Comment