Search code examples
powershellpowercli

Deal with Date Time in PowerShell


I've written a pretty nifty PowerShell script that works with VMware PowerCLI to clone a couple of VMs off to a second storage device and then automatically delete them when they reach a certain age. It seems to work great until it gets to the end/beginning of the month, then the approach I used for date time seems to fail and all clones are deleted unexpectedly. Rather than include the entire script, here are the pieces that matter.

First, when the clones are created I am using the following code..

$vmdatestamp = (Get-Date).tostring('yyyyMMdd-HHmmss')
new-vm -Name $VM-$vmdatestamp -VM $VM -Datastore $CPFlag -vmhost host.domain.local -Location 'Regular Clone'

This variable ends up creating a VM clone that is named something like "VMName-20200214-040022" in the case that the date is Feb 14th, 2020 and the variable captured 4 AM and 00 Min and 22 seconds.

Then later on in the script there is a cleanup section that lists these cloned VMs and checks the date. The objective is to run a delete command if the clone is older than 3 days. So there is a foreach loop that runs off of all VMs found within a particular folder, "Regular Clone". $vmls is the var within the loop for each VM found. Here is the code I am using to check the dates and delete older than 3 days.

#Grab matched string and doctor it to only look at 8 digit date.
$var1 = $vmls.name
$var2 = $var1 -split '-' | Select-String '\d{8}'
$var3 = $var2 -replace '(?S)'

#Grab todays date in the same 8 digit format then subtract to compare variance.  How old is the clone?
$CompareDate = (Get-Date).tostring('yyyyMMdd')
$var4 = $CompareDate - $var3

      #If clone is older than 3 days, delete it.  Turn this knob based on your requirements.
      if($var4 -gt '3') {

So this last "if" statement that checks $var4 is greater than 3 is where the source of my problem is. I don't think the script is smart enough to figure out if for example today is the 1st, how minus '-' works. Anyone have a suggestion on how to better deal with this?

Regards, Adam Tyler


Solution

  • Powershell has a great deal of flexibility in dealing with dates and times using the [datetime] type. There is probably another answer to this somewhere out there, and I'll search for it later, but here are some basics.

    When you read in your filenames, which I am assuming are in 'VMName-yyyyMMdd-HHmmss' format, you can turn that into a PowerShell [datetime] object like so (Thanks to this post for the info on [datetime]::parseexact):

    [string]$VMFileName = #load $VMFileName variable with the name of your VM file somehow
    $VMFNSplit = $VMFileName -split '-'
    $FileDateStamp = [datetime]::ParseExact("$($VMFNSplit[-2])-$($VMFNSplit[-1])",'yyyyMMdd-HHmmss',$null)
    

    EDIT: Tested the above, and got this:

    PS> $VMFileName = 'VMName-20200222-043322'
    PS> $VMFNSplit = $VMFileName -split '-'
    
    PS> $VMFNSplit[-2]
    20200222
    
    PS> $VMFNSplit[-1]
    043322
    
    PS> "$($VMFNSplit[-2])-$($VMFNSplit[-1])"
    20200222-043322
    
    PS> $FileDateStamp = [datetime]::ParseExact("$($VMFNSplit[-2])-$($VMFNSplit[-1])",'yyyyMMdd-HHmmss',$null)
    
    PS> $FileDateStamp
    Saturday, February 22, 2020 4:33:22 AM
    

    Once you have your file date/time stamp in a [datetime], you can use the built in methods to add/subtract your intervals, like this:

    #If clone is older than 3 days, delete it.  Turn this knob based on your requirements.
    $TooOld = (Get-Date).AddDays(-3)
    If ($FileDateStamp -lt $TooOld) {#Delete it}
    

    Hope this helps!