54

我正在编写一个简单的脚本来在一定天数后删除 USMT 迁移文件夹:

## Server List ##
$servers = "Delorean","Adelaide","Brisbane","Melbourne","Newcastle","Perth"

## Number of days (-3 is over three days ago) ##
$days = -3

$timelimit = (Get-Date).AddDays($days)

foreach ($server in $servers)
{
    $deletedusers = @()
    $folders = Get-ChildItem \\$server\USMT$ | where {$_.psiscontainer}
    write-host "Checking server : " $server
    foreach ($folder in $folders) 
    {
        If ($folder.LastWriteTime -lt $timelimit -And $folder -ne $null)
        {
            $deletedusers += $folder
            Remove-Item -recurse -force $folder.fullname
        }
    }
        write-host "Users deleted : " $deletedusers
        write-host
}

但是我一直在击中可怕的Remove-Item : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

我一直在寻找解决方法和替代方案,但它们都围绕着我关心文件夹中的内容。

我希望有一个更简单的解决方案,因为如果文件夹内容被标记为删除,我并不真正关心它。

除了Remove-Item -recurse之外,是否有任何本机 Powershell cmdlet可以完成我所追求的目标?

4

17 回答 17

60

我经常遇到节点项目的这个问题。它们嵌套了它们的依赖项,一旦 git 克隆,就很难删除它们。我遇到的一个不错的节点实用程序是rimraf

npm install rimraf -g
rimraf <dir>
于 2015-11-13T11:51:50.523 回答
44

正如 CADII 在另一个答案中所说:Robocopy能够创建超过 260 个字符限制的路径。Robocopy 也能够删除此类路径。您可以在路径上镜像一些包含太长名称的空文件夹,以防您想删除它。

例如:

robocopy C:\temp\some_empty_dir E:\temp\dir_containing_very_deep_structures /MIR

这是了解参数和各种选项的Robocopy 参考。

于 2015-01-08T13:17:34.460 回答
24

我创建了一个 PowerShell 函数,该函数能够使用提到的robocopy 技术删除长路径 (>260) :

function Remove-PathToLongDirectory 
{
    Param(
        [string]$directory
    )

    # create a temporary (empty) directory
    $parent = [System.IO.Path]::GetTempPath()
    [string] $name = [System.Guid]::NewGuid()
    $tempDirectory = New-Item -ItemType Directory -Path (Join-Path $parent $name)

    robocopy /MIR $tempDirectory.FullName $directory | out-null
    Remove-Item $directory -Force | out-null
    Remove-Item $tempDirectory -Force | out-null
}

使用示例:

Remove-PathToLongDirectory c:\yourlongPath
于 2016-09-20T07:14:46.253 回答
22

SuperUser 上的这个答案为我解决了这个问题:https ://superuser.com/a/274224/85532

Cmd /C "rmdir /S /Q $myDir"
于 2013-08-16T07:24:11.477 回答
18

不久前我学到了一个技巧,它通常可以解决长文件路径问题。显然,当使用某些 Windows API 的某些功能时,将流经无法处理长文件名的遗留代码。但是,如果您以特定方式格式化路径,则可以避免遗留代码。解决这个问题的技巧是使用“\\?\”前缀来引用路径。应该注意的是,并非所有 API 都支持这一点,但在这种特殊情况下它对我有用,请参见下面的示例:

以下示例失败:

PS D:\> get-childitem -path "D:\System Volume Information\dfsr" -hidden


Directory: D:\System Volume Information\dfsr


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a-hs        10/09/2014  11:10 PM     834424 FileIDTable_2
-a-hs        10/09/2014   8:43 PM    3211264 SimilarityTable_2

PS D:\> Remove-Item -Path "D:\System Volume Information\dfsr" -recurse -force
Remove-Item : The specified path, file name, or both are too long. The fully qualified file name must be less than 260
characters, and the directory name must be less than 248 characters.
At line:1 char:1
+ Remove-Item -Path "D:\System Volume Information\dfsr" -recurse -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : WriteError: (D:\System Volume Information\dfsr:String) [Remove-Item], PathTooLongExcepti
on
+ FullyQualifiedErrorId : RemoveItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand

PS D:\>

但是,在路径前加上“\\?\”可以使命令成功运行:

PS D:\> Remove-Item -Path "\\?\D:\System Volume Information\dfsr" -recurse -force
PS D:\> get-childitem -path "D:\System Volume Information\dfsr" -hidden
PS D:\>
于 2014-09-11T07:49:22.270 回答
10

如果你安装了 ruby​​,你可以使用 Fileman:

gem install fileman

安装后,您只需在命令提示符下运行以下命令:

fm rm your_folder_path

当您在 Windows 上使用 node.js 进行开发时,这个问题确实令人头疼,因此 fileman 变得非常方便,可以偶尔删除所有垃圾

于 2014-07-15T02:43:22.237 回答
9

这是一个已知的限制PowerShell。解决方法是使用dircmd (对不起,但这是真的)。

http://asysadmin.tumblr.com/post/17654309496/powershell-path-length-limitation

