使用remove-item cmdlet

时间:2016-11-08 16:14:05

标签: powershell

我写了一个简单的PowerShell脚本,它将目录备份到C:\,然后在其年龄= X天时删除任何备份文件夹。

出于某种原因,当我使用Remove-Item cmdlet时,我收到Remove-Item: Cannot find path 'C:\Windows\system32\ [Sub-Folder name]' because it does not exist错误。

以下是摘录:

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

$TargetFolder = "C:\Folder\"内,有一些子文件夹。 示例:C:\Folder\SubfolderAC:\Folder\SubfolderB等。

当我为Write-Host $Folder SubFolderA时,它会正确列出SubFolderBCannot find path等,所以我不确定为什么我会这样做收到class ApiService { class func getExerciseData(completion: @escaping ([[String: AnyObject]]) -> ()) { Alamofire.request("https://wger.de/api/v2/exercise/?format=json").responseJSON { (responseData) -> Void in guard let jsonResponse = responseData.result.value else { //possibly put some sort of protection, or what you want to do if there is not a response here return } //instead of creating a variable for swiftyJsonVar in this class, //you want to use a completion to send the array of dictionaries to the tableview asynchronously, //that way it doesn't load blank //I'm not super familiar with swifty json(sorry). What I normally do is below. let swiftyJsonVar = JSON(jsonResponse) guard let dictArray = swiftyJsonVar["exercise"].arrayObject as? [[String: AnyObject]] else { //some sort of protection here if this fails return } completion(dictArray) } } 错误。

3 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:2)

尝试在完整路径上执行remove-item,例如

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

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

答案 2 :(得分: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是包含完整路径信息的[System.IO.DirectoryInfo]对象,也会转换为字符串 情境可能只会扩展到其目录 name (最后路径组件) - 它取决于[System.IO.DirectoryInfo][System.IO.FileInfo]实例的方式获得,即:
      如果Get-ChildItem被调用没有路径参数或通过路径参数目录,则输出对象将字符串化为其纯文件/目录名。< /强>
      简单示例:$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以执行实际删除。