Pete_Howarth3
Contributor
Contributor

Snapshot Deletion

I found the script below to delete snaps older than 5 days.  Is there a way to have it look at a date value assigne to a custom attibute called say snapshot_date and ignore deleting that snapshot until that date arrives?  For devs that want to keep a snapshot for until a specific date in the future?

$vcenter = "hostname"

$creds = Get-VICredentialStoreItem -file "C:\Vmware script\pass.cred"

 

#Connect to the vCenter server defined above. Ignore certificate errors

connect-viserver $vcenter -User $creds.User -Password $creds.Password -WarningAction 0

 

$excludeNamesRegEx = "donotdelete|donttouch|stayaway"

 

Clear-Host

Get-VM | Get-Snapshot |

Where {$_.Created -lt (Get-Date).AddDays(-5) -and $_.Name -notmatch $excludeNamesRegEx } |

Remove-Snapshot -Confirm:$false

Reply
0 Kudos
LucD
Leadership
Leadership

Try something like this

$ca = Get-CustomAttribute -Name 'snapshot_date'
$now = Get-Date

Get-VM | Get-Snapshot |
where{(Get-Annotation -Entity $_.vm -CustomAttribute $ca).Value -ge $now} |
Remove-Snapshot -Confirm:$false


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Pete_Howarth3
Contributor
Contributor

Is there a way to combine the two scripts so that I can have a jumpbox run it daily.  Delete any snaps that are 3 days old or 5 days old that it finds.  Ignore vm's with snaps that have that future date value until that date arrives?

Reply
0 Kudos
LucD
Leadership
Leadership

You could combine those in that Where-clause

where{$_.Created -lt (Get-Date).AddDays(-5) -and (Get-Annotation -Entity $_.vm -CustomAttribute $ca).Value -le $now} |


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Pete_Howarth3
Contributor
Contributor

I noticed that it's not storing the date value in $ca for the custom attribute named snapshot_date.

$ca = Get-CustomAttribute -Name 'snapshot_date'
$now = Get-Date

 

If I set the value of $ca to 11/3/2023 a future date and change the .addDays(0) it will delete the snapshot even though $ca has a future date value.

where{$_.Created -lt (Get-Date).AddDays(-0) -and (Get-Annotation -Entity $_.vm -CustomAttribute $ca).Value -le $now} |

Reply
0 Kudos
LucD
Leadership
Leadership

Are you sure it interprets '11/3/2023' correctly?
What does this show as date?

[DateTime]'11/3/2023'

Also, the Where-clause compares the value in the CA to the content of the $now variable.

The first part of the condition ($_.Created -lt (Get-Date).AddDays(-5)) checks if the snapshot was created more than 5 days ago.
The complete condition checks:
- if the snapshot was created more than 5 days ago
AND
- if the value in the CA is a date before now


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
wetnose88
Enthusiast
Enthusiast

If the date format is in MM/dd/yyyy h:mm:ss AM/PM, the sort result is not correct.

I have been working on report storage events from multiple arrays, the event creation time is MM/dd/yyyy h:mm:ss AM/PM, I need to  convert the datetime to DateTime objects, then do the sort, after the sort, convert the output back again for us to understand.

The code to sort date and time I used is as follows, hopefully this can help.

# Convert the data in the specified column to DateTime objects
    $dateColumn = $dataRange.Columns.Item("F")
    foreach ($cell in $dateColumn.Cells) {
    $cell.Value2 = [DateTime]::Parse($cell.Text)
   }

    # Perform the sort on the data range (descending order)
    $dataRange.Sort($dateColumn, 2) # Use 2 for descending order

    # Convert the sorted date and time values back to their original format
    foreach ($cell in $dateColumn.Cells) {
    $cell.NumberFormat = "MM/dd/yyyy h:mm:ss AM/PM"
}
    # Autofit all columns in the worksheet
    $usedRange.Columns.AutoFit()    

 

 

Reply
0 Kudos
Pete_Howarth3
Contributor
Contributor

 

PS C:\Users\pjhowarth> Date

 

Thursday, November 2, 2023 11:07:37 AM

 

 

 

PS C:\Users\> $ca = Get-CustomAttribute -Name 'snapshot_date'

 

PS C:\Users\> $ca

 

Key   Name                 TargetType         

---   ----                 ----------         

108   snapshot_date                           

 

PS C:\Users\> Get-Annotation -Entity $_.vm -CustomAttribute $ca

Get-Annotation : Cannot validate argument on parameter 'Entity'. The argument is null. Provide a valid value for the argument, and then

try running the command again.

At line:1 char:24

+ Get-Annotation -Entity $_.vm -CustomAttribute $ca

+                        ~~~~~

    + CategoryInfo          : InvalidData: (:) [Get-Annotation], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetAnnotation

Reply
0 Kudos
LucD
Leadership
Leadership

You can't run that code line by line from the PS prompt.
The $_ variable is the object in the pipeline, i.e. the Snapshot object returned by Get-Snapshot.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Pete_Howarth3
Contributor
Contributor

I setup two vm's with snaps.  One with a custom attribute and a future date.  Run the code below and it deletes the snap on the vm with no custom attribute and leaves the other alone.  If I change the date on the other and run the code again.  It doesn't do anything.  I've tried using a Global and Virtual Machine Custom attribute using the values 11-02-2023 and 11/02/2023 to see if it would delete it with today's date.  It doesn't do anything.  No errors either.

$ca = Get-CustomAttribute -Name 'snapshot_date'
$now = Get-Date

Get-VM | Get-Snapshot |
where{$_.Created -lt (Get-Date).AddDays(-0) -and (Get-Annotation -Entity $_.vm -CustomAttribute $ca).Value -le $now} |
Remove-Snapshot -Confirm:$false

Reply
0 Kudos
LucD
Leadership
Leadership

Did you check what is exactly in the CA?

Get-Annotation -Entity <VMname> -CustomAttribute $ca |
Select -ExpandProperty Value

Take note that the $now variable contains DateTime, i.e. today's date and the time.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Pete_Howarth3
Contributor
Contributor

The property value is 11-02-2023.  And the Get-Date is Thursday, November 2, 2023 11:45:35 AM.  

View solution in original post

Tags (1)
Reply
0 Kudos
Pete_Howarth3
Contributor
Contributor

Okay got it to work by Setting the format value for $now = Get-Date- Format MM/dd/yyyy 

Reply
0 Kudos
Pete_Howarth3
Contributor
Contributor

Full script

$vcenter = "name of vcenter"

$creds = Get-VICredentialStoreItem -file "C:\Temp\pass.cred"

$ca = Get-CustomAttribute -Name 'snapshot_date'

$now = Get-Date -Format MM/dd/yyyy

#Connect to the vCenter server defined above. Ignore certificate errors

#connect-viserver $vcenter -User $creds.User -Password $creds.Password -WarningAction 0


Clear-Host

Get-VM | Get-Snapshot |

where{$_.Created -lt (Get-Date).AddDays(-3) -and (Get-Annotation -Entity $_.vm -CustomAttribute $ca).Value -le $now} |

Remove-Snapshot -Confirm:$false

 

 

 

 

Reply
0 Kudos