Hi,
I have written the below script that should delete any VMs with _deco in the name, and have been powered off for 14 days or more. However, I find that it occasionally still removes VMs that were powered off before the 14 day threshold. Any idea what I'm doing wrong here?
# get all VMs that are powered off and contain's _deco in the name
$vms = Get-VM | where {$_.PowerState -eq "PoweredOff" -and $_.Name -match "_deco"}
# look for powered off events of the VMs stored in $VM over the last 14 days
$events = Get-VIEvent -Start (Get-Date).AddDays(-14) -Entity $vms | where{$_ -is [VMware.Vim.VmPoweredOffEvent]}
# the VIEvent above contains the old VM name in the event before it was renamed, as we normally shut it down before renaming. This line selects events that have the original server name
$selectedVMS = $vms | where{$events.Vm.Name -notcontains $_.Name}
# remove all VMs that have been powered off for >= 14 days and have _deco in the name
Remove-VM -VM $selectedVMS -DeletePermanently -Confirm:$false
Never mind, I had a colleague look at it and it turns out using -finish instead of -start solved the problem.
It now looks like this:
$events = Get-VIEvent -finish (Get-Date).addDays(-14) -Entity $vms | where{$_.FullFormattedMessage -like "*is powered off"}
Thanks for all your help as always!
Unless those specific VMs were powered off multiple times, I don't see an issue with the logic
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It might actually be due to the date format. I've done some more digging and it seems it prematurely deletes VMs from our vCenter in Europe, which uses European date format.
I need to tweak this and force the date to be in a consistent format, but not sure how that'll work. Have you seen this before and found a way to handle it?
In such multi-timezone scripts, I always make sure to use UTC.
If the different vCenters are not configured for UTC but in the local TZ, you can use the ToUniversalTime method on a DateTime object.
Just make sure the timestamps contain the original TZ information before calling ToUniversalTime, otherwise it will use the TZ of where you are calling the method.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Apologies for the delayed reply, I was on vacation.
I decided to first test as to whether the logic is actually working. I created a new VM called rgtest_decomm and ran the below.
It stored the rgtest_decomm VM in the $selectedVMs variable even though I had literally created it 5 mins prior to running the script.
Any idea why this would happen?
# get all VMs that are powered off and contain's _deco in the name
$vms = Get-VM | where {$_.PowerState -eq "PoweredOff" -and $_.Name -match "_deco"}
# look for powered off events of the VMs stored in $VM over the last 14 days
$events = Get-VIEvent -Start (Get-Date).addDays(-14) -Entity $vms | where{$_.FullFormattedMessage -like "*is powered off"}
write-host $events
# the VIEvent above contains the old VM name in the event before it was renamed, as we normally shut it down before renaming. This line selects events that have the original server name
$selectedVMS = $vms | where{$events.Vm.Name -notcontains $_.Name}
write-host $selectedVMs
Is the last poweroff event of that VM in the returned events ($events)?
If it is, which timestamp does the event have?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi,
It does and it returns the following (I replaced sensitive information with xxxx):
Template : False
Key : xxxx
ChainId : xxxx
CreatedTime : 8/30/2021 12:14:07 PM
UserName : xxxx
Datacenter : VMware.Vim.DatacenterEventArgument
ComputeResource : VMware.Vim.ComputeResourceEventArgument
Host : VMware.Vim.HostEventArgument
Vm : VMware.Vim.VmEventArgument
Ds :
Net :
Dvs :
FullFormattedMessage : rgtest_decomm on xxxx in ATL is powered off
ChangeTag :
If I let it continue with the script it'll remove rgtest_decomm despite the created time being less that 14 days old
Did you check that $events.VM.Name actually contains the name?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I just tested it, and $events.VM.Name does contain the name of the VM.
Then I'm afraid I have no clue why that event is in there.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Bugger. In that case do you have any other suggestions as to how I could achieve the goal of removing VMs that have been powered off for 14 days or longer and contain _decom in the name?
I would first investigate why there is a power off event for that specific VM.
Can you check which Tasks were executed against that VM over the last 14 days?
You can retrieve the TaskEvent objects.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Never mind, I had a colleague look at it and it turns out using -finish instead of -start solved the problem.
It now looks like this:
$events = Get-VIEvent -finish (Get-Date).addDays(-14) -Entity $vms | where{$_.FullFormattedMessage -like "*is powered off"}
Thanks for all your help as always!
That means you are fetching all events older than 14 days.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference