Hi guys,
A while back Mr. LucD helped me with a script that automatically deletes any VM that has been powered off longer than 14 days. The script does work as intended but I wanted to see if someone could help me by modifying it so that instead of me having to update the script manually to exclude a VM from being deleted, we could simply make it so that if a virtual machine or multiple virtual machines are inside a folder, these would not get deleted. In other words, if we manually move a VM to a folder, the script will NOT remove any of the virtual machines inside it.
Below is the script I am using.
##Load all VMware related snap-ins
#Add-PSSnapin VMware.VimAutomation.Core
Get-Module -ListAvailable VM* | Import-Module
##vCenter connection information
$vcenter = 'vcenter instances'
$vcenteruser = 'vadmin'
$vcenterpw = ''
##Connects to all vCenter instances
Connect-VIServer $vcenter -User $vcenteruser -Password $vcenterpw
#Here's where you can exclude any virtual machines from being removed by the script. You will need to un-comment this line.
#You will also need to comment the $excludedVM = @{} line in order to honor this line.
#$excludedVM = 'Some VM' -----> This is where a folder would be a lot safer to use.
#Here's where you can ignore the exclusions. If you un-comment this line, all virtual machines that meet the 7 day criteria will be removed.
#If you comment this line, then you will need to un-comment the #$excludedVM = 'VM Name Line' in order to honor this line.
$excludedVM = @{}
#Here you're defining the any VM variable
$vms = @{}
#This piece will get all powered off VMs and exclude the ones from the list that were defined in the $excludedVM variable
Get-VM | where {$_.PowerState -eq "PoweredOff" -and $excludedVM -notcontains $_.Name} | % {$vms.Add($_.Name, $_)}
#Get-VM | where {$_.PowerState -eq "PoweredOff"} | % {$vms.Add($_.Name, $_)}
#Exclude any virtual machine that was powered off before the last 7 days
Get-VIEvent -Start (Get-Date).AddDays(-7) -Entity $vms.Values -MaxSamples ([int]::MaxValue) | where {$_ -is [VMware.Vim.VmPoweredOffEvent]} | Sort-Object -Property CreatedTime -Unique | % {$vms.Remove($_.VM.Name)}
#Remove the remaining VMs
#Remove-VM -VM $vms.Values -DeletePermanently -Confirm:$false -WhatIf
Remove-VM -VM $vms.Values -DeletePermanently -Confirm:$false
I think there was indeed an issue with that line I gave.
Try changing it to
$excludedVM = (Get-Folder -Name SafePlace | Get-VM).Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
If you replace that line with
all VMs in the folder SafePlace will be excluded.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Mr. Luc,
Thanks again for helping me on this one. It looks like the code modification may not be working and I say "may" cause I'm not 100 percent sure. There are a number of virtual machines (VM01 - VM05) that have been powered off for longer than a month and even though I have moved them to the "Exclude" folder, according to the Remove-VM statement they will still be removed.
I'm executing the code you provided in the following order:
1. $excludedVM = Get-Folder -Name Exclude | Get-VM
2. $vms = @{}
3. Get-VM | where {$_.PowerState -eq "PoweredOff" -and $excludedVM -notcontains $_.Name} | % {$vms.Add($_.Name, $_)}
4. Get-VIEvent -Start (Get-Date).AddDays(-7) -Entity $vms.Values -MaxSamples ([int]::MaxValue) | where {$_ -is [VMware.Vim.VmPoweredOffEvent]} | Sort-Object -Property CreatedTime -Unique | % {$vms.Remove($_.VM.Name)}
5. Remove-VM -VM $vms.Values -DeletePermanently -Confirm:$false -WhatIf
The output here tells me that VM01 - VM05 will still be removed even though they have been moved to the Exclude folder.
What if: Performing operation 'Removing VM from disk.' on VM 'VM01'
What if: Performing operation 'Removing VM from disk.' on VM 'VM02'
What if: Performing operation 'Removing VM from disk.' on VM 'VM03'
What if: Performing operation 'Removing VM from disk.' on VM 'VM04'
What if: Performing operation 'Removing VM from disk.' on VM 'VM05'
If i test the $excludeVM variable it does get the correct VMs. These are the VMs that have been powered off longer than a month. Also, it doesn't really matter if I change the Get-Date to 1 or 14. I don't think it would anyways.
PS C:\WINDOWS\system32> $excludedVM
Name PowerState Num CPUs MemoryGB
---- ---------- -------- --------
VM01 PoweredOff 6 16.000
VM02 PoweredOff 2 8.000
VM03 PoweredOff 8 16.000
VM04 PoweredOff 6 32.000
VM05 PoweredOff 4 32.000
Am I doing something wrong here or am I not testing this properly? Thanks again for your help sir.
Sir,
Any other options I can try to prevent the script from removing the virtual machines that have been placed inside the Exclude directory?
I think there was indeed an issue with that line I gave.
Try changing it to
$excludedVM = (Get-Folder -Name SafePlace | Get-VM).Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank very much sir. I will try it and let you know soon.
Mr. Luc!
Thank you very much. The last code modification did the trick.