或如 AaronH 回答所提到的,在此示例中使用 \?\ 语法来删除构建

dir -Include build -Depth 1 | Remove-Item -Recurse -Path "\\?\$($_.FullName)"
于 2013-05-06T06:19:50.433 回答
7

如果您所做的只是删除文件,我会使用一个函数来缩短名称,然后删除。

    function ConvertTo-ShortNames{
    param ([string]$folder)
    $name = 1
    $items = Get-ChildItem -path $folder
    foreach ($item in $items){
        Rename-Item -Path $item.FullName -NewName "$name"
        if ($item.PSIsContainer){
            $parts = $item.FullName.Split("\")
            $folderPath = $parts[0]
            for ($i = 1; $i -lt $parts.Count - 1; $i++){
                $folderPath = $folderPath + "\" + $parts[$i]
            }
            $folderPath = $folderPath + "\$name"
            ConvertTo-ShortNames $folderPath
        }
        $name++
    }
}

我知道这是一个老问题,但我想我会把它放在这里以防有人需要它。

于 2015-10-21T20:51:32.720 回答
3

有一种解决方法是使用基类库项目中的 Experimental.IO。你可以在poshcode上找到它,或者从作者的博客下载。260 限制源自.NET,因此要么是这个,要么是使用不依赖于 .NET 的工具(如cmd /c dir@Bill 建议的那样)。

于 2013-05-06T11:59:33.583 回答
2

工具组合效果最好,尝试使用 dir /x 来获取 8.3 文件名。然后,您可以将该输出解析为文本文件,然后构建一个 powershell 脚本来删除您输出文件的路径。陪你一分钟。或者,您可以将 8.3 文件名重命名为更短的名称,然后删除。

于 2016-06-07T20:59:23.670 回答
2

我的 Robocopy 在 1、2 和 3 中工作

  1. 首先创建一个空目录让我们说 c:\emptydir
  2. ROBOCOPY c:\emptydir c:\directorytodelete /purge
  3. rmdir c:\directorytodelete
于 2016-08-23T23:59:31.640 回答
1

PowerShell 可以很容易地与 AlphaFS.dll 一起使用来执行实际的文件 I/O 操作,而无需 PATH TOO LONG 的麻烦。

例如:

Import-Module <path-to-AlphaFS.dll>

[Alphaleonis.Win32.Filesystem.Directory]::Delete($path, $True)

有关此 .NET 项目,请参阅 Codeplex:https ://alphafs.codeplex.com/。

于 2014-09-09T10:21:46.490 回答
1

这已经过时了,但我最近不得不再次解决它。我最终使用了“subst”,因为它不需要在运行它的 PC 上提供任何其他模块或功能。便携一点。

基本上找到一个备用驱动器号,“替换”该字母的长路径,然后将其用作 GCI 的基础。

唯一的限制是 $_.fullname 和其他属性会将驱动器号报告为根路径。

似乎工作正常:

$location = \\path\to\long\
$driveLetter = ls function:[d-z]: -n | ?{ !(test-path $_) } | random

subst $driveLetter $location
sleep 1
Push-Location $driveLetter -ErrorAction SilentlyContinue
Get-ChildItem -Recurse

subst $driveLetter /D

该命令显然不是删除文件,而是可以替换。

于 2014-04-15T23:55:47.103 回答
1

我在尝试删除远程计算机上的文件夹时遇到了同样的问题。

没有什么帮助,但......我发现了一个窍门:

# 1:let's create an empty folder
md ".\Empty" -erroraction silentlycontinue

# 2: let's MIR to the folder to delete : this will empty the folder completely.
robocopy ".\Empty" $foldertodelete /MIR /LOG+:$logname 

# 3: let's delete the empty folder now:
remove-item $foldertodelete -force

# 4: we can delete now the empty folder
remove-item ".\Empty" -force

在本地或远程文件夹上像魅力一样工作(使用 UNC 路径)

于 2016-08-16T15:28:35.780 回答
0

Any thing developed using .NET out of the box will fail with paths too long. You will have to move them to 8.3 names, PInVoke (Win32) calls, or use robocopy

于 2014-09-19T16:18:51.177 回答
0

添加到 Daniel Lee 的解决方案中,当 $myDir 中间有空格时,考虑到从空间中拆分的文件集,它会给出 FILE NOT FOUND 错误。为了克服这个问题,请在变量周围使用引号并放置 powershell 转义字符以跳过 quatations。

PS>cmd.exe /C "rmdir /s /q <grave-accent>"$myDir<grave-accent>""

请用正确的重音字符代替<grave-accent>
SO 和我一起玩,我不能添加它:)。希望有人会更新它以便其他人容易理解

于 2014-02-25T00:51:20.213 回答
0

为了完整起见,我又遇到过几次,并结合使用“subst”和“New-PSDrive”在各种情况下解决它。

不完全是一个解决方案,但如果有人正在寻找替代方案,这可能会有所帮助。

Subst 似乎对您使用哪种类型的程序来访问文件非常敏感,有时它可以工作,有时它不工作,似乎与 New-PSDrive 相同。

于 2014-06-16T00:22:25.167 回答