2012-12-07 18 views
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) 

回答

0

我發現this other StackOverflow question,並通過尋找答案後,我意識到這個問題是管道。所以,我改變了我的代碼如下:

... 
$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 
------------------------------- 
-1

,我認爲它會更容易使用自下而上的方法來完成這種遞歸刪除的,而不是自上而下這正是GET-ChildItem給你默認。試試這個:

$proj_loc | 
    Get-ChildItem -recurse -force -Name | sort -desc | Get-Item | 
    ? { .... 
    } 
+0

我創建了幾個文件夾,並試圖此,與我目前擁有該位置對象命令的代碼替換「......」。結果是一個「無法找到路徑」例外刪除。 – KBKarma