openlang

-WhatIf cleanup script says 13 expired archives but I only have 9 files total

tidying old backup archives on my fedora laptop (pwsh 7.4, emacs, and yes this is becoming a demo for my class). the script finds *.tar.gz older than KeepDays under ~/srv/archives and removes them, and i run it with -WhatIf first because i'm not an animal.

the folder has 9 archives across 3 subfolders. by hand i count 4 older than 30 days. the log says found 13 expired archives. then the foreach prints a few proper What if: Performing the operation "Remove archive" on target ... lines, but in between it dies with The property 'FullName' cannot be found on this object. Verify that the property exists. on the $item.FullName line.

i figured strict mode was being fussy about FileInfo, so i commented out Set-StrictMode -Version Latest. errors gone, count still 13. Get-ChildItem ... | Measure-Object by hand gives 9, which is right. so where do the extra 9 "items" come from, and why do only some blow up? (i can't paste a transcript right now, this is from memory of the terminal.)

the function in lib/Retention.ps1:

$cutoff = (Get-Date).AddDays(-$KeepDays)
$seenDirs = [System.Collections.Generic.HashSet[string]]::new()
$expired = [System.Collections.Generic.List[System.IO.FileInfo]]::new()

foreach ($f in Get-ChildItem -Path ... -Recurse -File -Filter '*.tar.gz') {
    $seenDirs.Add($f.DirectoryName)
    if ($f.LastWriteTime -lt $cutoff) {
        $expired.Add($f)
    }
}

Write-Verbose "scanned $($seenDirs.Count) directories"
return $expired

and in the main script:

$expired = Find-ExpiredArchives -Root $root -KeepDays $KeepDays
Write-LogLine "found $($expired.Count) expired archives"

foreach ($item in $expired) {
    if ($PSCmdlet.ShouldProcess($item.FullName, 'Remove archive')) {
        Remove-Item -LiteralPath $item.FullName
        $freed += $item.Length
    }
}

is -Recurse with -Filter doing something weird, or is the lib file getting loaded twice?

The conversation continues 2

Follow the reasoning
  1. Permalink

    Side point, since this is going to be a class demo: be careful with the word "script". lib/Retention.ps1 holds a function, and -WhatIf only exists on your main script because it declares [CmdletBinding(SupportsShouldProcess)]. It's not magic. Students get confused there. And "not an animal" is a good line for the slides, by the way.

Other sides of the same question

  1. httptest Server.Close hangs, and no failure message from my test

    Is it possible that httptest.Server.Close hangs on Go 1.23 with keep-alive? I run go test -timeout 5s ./... and the new test…

    Replies 3Latest activity go
  2. My init set fill-column for exactly one buffer

    Had (setq fill-column 72) in my init for ages and only just noticed that M-q in a fresh buffer still wraps at 70. (In *scratc…

    Replies 3Latest activity emacs-lisp
  3. SilentlyContinue is On Error Resume Next with better spelling

    Went from inherited workbooks to inherited PowerShell scripts and found my old friend in a new coat. -ErrorAction SilentlyCon…

    Replies 0Latest activity powershell