I’ve written a Powershell script that would periodically delete folders on my machine.
The algorithm is as follows:
- Drill down into each directory structure to the lowest subfolders
- Check the creation date of the subfolder
- If it’s 14 days old, or older, delete it
- LOG EVERYTHING (not part of the algorithm, just good practise)
When running, it operates exactly as expected…
… Except it throws the following, non-terminating exception:
Get-ChildItem : Could not find a part of the path 'C:\foo\baz'.
At C:\src\CoreDev\Trunk\Tools\BuildClean script\buildclean.ps1:55 char:15
+ Get-ChildItem <<<< -recurse -force |
+ CategoryInfo : ReadError: (C:\foo\baz:String) [Get-ChildItem],
DirectoryNotFoundException
+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChil
dItemCommand
Why is this happening? More importantly, how can I remove it, and will it cause an issue?
The script is as follows:
# folderclean.ps1
# This script will remove each leaf node of a directory, provided that leaf is over
# 14 days old.
# CONSTANT DECLARATIONS
# testing (run on my local machine)
$proj_loc = "C:\foo", "C:\bar"
$logpath = "C:\Logs\BuildClean\$(Get-Date -format yyyyMMdd).log"
function Write-ToLogFile {
param ([string]$stringToWrite)
Add-Content $logpath -value $stringToWrite
}
# Function to check if a folder is a leaf folder.
# First, retrieve the directory $item is pointing to
# Then, create a list of children of $item that are folders
# If this list is either empty or null, return $true
# Otherwise, return $false
function Folder-IsLeaf($item) {
$ary = Get-ChildItem $item -force | ?{ $_.PSIsContainer }
if (($ary.length) -eq 0 -or $ary -eq $null) {
return $true
}
return $false
}
# Deletes leaf folders that are older than a certain threshhold.
# Get a list of children of the folder, where each child is a folder itself and
# was created over 14 days ago and the folder is a leaf
# For each of these children, delete them and increment $folderCount
# Get a list of children of the folder, where each child is a folder itself and
# was last modified over 14 days ago and the folder is a leaf
# For each of these children, delete them and increment $folderCount
function Remove-LeafFolders($path) {
$createdCount = 0
$modifiedCount = 0
Write-ToLogFile "Operation started at $(Get-Date -format "dd/MM/yyyy hh:mm:ss.fff")"
Write-ToLogFile "Looking in $proj_loc"
Write-ToLogFile ""
$start = $(Get-Date)
$proj_loc |
Get-ChildItem -recurse -force |
?{
$_.PSIsContainer -and ($_.CreationTime).AddDays(15) -lt $(Get-Date) -and $(Folder-IsLeaf $_.FullName) -eq $true
} | %{
$formattedDate = $($_.CreationTime).ToString("dd/MM/yyyy hh:mm:ss");
Write-ToLogFile "Folder $($_.FullName) is being removed; created: $formattedDate"
Remove-Item $_.FullName -recurse;
$createdCount += 1
}
$end = $(Get-Date)
$elapsed = $end - $start
Write-ToLogFile "Operation completed at $(Get-Date -format "dd/MM/yyyy hh:mm:ss.fff")."
Write-ToLogFile "Folders removed: $createdCount"
Write-ToLogFile "Time elapsed: $(($elapsed).TotalMilliseconds) ms"
Write-ToLogFile "-------------------------------"
}
Remove-LeafFolders($proj_loc)
I found this other StackOverflow question, and, after looking through the answer, I realised that the problem was the pipeline. So, I changed my code as follows:
I created a few local folders and screwed around with them. No exceptions cropped up, so this appears to have worked: