AJF
AJF

Reputation: 1931

Anomaly in powershell script doesn't make sense

We have a SQL Server on a Windows 2016 server that creates a SQL Server backup of the .MDF and Log files once a weekday basis scheduled for 23:30. I created a housekeeping script to start deleting these .bak files that are older than two working days.

However, the check for a Tuesday, functions with an anomaly. In the script below the part AddDays(4) retains files for Monday, Friday AND Thursday instead of Monday and Friday only. But if I change this to AddDays(3) it ONLY retains Monday's files.

Why is this behaving like this?

# Determine day of week
$weekDay = (get-date).DayOfWeek.ToString()
$firstAbbrevCheck = $weekDay.SubString(0,3)
# write-host $firstAbbrevCheck
# Write date to log file to ensure sripts ran
$todaysDate = (get-date).ToString("ddMMyyyy")
Write-output $todaysDate | Out-file <path>\HouseKeepLog.txt -append
# If not a sunday or Monday then process
if($firstAbbrevCheck -ne "Sun") {
  if($firstAbbrevCheck -ne "Mon") {
    $secondAbbrevCheck = $weekDay.SubString(0,2)
    # If retaining two work days of backups then for Tuesday delete 
      files greater than 4 days old
    if($secondAbbrevCheck -eq "Tu") {
     Get-ChildItem –Path <Path to backup folder> -recurse -Filter 
       *.bak -exclude master*, msdb* | Where-Object 
      {($_.LastWriteTime -lt (Get-Date).AddDays(-4))} | Remove-Item
    }
    else {
    # Else Wed - Sat and delete files greater than 2 days old 
    Get-ChildItem –Path <Path to backup folder> -recurse -Filter 
      *.bak -exclude master*, msdb* | Where-Object 
      {($_.LastWriteTime -lt (Get-Date).AddDays(-2))} | Remove-Item
    }
  }
 }  

Upvotes: 1

Views: 112

Answers (3)

wasif
wasif

Reputation: 15518

You can also use UFormat. Here's how:

$today = Get-Date 
$wd = Get-Date -UFormat "%A"
Write-output ('{0:ddMMyyyy}' -f $today >><path>\HouseKeepLog.txt
if (($wd -notmach "Su.*") -and ($wd -notmatch "Mo.*")) {
   $rd = switch -Regex ($wd) {
     "Tu.*" { $today.AddDays(-4).Date }    
     default { $today.AddDays(-2).Date }
    }
 Get-ChildItem "Path to backup folder" -Recurse -Filter "*.bak" -Exclude "master*", "msdb*" -File | 
            Where-Object {($_.LastWriteTime -lt $rd)} | 
            Remove-Item
}

Upvotes: 1

js2010
js2010

Reputation: 27606

"Tu" not "Tue"? Btw you can compare enums with strings:

(get-date).dayofweek -eq 'saturday'
True

'saturday' -eq (get-date).dayofweek
True

Fyi, here's how the dayofweek enum is laid out:

(get-date).dayofweek.gettype()               

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DayOfWeek                                System.Enum

0..6 | foreach { [system.dayofweek]$_ } 

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Upvotes: 0

Theo
Theo

Reputation: 61253

Why do the manual abbreviations at all and not use the int number from the dayofweek
(0 --> Sunday, 6 --> Saturday)? This will make for shorter code AND you don't have to worry about locale weekday names.

# Determine day of week
$today   = Get-Date
$weekDay = [int]$today.DayOfWeek   # today's weekday: 0 --> Sunday, 6 --> Saturday

# Write date to log file to ensure sripts ran
Write-output ('{0:ddMMyyyy}' -f $today) | Out-file <path>\HouseKeepLog.txt -append
# If not a sunday or Monday then process
if ($weekDay -gt 1) {
    # use '.Date' to strip off the time part, effectively return the date at midnight
    $refDate = switch ($weekDay) {
        2 { $today.AddDays(-4).Date }        # Tuesday:   delete files greater than 4 days old
        default { $today.AddDays(-2).Date }  # Wed..Sat:  delete files greater than 2 days old
    }
    Get-ChildItem –Path '<Path to backup folder>' -Recurse -Filter '*.bak' -Exclude 'master*', 'msdb*' -File | 
        Where-Object {($_.LastWriteTime -lt $refDate)} | 
        Remove-Item -WhatIf
}

P.S. remove or comment out the -WhatIf switch if you are satisfied with the results shown in the console

Upvotes: 0

Related Questions