0

我编写了一个 Powershell 脚本,它会定期删除我机器上的文件夹。算法如下:

  • 深入每个目录结构到最低的子文件夹
  • 检查子文件夹的创建日期
  • 如果是 14 天或更早,请将其删除
  • 记录一切(不是算法的一部分,只是好的做法)

运行时,它完全按预期运行......

...除了它抛出以下非终止异常:

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

为什么会这样?更重要的是,我怎样才能删除它,它会引起问题吗?

脚本如下:

# 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)
4

2 回答 2

0

我发现了另一个 StackOverflow 问题,在查看了答案后,我意识到问题出在管道上。所以,我改变了我的代码如下:

...
$leafList = $proj_loc | 
    Get-ChildItem -recurse -force | 
    ?{

        $_.PSIsContainer -and ($_.CreationTime).AddDays(15) -lt $(Get-Date) -and $(Folder-IsLeaf $_.FullName) -eq $true
    }

    Foreach ($folder in $leafList)
    {
        $formattedDate = $($folder.CreationTime).ToString("dd/MM/yyyy hh:mm:ss");
        Write-ToLogFile "Folder $($folder.FullName) is being removed; created: $formattedDate"
        Remove-Item $folder.FullName -recurse;
        $createdCount += 1
    }
...

我创建了一些本地文件夹,并搞砸了它们。没有出现异常,所以这似乎奏效了:

Operation started at 10/12/2012 05:16:18.631
Looking in C:\foo C:\bar

Folder C:\foo\baz is being removed; created: 09/01/2010 02:00:00
Folder C:\bar\baz3\recursion is being removed; created: 01/01/2008 01:00:00
Operation completed at 10/12/2012 05:16:18.748.
Folders removed: 2
Time elapsed: 33.0033 ms
-------------------------------
Operation started at 10/12/2012 05:41:59.246
Looking in C:\foo C:\bar

Folder C:\foo\baz2\NewFolder is being removed; created: 10/10/2010 10:10:10
Folder C:\bar\baz3\barbar is being removed; created: 20/11/2012 05:37:38
Operation completed at 10/12/2012 05:41:59.279.
Folders removed: 2
Time elapsed: 21.0021 ms
-------------------------------
于 2012-12-10T17:43:32.550 回答
-1

我认为使用自下而上的方法完成这种递归删除会更容易,而不是 Get-ChildItem 默认为您提供的自上而下。试试这个:

$proj_loc | 
    Get-ChildItem -recurse -force -Name | sort -desc | Get-Item |
    ? { ....
    }
于 2012-12-10T17:12:06.700 回答