copying files from daily folders using Powershell - powershell

I am looking to move daily created files each day to another folder. These files are saved to the relevant YYYY\MM\folder each day. Now I have created a way to move these files over using the year/month date function, however because there a number attached to the month, i.e. December looks like "12. December" it becomes a little tricky.
I tried to amend this with an If statement which would assign "a" to the relevant number corresponding with the month however it doesnt work.
$year = (Get-Date).Year
$month = Get-Date -Format "MMMMMMMM"
$day = (Get-Date).Day
$a = ""
If ($month = "January") { $a = "1."}
Elseif ($month = "February") { $a = "2."}
Elseif ($month = "March") { $a = "3."}
Elseif ($month = "April") { $a = "4."}
Elseif ($month = "May") { $a = "5."}
Elseif ($month = "June") { $a = "6."}
Elseif ($month = "July") { $a = "7."}
Elseif ($month = "August") { $a = "8."}
Elseif ($month = "September") { $a = "9."}
Elseif ($month = "October") { $a = "10."}
Elseif ($month = "November") { $a = "11."}
Elseif ($month = "December") { $a = "12."}
$month = Get-Date -Format $a" MMMMMMMM"
Copy-Item -Path F:\BB\$year\$month\Scan.pdf -Destination F:\BB
Any idea how to fix this/where am i going wrong. This is my first time writing in Powershell.
Edit: I am getting an error in the file location it is copying to does not register the difference in the coressponding months. For example the if statement states that if the month is = December a should = 12. but its currently coming up as 1. which should be the case for if it were January

The different forms of the month may as well be repeated in the format string, where
M = month number without leading zeroes
MM = month number with leading zeroes
MMM = abbreviated month name
MMMM = full month name
So:
$Month = Get-Date -f "M. MMMM"
> $Month
12. December
As the format string can contain any letter you can build the source path in one step:
(escaped with a backslash if interfering with a format letter)
$Source = "F:\BB\{0:yyyy\\M. MMMM}\Scan.pdf" -f (Get-Date)
> $Source
F:\BB\2018\12. Dezember\Scan.pdf
But I'm missing the days here?

If you use
$month = Get-Date -Format "MM"
this will get you the month as a number. If I understand what you are trying to achive this should match you source path.

$Date = get-date
$Path = "F:\BB\" + "$($Date.year)" + "\" + "$($Date.month)" + "\"
Copy-Item -Path $Path -Destination F:\BB

Related

How to get a result from a function

