How to compare a date to x months ago when only a part month has passed

Hi,

I’m wanting to create a monthly archive and keep 4 months worth. Each month i’ll create a new folder for this month and remove the oldest. Whilst I have a check in there to just select the oldest month to remove, i also wanted a bit of belt and braces to check that the folder i’m removing is indeed 4 months old. The issue I have is that i’m going to be running it on the first Monday of each month so date wise this may say have run on the 5th 4 months ago but is running on the 2nd this month, so the following check wouldn’t remove the 4 month old folder, as it’s just shy of 4 months old (obviously if it had run on the 2nd 4 months ago, and the 5th this month it would be fine):

Get-ChildItem -path “C:\temp” |Sort-Object -property creationtime -descending | Select -last 1 | Where CreationTime.month -le (Get-Date).AddMonths(-4) | remove-item

So what i’ve been trying to work out is a way of checking if the original folder is “the 4th month ago” if that makes sense ie Sept, i’ve tried various things all to no avail. Any pointers would be greatly welcomed :slight_smile:

Hi and welcome! When you share your code please format it :slight_smile:

Next with Get-ChildItem -path "C:\temp" That will get files and folders stored in that directory. You may want to add on the -Directory parameter to filter out non-directories.

If I am understanding you correctly, you’re just concerned about the month yeah? That is, as long the integar month value is 4 months in the future for the current date (or more) you want to proceed. I see you used the month property from the CreationTime but you didn’t do that with the second part. Have you tried something like this:

Get-ChildItem -Path "C:\temp" -Directory | Sort-Object -Property creationtime -Descending | Select-Object -Last 1 | Where-Object {($_.CreationTime.month) -le ((Get-Date).AddMonths(-4)).Month} | Remove-Item

That should in theory get you what you’re looking for, as that should just compare the [int] values those contain.

Hi thanks a lot for your response dotnVo. Yes, I definitely need to specify the -Directory parameter, thanks for that. I tried adding the .Month to the Get-Date but it still had the same result, if the folder was created on a day of the month after the current day of the month it would still leave it there. I had another suggestion posted elsewhere which has done the trick which is to create a new datetime object but adjusted to be the first of the month in which we’re runnnig the script, as below (apologies if it doesn’t format - I wasn’t sure how to do that on this forum)

Get-ChildItem -Directory -Path “C:\Temp” |
Where-Object {
$_.CreationTime -lt ([datetime]::new([datetime]::Now.Year, [datetime]::Now.Month, 1)).AddMonths(-3)
} |
Remove-Item -Recurse -Force;

Thanks again for taking time out to respond.

Formatting your code: How to format code on PowerShell.org

I thought about it some more and my approach really wasn’t a good one, mostly because if we try to use the month integer that represents it, we do math out of base 10, but that’s not how time works. There’s probably ways to get my approacch to work but it takes more code and work. For example, Jan of 2023 the value of the month is 1, but December of 2023 its 12, however, Jan of 2024 is ‘in the future’, so we really can’t take the month integer alone to do comparisons. Also, consider the fact that a ‘month’ is also a variable piece of data. How long is a month? Well, it depends.

I think there’s perhaps a better approach, but it ultimately depends on your needs.

  1. Separate your tasks into two different tasks. For your "creation’ task, always create it on a specific date (not every first Monday) but… perhaps every first day of the month. Then, for your removal task, run it maybe every month on the 7th. That way, when you do your time comparisons with the AddMonths method, the CreationTime of the folder your checking will be always created on the first of the month, and you are checking against the time where your script for the removal runs, which is the 7th, so you remove the days as part of the equation, as day 1 is always less than day 7. Hopefully that makes sense.
  2. There is a New-TimeSpan cmdlet that might be useful here. You can feed it a start date and end date and while it doesn’t spit out months, it does spit out days. Maybe you can work out what an ‘acceptable’ number of days is. That said, you’ll still run into situations where it won’t catch so you might need to drop the Select-Object -Last 1
  3. On that topic, consider dropping the Select-Object -Last 1. Add any checks that you need but perhaps when a situation happens and it hasn’t been quite 4 months ‘technically’, you just let it go, and clean it up the following month. This seems like the simplest solution to be honest. If it doesn’t matter if the archived folder sticks around another month, it should be cleaned up the following month. That said, I’d still probably implement #1. You just need to have other checks in place, like, make sure you name the folders in a certain pattern and you can filter on those with Get-ChildItem.
  4. Consider naming your folders in such a way so you can not only add those in to your checks, but implement a system where you can compare based on the folder names, based on what you want to do with them.

There are some different ways to get the job done it just depends on what you need really.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.