2016-11-08 25 views
1

我寫了一個簡單的powershell腳本,用於將目錄備份到C:\,然後在其年齡= X天時刪除任何備份文件夾。出於某種原因,當我使用remove-item cmdlet時,出現「Remove-Item:Can not find path'C:\ Windows \ system32 \ [Sub-Folder name]',因爲它不存在」錯誤。Powershell - 使用remove-item cmdlet時找不到路徑

下面是摘錄:

$TargetFolder = "C:\Folder\" 
    $Folders = get-childitem -path $TargetFolder 
    foreach ($Folder in $Folders) 
    { 
     remove-item $Folder -recurse -force 
    } 

內$ TargetFolder = 「C:\文件夾\」 有幾個子文件夾。 例如: 「C:\文件夾\ SubfolderA」, 「C:\文件夾\ SubfolderB」 等

當我寫主機$文件夾它列出SubFolderA,SubFolderB等,正確的,所以我不完全確定爲什麼我得到「無法找到路徑」錯誤。

任何援助非常感謝。謝謝。

+0

那麼你爲什麼這樣做呢?爲什麼不只是Remove-Item -Recurse -Force $ targetfolder? – 4c74356b41

+0

我不想刪除$ TargetFolder中的所有內容。我只想刪除已達到特定年齡的備份文件夾。這是腳本。@ 4c74356b41 '代碼 $現在=獲取最新 $天= 「5」 $ TargetFolder = 「C:\文件夾\」 $ LastWrite = $ Now.AddDays( - $天) $文件夾= GET -childitem -path $ TargetFolder | 其中{$ _。psIsContainer -eq $ true} | 其中{$ _。LastWriteTime -le 「$ LastWrite」} 的foreach($文件夾中$文件夾) { \t刪除,項目-path $文件夾-Recurse -Force } 'code' – Mike

+0

OK,首先所有你想要使用get-childitem -directory,以避免另一個管道。也沒有意義調用$ now.adddays,直接調用(Get-Date).AddDays。此外,嘗試在刪除項目 – 4c74356b41

回答

5

看來你想在LastWriteTime目錄的基礎上做到這一點,但是你沒有提到Get-ChildItem上的-Directory。

[cmdletbinding()] 
Param() 

$TargetFolder = "C:\Users\lit\Documents" 
$Folders = Get-ChildItem -Path $TargetFolder -Directory 
$Days = 80 

foreach ($Folder in $Folders) { 
    if ($Folder.LastWriteTime -lt (Get-Date).AddDays(-$Days)) { 
     Write-Verbose "Deleting directory $($Folder.FullName)" 
     Remove-Item -WhatIf "$($Folder.FullName)" -Recurse -Force 
    } 
} 
+0

感謝您的更新;實際上,PowerShell變量通常不需要雙引號作爲參數(除非它們被嵌入在雙引號字符串中),即使它們包含空格。因此,'Remove-Item $ Folder.FullName'工作得很好。 – mklement0

+0

這工作。謝謝您的幫助! – Mike

2

嘗試在完整路徑上執行remove-item,例如,

$TargetFolder = "C:\Folder\" 
    $Folders = get-childitem -path $TargetFolder 

    foreach ($Folder in $Folders) 
    { 
     remove-item $TargetFolder$Folder -recurse -force 
    } 
+0

這也適用。謝謝您的幫助! – Mike

+0

工作,但使用'$ Folder.FullName'更簡單。 – mklement0

2

TL;博士

爲了確保Remove-Item正確地標識爲返回由Get-ChildItem[System.IO.DirectoryInfo]類型的實例)的一個目錄對象:

  • 當通過對象如一個參數值(參數),你必須使用.FullName

    Remove-Item -LiteralPath $Folder.FullName ... # !! Note the need for .FullName 
    

-LiteralPath並不是必需的,但更強大的選擇,因爲Remove-Item $Folder.FullName隱式綁定到-Path參數代替,後者解釋其參數爲通配符表達式;往往這不會有什麼區別,但它可以

  • 當使用管道,你可以通過對象原樣

    Get-ChildItem -Directory | Remove-Item ... 
    

令人驚訝的需要使用.FullName是一家集設計怪癖的結果;結果的行爲及其影響將在下面討論;已在this GitHub issue中提出了修復方案。


Liturgist's helpful answerAJK's helfpul answer包含解決方案的配套件(Liturgist的答案已經被修改,以提供一個完整的解決方案):

  • 來限制Get-ChildItem返回目錄(文件夾),您必須使用-Directory(PSv3 +)。

  • 爲了將它傳遞給Remove-Object作爲參數被轉換到一個,必須指定其完整路徑時明確地識別一個文件系統對象。

    • 在手頭的情況下,考慮到$Folder包含[System.IO.DirectoryInfo]對象Get-ChildItem返回,$Folder.FullName是最簡單的(但在前面加上$TargetPath構建路徑也工作)。

    • 注意,即使$Folder是一個對象,它確實包含全路徑信息,當轉換爲一個它僅擴展到僅僅文件名(最後一個路徑組件) - 簡單的例子:$d = (Get-ChildItem -Directory $HOME)[0]; "$d"產量Contacts,例如,不是C:\Users\jdoe\Contacts
      相反,如果您通過管道Remove-Item傳遞此類對象,PowerShell將使用完整路徑。

    • 重要:如果你傳遞目標文件夾作爲參數和忽視指定的完整路徑而不是在相同的位置,目標文件夾,名稱被解釋爲相對當前的位置,你會得到一個Cannot find path錯誤 - 正如你所看到的 - 或者更糟的是,如果碰巧出現在你當前的位置(目錄)中,你最終可能會刪除一個不同的文件夾。 。

如前所述,您可以通過管道文件夾對象由Get-ChildItem回到Remove-Item,這也使得更多的優雅,單管道解決方案(PSv3 +)避免全路徑問題:

$TargetFolder = "C:\Folder" 
$Days = 5 
Get-ChildItem -Directory $TargetFolder | 
    Where-Object LastWriteTime -lt (Get-Date).Date.AddDays(-$Days) | 
    Remove-Item -WhatIf -Force -Recurse 

刪除-WhatIf以執行實際刪除操作。