【问题标题】:Cannot find path when using remove-item cmdlet使用 remove-item cmdlet 时找不到路径
【发布时间】:2019-09-19 13:43:40
【问题描述】:

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

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

下面是sn-p:

    $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 等。

当我为$Folder 执行Write-Host 时,它会正确列出SubFolderASubFolderB 等,所以我不确定为什么会收到Cannot find path 错误。

【问题讨论】:

  • 那你为什么要那样做?为什么不只是 Remove-Item -Recurse -Force $targetfolder?
  • 我不想删除 $TargetFolder 中的所有内容。我只想删除已达到特定年龄的备份文件夹。这是脚本。 @4c74356b41 code $Now = Get-Date $Days = "5" $TargetFolder = "C:\Folder\" $LastWrite = $Now.AddDays(-$Days) $Folders = get-childitem -path $TargetFolder | Where {$_.psIsContainer -eq $true} | Where {$_.LastWriteTime -le "$LastWrite"} foreach ($Folder in $Folders) { Remove-Item -path $Folder -Recurse -Force } code`
  • 好的,首先你会想要使用 get-childitem -directory,以避免另一个管道。调用 $now.adddays 也没有任何意义,直接调用 (Get-Date).AddDays。另外,尝试在删除项目中使用 $folder.fullname
  • 你应该edit your code into your question。 IMO 您提供的代码示例只说明了您想要做的事情的一半,而且,如果您展示整个图片,您可能会得到更好的帮助。

标签: powershell


【解决方案1】:

看来你是想在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
    }
}

【讨论】:

  • 感谢更新;实际上,PowerShell 变量通常不需要双引号作为参数(除非它们要嵌入 双引号字符串中),即使它们包含空格。因此,Remove-Item $Folder.FullName 工作得很好。
【解决方案2】:

tl;dr

为确保Remove-Item 正确识别Get-ChildItem 返回的目录对象([System.IO.DirectoryInfo] 类型的实例):

  • Windows PowerShell 中将对象作为 参数 值(参数)传递(不再在 PowerShell Core em>) 您必须使用.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 时明确识别文件系统对象作为参数 转换为字符串,它的完整路径必须指定。

    • 注意:下面描述的仅情景文件名字符串化只影响Windows PowerShell幸运的是,问题已经幸运的是,已在 PowerShell Core 中修复。

    • 在手头的情况下,假设$Folder 包含Get-ChildItem 返回的[System.IO.DirectoryInfo] object$Folder.FullName 是最简单的(但通过在前面加上 @ 来构造路径987654342@ 也可以)。

    • 在 Windows PowerShell 中,即使 $Folder 是包含完整路径信息的 [System.IO.DirectoryInfo] 对象,当转换为 字符串 时,它 situationally 可能只会扩展到它的目录 name(最后一个路径组件) - 这取决于如何获得 [System.IO.DirectoryInfo][System.IO.FileInfo]instances,即:
      如果Get-ChildItem 被调用没有路径参数或通过路径参数是一个目录,输出对象字符串化为它们的文件/目录名称
      - 详情请参阅this answer
      简单示例:$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 以执行实际删除。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 可行,但使用$Folder.FullName 更简单。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 2021-11-09
    • 2017-09-07
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    相关资源
    最近更新 更多