无论260 char限制,都删除目录

时间:2013-05-06 05:57:18

标签: powershell limit

我正在写一个简单的脚本,在一定时间后删除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可以完成我所追求的目标?

17 个答案:

答案 0 :(得分:54)

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

npm install rimraf -g
rimraf <dir>

答案 1 :(得分:36)

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

例如:

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

以下是了解参数和各种选项的Robocopy reference

答案 2 :(得分:22)

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

Cmd /C "rmdir /S /Q $myDir"

答案 3 :(得分:13)

我创建了一个PowerShell功能,可以使用上面提到的 robocopy技术删除长路径(&gt; 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

答案 4 :(得分:11)

我刚才学会了一个技巧,通常可以解决长文件路径问题。显然,当使用某些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:\>

答案 5 :(得分:10)

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

gem install fileman

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

fm rm your_folder_path

当你在Windows上的node.js中进行开发时,这个问题真的很痛苦,所以fileman在一段时间内删除所有垃圾变得非常方便

答案 6 :(得分:9)

这是PowerShell的已知限制。解决方法是使用dir cmd(对不起,但这是真的)。​​

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

或者如Aaron所述,回答使用\?\语法在此示例中删除构建

dir -Include build -Depth 1 | Remove-Item -Recurse -Path "\\?\$($_.FullName)"

答案 7 :(得分:5)

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

    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++
    }
}

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

答案 8 :(得分:3)

有一种解决方法使用Base Class Libraries项目中的Experimental.IO。您可以在poshcode上找到它,或从author's blog下载。 260限制来自.NET,所以它或者是这个,或者使用不依赖于.NET的工具(如cmd /c dir,如@Bill建议的那样。)

答案 9 :(得分:1)

PowerShell可以轻松地与AlphaFS.dll一起使用来执行实际的文件I / O操作 没有太多的麻烦。

例如:

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

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

请参阅Codeplex:https://alphafs.codeplex.com/了解这个.NET项目。

答案 10 :(得分:1)

这已经老了,但我最近不得不再次解决它。我最终使用了&#39; subst&#39;因为它不需要在PC上运行的任何其他模块或功能。更便携一点。

基本上找一个备用驱动器号,&#39; subst&#39;这条信的长路,然后用它作为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

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

答案 11 :(得分:1)

工具的组合可以效果最好,尝试使用dir / x来获取8.3文件名。然后,您可以将该输出解析为文本文件,然后构建一个PowerShell脚本,以删除您提交的文件。请你花一点时间。或者,您可以将8.3文件名重命名为更短的内容,然后删除。

答案 12 :(得分:1)

我的Robocopy工作在1,2和3

  1. 首先创建一个空目录,例如c:\ emptydir
  2. ROBOCOPY c:\ emptydir c:\ directorytodelete / purge
  3. rmdir c:\ directorytodelete

答案 13 :(得分:0)

为了完整起见,我已经多次遇到过这种情况,并且在各种情况下使用'subst'和'New-PSDrive'的组合来解决它。

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

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

答案 14 :(得分:0)

使用.NET开发的任何东西都会因路径太长而失败。您必须将它们移至8.3 namesPInVoke (Win32) calls或使用robocopy

答案 15 :(得分:0)

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

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

请替换正确的重音字符而不是<grave-accent> 我和我玩,我不能添加它:)。希望有人会更新它以便其他人轻松理解

答案 16 :(得分:0)

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

没有任何帮助,但......我找到了一个技巧:

# 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路径)