I'm trying to write a function to calculate either a full ISO date (yyyy-W-d, where W is the ISO week number), or just the ISO week number by itself. My function is based on this.
I have 2 problems with my code. One is that I do not know how extract either of the results I am after as written above. The other problem is that the second parameter doesn't show when I try to call the function.
This is my current code.
Function Get-ISODate {
Param(
[datetime]$Date = (Get-Date),
[bool]$LongFormat
)
$DayOfWeek = $Date.DayOfWeek
If ($DayOfWeek -match "[1-3]") {$Date.AddDays(3)}
$Year = $Date.Year
$Week = $(Get-Culture).Calendar.GetWeekOfYear(($Date),[System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [DayOfWeek]::Monday)
$Day = $Date.Day
If ($LongFormat)
{
Get-ISODate = $Year + '-W' + $Week + '-' + $Day
}
Else
{
Get-ISODate = 'W' + $Week
}
}
My expected results would be,
Get-ISOWeek returns W16, which is the current ISO week at this time of writing.
Get-ISOWeek -LongFormat $true returns 2021-W16-1
Get-ISOWeek -Date '2000-1-1' returns W52
Get-ISOWeek -Date '2000-1-1' -LongFormat $true returns 1999-W52-6
I'm using this link to verifiy my results with regards to the week calculation.
You can read about switch paramenter here.
What Mathias meant is to literally remove Get-ISODate =
The function should look like this:
Function Get-ISODate {
Param(
[datetime]$Date = (Get-Date),
[switch]$LongFormat
)
$DayOfWeek = $Date.DayOfWeek
If ($DayOfWeek -match "[1-3]") {$Date.AddDays(3)}
$Year = $Date.Year
$Week = $(Get-Culture).Calendar.GetWeekOfYear(($Date),[System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [DayOfWeek]::Monday)
$Day = $Date.Day
If ($LongFormat.IsPresent)
{
return "$Year-W$Week-$Day"
}
'W' + $Week
}
# Testing the function
PS /~> Get-IsoDate
W16
PS /~> Get-IsoDate -LongFormat
2021-W16-19
Got this working. Please note that the main issue was that I was trying to call the function incorrectly with "Get-ISOWeek". Monday morning.
I also added .value__ to Day for $Day to get the number instead of the day as "Monday" etc.
Function Get-ISODate {
Param(
[datetime]$Date = (Get-Date),
[bool]$LongFormat
)
$DayOfWeek = $Date.DayOfWeek
If ($DayOfWeek -match "[1-3]") {$Date.AddDays(3)}
$Year = $Date.Year
$Week = $(Get-Culture).Calendar.GetWeekOfYear(($Date),[System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [DayOfWeek]::Monday)
$Day = $Date.DayOfWeek.value__
If ($LongFormat -eq $true)
{
"$Year-W$Week-$Day"
}
Else
{
"W$Week"
}
}
Edit: I realised after posting this, the year was sometimes wrong according to the week number and day of the week. So here is my new version. I have checked the dates here.
Function Get-ISODate {
Param(
[datetime]$Date = (Get-Date),
[switch]$LongFormat
)
[int]$Year = $Date.Year
[int]$Month = $Date.Month
[int]$Day = $Date.DayOfWeek.value__
If ($Day -eq 0) {$Day = 7}
If ($Day -ge 1 -and $Day -le 3) {$Date = $Date.AddDays(3)}
$Week = (Get-Culture).Calendar.GetWeekOfYear($Date, 'FirstFourDayWeek', 'Monday')
Switch ($Week)
{
52 {If ($Day -ge 5 -and $Day -le 7 -and $Month -ne 12) {$Year = $Year - 1} ; Break}
53 {If ($Day -ge 5 -and $Day -le 7 -and $Month -ne 12) {$Year = $Year - 1} ; Break}
1 {If ($Month -eq 12) {$Year = $Year + 1} ; Break}
}
$Week = $Week.ToString('00')
If ($LongFormat.IsPresent)
{
"$Year-W$Week-$Day"
}
Else
{
"W$Week"
}
}

PowerShell script efficiency advice

I have a telephony .csv with compiled data from January 2020 and some days of February, each row has the date and time spent on each status, since someone uses different status over the day the file has one row for each status, my script is supposed to go through the file, find the minimum date and then start saving on new files all the data for the same day, so I'll end with one file for 01-01-2020, 02-01-2020 and so on, but it has 15 hours running and it's still at 1/22.
The column I'm using for the dates is called "DateFull" and this is the script
write-host "opening file"
$AT= import-csv “C:\Users\xxxxxx\Desktop\SignOnOff_20200101_20200204.csv”
write-host "parsing and sorting file"
$go= $AT| ForEach-Object {
$_.DateFull= (Get-Date $_.DateFull).ToString("M/d/yyyy")
$_
}
Write-Host "prep day"
$min = $AT | Measure-Object -Property Datefull -Minimum
Write-Host $min
$dateString = [datetime] $min.Minimum
Write-host $datestring
write-host "Setup dates"
$start = $DateString - $today
$start = $start.Days
For ($i=$start; $i -lt 0; $i++) {
$date = get-date
$loaddate = $date.AddDays($i)
$DateStr = $loadDate.ToString("M/d/yyyy")
$now = Get-Date -Format HH:mm:ss
write-host $datestr " " $now
#Install-Module ImportExcel #optional import if you dont have the module already
$Check = $at | where {$_.'DateFull' -eq $datestr}
write-host $check.count
if ($check.count -eq 0 ){}
else {$AT | where {$_.'DateFull' -eq $datestr} | Export-Csv "C:\Users\xxxxx\Desktop\signonoff\SignOnOff_$(get-date (get-date).addDays($i) -f yyyyMMdd).csv" -NoTypeInformation}
}
$at = ''
The first loop doesn't make much sense. It loops through CSV contents and converts each row's date into different a format. Afterwards, $go is never used.
$go= $AT| ForEach-Object {
$_.DateFull= (Get-Date $_.DateFull).ToString("M/d/yyyy")
$_
}
Later, there is an attempt to calculate a value from uninitialized a variable. $today is never defined.
$start = $DateString - $today
It looks, however, like you'd like to calculate, in days, how old eldest record is.
Then there's a loop that counts from negative days to zero. During each iteration, the whole CSV is searched:
$Check = $at | where {$_.'DateFull' -eq $datestr}
If there are 30 days and 15 000 rows, there are 30*15000 = 450 000 iterations. This has complexity of O(n^2), which means runtime will go sky high for even relative small number of days and rows.
The next part is that the same array is processed again:
else {$AT | where {$_.'DateFull' -eq $datestr
Well, the search condition is exactly the same, but now results are sent to a file. This has a side effect of doubling your work. Still, O(2n^2) => O(n^2), so at least the runtime isn't growing in cubic or worse.
As for how to fix this, there are a few things. If you sort the CSV based on date, it can be processed afterwards in just a single run.
$at = $at | sort -Property datefull
Then, iterate each row. Since the rows are in ascending order, the first is the oldest. For each row, check if date has changed. If not, add it to buffer. If it has, save the old buffer and create a new one.
The sample doesn't convert file names in yyyyMMdd format, and it assumes there are only two columns foo and datefull like so,
$sb = new-object text.stringbuilder
# What's the first date?
$current = $at[0]
# Loop through sorted data
for($i = 0; $i -lt $at.Count; ++$i) {
# Are we on next date?
if ($at[$i].DateFull -gt $current.datefull) {
# Save the buffer
$file = $("c:\temp\OnOff_{0}.csv" -f ($current.datefull -replace '/', '.') )
set-content $file $sb.tostring()
# Pick the current date
$current = $at[$i]
# Create new buffer and save data there
$sb = new-object text.stringbuilder
[void]$sb.AppendLine(("{0},{1}" -f $at[$i].foo, $at[$i].datefull))
} else {
[void]$sb.AppendLine(("{0},{1}" -f $at[$i].foo, $at[$i].datefull))
}
}
# Save the final buffer
$file = $("c:\temp\OnOff_{0}.csv" -f ($current.datefull -replace '/', '.') )
set-content $file $sb.tostring()

datetime comparison letting thread proceed when shouldn't

I have a backup script that puts files in a dated directory every night. I have another script, below, that goes through a list of dated directories and if it's within the range I want to delete, I will delete the directory, keeping the Saturday dated file. For some reason, for the dir dated Saturday, 1/12/2019, it's being deleted, even though the if statement should indicate it wouldn't be deleted.
This is my code:
function WeeklyCleanup($folderWeeklyCleanupDatedSubdirs) {
#find out date range to cleanup
$lastSaturday = GetLastSaturdayDate
$lastSaturday = [datetime]$lastSaturday
$weekAgoSunday = GetWeekAgoSundayDate
$weekAgoSunday = [datetime]$weekAgoSunday
#find out filename with Saturday date before current date but within week
Get-ChildItem $folderWeeklyCleanupDatedSubdirs | ForEach-Object {
write-output $_
#check to see if item is before day we want to remove
$temp = $_
$regex = [regex]::Matches($temp,'([0-9]+)-([0-9]+)-([0-9]+)')
if($regex.length -gt 0) #it matched
{
$year = $regex[0].Groups[1].Value
$month = $regex[0].Groups[2].Value
$day = $regex[0].Groups[3].Value
write-output $year
write-output $month
write-output $day
write-output "*************"
$dirDate = $regex[0].Groups[0].Value + " 12:00:00 PM"
write-output $dirDate
if($dirDate.length -gt 0) #it matched
{
$dateTimeObjectFromRegex = [datetime]$dirDate
##########this next statement is letting $dateTimeObjectFromRegex of 1/12/2019 through when it shouldn't. See time comparison below
if(([datetime]$dateTimeObjectFromRegex -lt [datetime]$lastSaturday) -and ([datetime]$dateTimeObjectFromRegex -ge [datetime]$weekAgoSunday)) #we're removing extra ones over last week, keep Saturday
{
$dirPathToRemove = Join-Path -path $folderWeeklyCleanupDatedSubdirs -ChildPath $temp.ToString()
Get-ChildItem -Path $dirPathToRemove #list the dir
#remove dir
if(-Not (Test-Path $dirPathToRemove )) #-PathType Container
{
$global:ErrorStrings.Add("Exception: No such path, $dirPathToRemove;; ")
write-output "++ Error: An error occured during copy operation. No such path, $dirPathToList ++"
}
else
{
#remove dir and subdirs
Remove-Item $dirPathToRemove -Force -Recurse
Get-ChildItem -Path $dirPathToRemove #list the dir
}
#Write-Output $_
#Write-Output " 1 "
} #if within last week
} #if dirDate length
} #if regex matched
} #get-childItem
}
function GetLastSaturdayDate()
{
$date = Get-Date #"$((Get-Date).ToString('yyyy-MM-dd'))"
#for($i=1; $i -le 7; $i++){
# if($date.AddDays(-$i).DayOfWeek -eq 'Saturday') #if found Saturday
# {
# $date.AddDays(-$i)
# $newDate = $date.AddDays(-$i)
# break
# }
#}
$newdate = $date.AddDays(-($date.DayOfWeek+1)%7)
return $newdate
}
function GetWeekAgoSundayDate()
{
$numberOfWeeks = 1; #week ago
$date = Get-Date #"$((Get-Date).ToString('yyyy-MM-dd'))"
#for($i=1; $i -le 7; $i++){
# if(($date.AddDays(-$i).DayOfWeek -eq 'Sunday') -and ($date.AddDays(-$i) -ne $date)) #if found a Sunday and it's not today
# {
# $date.AddDays(-$i)
# $newDate = $date.AddDays(-$i)
# break
# }
#}
#$newdate = $date.AddDays(-($date.DayOfWeek+1)%0)
$numDaysSincePreviousDate = $date.DayOfWeek.value__ + 0 #0 is Sunday
([System.DateTime] $previousDayOfWeek = $date.AddDays(- $numDaysSincePreviousDate)) | Out-Null
$previousDate = $previousDayOfWeek.AddDays(-($numberOfWeeks *7)).ToString("MM-dd-yyyy")
return $previousDate
}
The WeeklyCleanup script is called with this parameter:
$folderToCleanupDatedSubdirs = [System.IO.DirectoryInfo]"E:\Bak_TestDatedFolderCleanup"
For time comparison:
Directory item toLocRobo_2019-01-12 - Once I get regex with timestamp, I add the time in of 12:00:00 PM for the $dirDate variable. This becomes $dateTimeObjectFromRegex. Debugger shows it as Saturday, January 12, 2019 12:00:00 PM
When I run the program, I get $lastSaturday as Saturday, January 12, 2019 3:59:04 PM
When I run the program, debugger also shows $weekAgoSunday as Sunday, January 6, 2019 12:00:00 AM
From what I can see, it shouldn't be getting through that if statement to delete the dir for 1/12/2019.
I tried casting the dates to datetime to make sure it wasn't doing a string comparison in the if statement, even though I casted it above.
I've been looking at these links for more info on this, but it looks correct to me:
dateTimeComparisons not working expectedly
convert string to datetime
All I can think is that it's still treating the datetime in the first part of the if statement comparison like a string, so it's thinking 3:59 PM is greater than 12:00 PM. Any ideas how to get this date check to work? I don't care about times, just want to make sure it doesn't get rid of the Saturday-dated file from this past week, but only cleanup other dir's over that week.
Update
Made changes suggested by #brianist below, and it worked great. This is what it looks like so far. Saturday and Sunday functions haven't changed. He's asking me to post it. If he has any other suggestions how to get it to treat/compare what's returned from the last Saturday and weekAgoSunday functions as dates, without the cast, that'd make it look less clunky/easier to read. Thanks Brian!
#do weekly cleanup of DisasterBackup folder
function WeeklyCleanup($folderWeeklyCleanupDatedSubdirs) {
#find out current date
$currentDate = "$((Get-Date).ToString('yyyy-MM-dd'))" #example 2019-01-15
$currentDayOfWeek = (get-date).DayOfWeek.value__ #returns int value for day of week
#find out current day of week
$lastSaturday = GetLastSaturdayDate
$lastSaturday = [datetime]$lastSaturday #if we take away extra casts it won't do comparison line (-lt and -ge)
$weekAgoSunday = GetWeekAgoSundayDate
$weekAgoSunday = [datetime]$weekAgoSunday #if we take away extra casts it won't do comparison line (-lt and -ge), and can't move cast before function call because it isn't recognizing function anymore if I do
#find out filename with Saturday date before current date but within week
#get each dir item to check if we need to remove it
Get-ChildItem $folderWeeklyCleanupDatedSubdirs | ForEach-Object {
write-output $_
#check to see if item is before day we want to remove
$temp = $_
if($_.Name -match '(\d{4}-\d{2}-\d{2})$'){ #regex
write-output $Matches[1]
$dirDate = Get-Date $Matches[1] #turn regex into date
if(([datetime]$dirDate.Date -lt [datetime]$lastSaturday.Date) -and ([datetime]$dirDate.Date -ge [datetime]$weekAgoSunday.Date)) #we're removing extra ones over last week, keep Saturday
{
$dirPathToRemove = Join-Path -path $folderWeeklyCleanupDatedSubdirs -ChildPath $temp.ToString()
Get-ChildItem -Path $dirPathToRemove #list the dir
#remove dir
if(-Not (Test-Path $dirPathToRemove )) #-PathType Container
{
$global:ErrorStrings.Add("Exception: No such path, $dirPathToRemove;; ")
write-output "++ Error: An error occured during copy operation. No such path, $dirPathToList ++"
}
else
{
#remove dir and subdirs
Remove-Item $dirPathToRemove -Force -Recurse
Get-ChildItem -Path $dirPathToRemove #list the dir
}
} #if within last week
} #if regex matched
} #get-childItem
}
Re-reading your last sentence, I now see that your intention is to ignore times, not to include them in your comparison.
You are right to want to use [DateTime] objects when comparing, but do note that those objects always include a time.
Conveniently you can use the .Date property of such an object which returns a new one, with the time set to midnight. This is useful for comparing because the time would no longer be a factor.
Pulling out my modified if statement from below, you can do it like this:
if ($dirDate.Date -lt $lastSaturday.Date -and $dirDate.Date -ge $weekAgoSunday.Date) {
# do stuff
}
Now you're only comparing dates, and ignoring time!
Based on what you're showing it looks like the if statement is working as expected. To summarize, you say that:
$dateTimeObjectFromRegex is Saturday, January 12, 2019 12:00:00 PM
$lastSaturday is Saturday, January 12, 2019 3:59:04 PM
$weekAgoSunday is Sunday, January 6, 2019 12:00:00 AM
The conditional is:
if(([datetime]$dateTimeObjectFromRegex -lt [datetime]$lastSaturday)
-and ([datetime]$dateTimeObjectFromRegex -ge [datetime]$weekAgoSunday))
Therefore in pseudo-code it's:
if (
("January 12, 2019 12:00:00 PM" is earlier than "January 12, 2019 3:59:04 PM") # true
and
("January 12, 2019 12:00:00 PM" is later or the same as "January 6, 2019 12:00:00 AM") # true
) # true
I do want to point out that you are doing an awful lot of unnecessary datetime chopping and casting, and cleaning that up would help with readability and with debugging these types of issues.
$lastSaturday = GetLastSaturdayDate
$lastSaturday = [datetime]$lastSaturday
$weekAgoSunday = GetWeekAgoSundayDate
$weekAgoSunday = [datetime]$weekAgoSunday
Your functions already return [DateTime] objects, so there's no need for those casts.
$temp = $_
$regex = [regex]::Matches($temp,'([0-9]+)-([0-9]+)-([0-9]+)')
if($regex.length -gt 0) #it matched
{
$year = $regex[0].Groups[1].Value
$month = $regex[0].Groups[2].Value
$day = $regex[0].Groups[3].Value
write-output $year
write-output $month
write-output $day
write-output "*************"
$dirDate = $regex[0].Groups[0].Value + " 12:00:00 PM"
write-output $dirDate
This is quite complex, you could simplify it down to something like this:
if ($_.Name -match '(\d{4}-\d{2}-\d{2})$') {
# in here, you know the match was successful
$dirDate = Get-Date $Matches[1] # double check this, might need .Groups or something
if ($dirDate -lt $lastSaturday -and $dirDate -ge $weekAgoSunday) {
# do stuff
}
}
Probably some more optimizations etc. Hope this was helpful!

Loop through dates in hash table?

I have a hash table in Powershell that looks like this ($hash_dates.GetEnumerator() | sort -Property name):
11/1/2016 12:00:00 AM 5
11/2/2016 12:00:00 AM 3
11/4/2016 12:00:00 AM 2
The key is of type DateTime.
I am running a for loop to catch all the dates (dates only, times don't matter thus all midnight) and pull out each value in the hash table based on the date. The code:
$startdate = (get-date).AddDays(-30)
$today = get-date -format G
for($i = $startdate; $i -lt $today; $i=$i.AddDays(1))
{
$z = $i -split " "
$z = [datetime]$z[0]
$z = Get-Date $z -format G
"Comparing $z to: "
$hash_dates.Keys | ? { $hash_dates[$_] -eq $z }
}
I used the -format G and split to ensure the format matches. But the loop never finds any results (even though it loops through 11/1/2016 etc). Am I missing something?
Since your hashtable keys are [datetime] objects, there is no need to use date strings and string parsing at all:
$today = (Get-Date).Date # Note the .Date part, which omits the time portion
$startdate = $today.AddDays(-30)
# Note the change from -lt to -le to include today
for($i = $startdate; $i -le $today; $i = $i.AddDays(1))
{
# Note that `echo` is an alias for `Write-Output`, which is the default,
# so no need for an explicit output command.
"Looking for $i..."
# Simply try to access the hashtable with $i as the key, which
# either outputs nothing ($null), or outputs the value for that key.
$hash_dates.$i
}
Re echo / Write-Output / default output: note that your status messages will become of your data (output) stream, which may be undesired.
Consider using Write-Information instead.
Here's a simplified solution that demonstrates the expressiveness of PowerShell:
$today = (get-date).Date
# Construct an array with all dates of interest.
$dates = -30..0 | % { $today.AddDays($_) } # % is a built-in alias for ForEach-Object
# Pass the entire array as the hashtable "subscript", which returns
# the values for all matching keys while ignoring keys that don't exist.
$hash_dates[$dates]
Is this what you want?
$startdate = (get-date).AddDays(-30)
$today = get-date -format G
for($i = $startdate; $i -lt $today; $i=$i.AddDays(1))
{
$z = $i -split " "
$z = [datetime]$z[0]
Echo "Comparing $z to: "
$z = Get-Date $z
$hash_dates.$z
}

Powershell compare months and exclude which are not required

I have a text file as shown below. I need to preserve the files which are within 6 months old (from the previous month) and write every other content to other file which are more than 6 months old.
What I've done so far is like:
$array3 =
do {
foreach($monthl in $monthlookup)
{
$mnthl = $monthl -split '-'
$m_day = $mnthl[1]
$m_month = $mnthl[2]
$m_year = $mnthl[3]
$m_temp = 0
$prevmonth = (Get-Date).AddMonths(-1).ToString("dd-MM-yy")
while(($m_temp -eq "0"))
{
if(($m_month -ge $startmonth) -and ($m_month -le $prevmonth))
{
$monthl | Add-Content "C:\each_month_latest.txt"
break;
}else
{
$monthl | Add-Content "C:\exclusions.txt"
}
}
}
} until ($m_month -ge $m)
What the issue I identified here is like: If the current month is 1, then it wont go back to the last 6 months and check, as I use just strings here.
Any suggestions or code improvements, anyone of you can think of..? Would be really appreciated.
Edit
monthlookup will look like:
testdatabase-30-11-14-23-00
testdatabase-31-12-14-23-00
testdatabase-30-01-15-23-00
testdatabase-31-01-15-23-00
testdatabase-27-05-15-23-00
testdatabase-28-02-15-23-00
testdatabase-31-03-15-23-00
testdatabase-30-04-15-23-00
testdatabase-31-05-15-23-00
$m is $m = Get-Date -Format "MM"
Well, I don't completly understand what you want to do but here some tipps:
$prevmonth = (Get-Date).AddMonths(-1).ToString("dd-MM-yy") shouldn't be done each time within the foreach loop
You could extract the date using a simple regex: [regex]::Match('testdatabase-30-11-14-23-00', '^.*?-(\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$)').Groups[1].Value
Parse the date using [datetime]::ParseExact and a format string
So it could look like this:
# this doesn't have to be done each time in the foreach loop
$sixMonthBefore = (Get-Date).AddMonths(-6)
foreach($monthl in $monthlookup)
{
# extract the date
$dateString = [regex]::Match($monthl, '^.*?-(\d{2}-\d{2}-\d{2}-\d{2}-\d{2}$)').Groups[1].Value
# create a datetime using format string
$date = [datetime]::ParseExact($dateString, 'dd-MM-yy-HH-mm', $null)
if ($date.Month -eq (Get-Date).Month -and $date.Year -eq (Get-Date).Year)
{
Write-Host "$monthl is from this month"
}
elseif ($date -gt $sixMonthBefore)
{
$monthl | Add-Content "C:\each_month_latest.txt"
}
else
{
$monthl | Add-Content "C:\exclusions.txt"
}
}