删除目录,不pipe260个字符的限制
我正在编写一个简单的脚本来在一定天数之后删除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 : 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.
我一直在寻找解决办法和替代scheme,但他们都围绕着我关心文件夹中的内容。
我希望有一个更简单的解决scheme,因为如果它被标记为删除,我不关心文件夹的内容。
除了Remove-Item-recurse之外 ,是否有任何本机Powershell cmdlet可以完成我之后的操作?
这是PowerShell
一个已知限制。 解决方法是使用dir
cmd(对不起,但是这是真的)。
http://asysadmin.tumblr.com/post/17654309496/powershell-path-length-limitation
我经常遇到节点项目的这个问题。 他们嵌套他们的依赖,一旦git克隆,很难删除它们。 我碰到一个很好的节点工具是rimraf 。
npm install rimraf -g rimraf <dir>
正如CADII在另一个答案中所说: Robocopy能够创build超过260个字符限制的path。 Robocopy也能够删除这样的path。 您可以将包含太长名称的path中的某个空文件夹镜像到需要删除的位置。
例如:
robocopy C:\temp\some_empty_dir E:\temp\dir_containing_very_deep_structures /MIR
这里是Robocopy参考,以了解参数和各种选项。
超级用户的这个答案为我解决了它: https : //superuser.com/a/274224/85532
Cmd /C "rmdir /S /Q $myDir"
如果你安装了ruby,你可以使用Fileman:
gem install fileman
安装完成后,只需在命令提示符下运行以下命令即可:
fm rm your_folder_path
当你在Windows上的node.js中开发的时候,这个问题是一个真正的痛苦,所以fileman变得非常方便,在一段时间内删除所有的垃圾
我已经创build了一个PowerShell函数,可以使用提到的robocopy技术删除一个长path(> 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
前段时间我学到了一个技巧,经常解决长文件path问题。 显然,当使用某些Windows API时,某些function将stream经无法处理长文件名的遗留代码。 但是,如果以特定的方式格式化path,则可以避免遗留代码。 解决这个问题的技巧是使用“\\?\”前缀引用path。 应该指出的是,并不是所有的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:\>
但是,以“\\?\”为前缀的path使命令成功工作:
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:\>
如果你正在做的是删除文件,我使用一个函数来缩短名称,然后我删除。
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++ } }
我知道这是一个古老的问题,但我想我会把这里,以防万一需要它。
有一种解决方法使用基类库项目中的Experimental.IO。 你可以在poshcode上find它,或从作者的博客下载。 260的限制是从.NET派生的,所以它可能是这个,或者使用不依赖.NET的工具(比如cmd /c dir
,@Billbuild议)。
这已经老了,但我最近不得不再次解决它。 我结束了使用'subst',因为它不需要任何其他模块或function可用的PC上运行。 更便携一点。
基本上find一个备用驱动器盘符,'subst'是该信件的长path,然后用它作为GCI的基础。
唯一的限制是$ _。全名和其他属性将报告驱动器号作为根path。
似乎工作正常:
$location = \\path\to\long\ $driveLetter = ls function:[dz]: -n | ?{ !(test-path $_) } | random subst $driveLetter $location sleep 1 Push-Location $driveLetter -ErrorAction SilentlyContinue Get-ChildItem -Recurse subst $driveLetter /D
该命令显然不是删除文件,而是可以被replace。
工具的组合可以最好的工作,尝试做一个dir / x来取代8.3文件名。 然后,你可以parsing出输出到一个文本文件,然后build立一个PowerShell脚本来删除你out-file'd的path。 带你一分钟。 或者,您可以将8.3文件名重命名为更短,然后删除。
添加到Daniel Lee的解决scheme中,当$ myDir在中间有空格时,考虑到从空间分割的一组文件,会给出FILE NOT FOUND错误。 为了克服这个使用引用周围的variables,并把PowerShell的转义字符跳过quatations。
PS>cmd.exe /C "rmdir /s /q <grave-accent>"$myDir<grave-accent>""
请replace适当的重音字符而不是<grave-accent>
所以和我玩,我不能添加它:)。 希望有人会更新为他人易于理解
为了完整性,我再次遇到了这个问题,并且在各种情况下使用了“subst”和“New-PSDrive”的组合来解决这个问题。
不完全是一个解决scheme,但如果有人正在寻找替代品,这可能会有所帮助
Subst似乎对你用来访问这些文件的程序types非常敏感,有时候它有用,有时不起作用,似乎和New-PSDrive一样。
PowerShell可以轻松地与AlphaFS.dll一起使用来做实际的文件I / O的东西,没有PATH太长的麻烦。
例如:
Import-Module <path-to-AlphaFS.dll> [Alphaleonis.Win32.Filesystem.Directory]::Delete($path, $True)
请参阅Codeplex: https ://alphafs.codeplex.com/这个.NET项目。
任何使用.NET开发的东西都会失败,path太长。 您将不得不将它们移动到8.3名称 , PInVoke(Win32)调用或使用robocopy
在尝试删除远程计算机上的文件夹时遇到同样的问题。
没有什么帮助,但…我发现一个窍门:
“———————————————–
'#1:让我们创build一个空文件夹
md“。\ Empty”-erroraction默默继续
'#2:让我们MIR到要删除的文件夹:这将完全清空文件夹。
robocopy“。\ Empty”$ foldertodelete / MIR / LOG +:$ logname
'#3:让我们现在删除空文件夹:
remove-item $ foldertodelete -force
'#4:我们现在可以删除空文件夹
删除项目“。\空”的力量
“——————————
像本地或远程文件夹上的魅力一样工作(使用UNCpath)
我的Robocopy在1,2和3工作
- 首先创build一个空目录,让我们说c:\ emptydir
- ROBOCOPY c:\ emptydir c:\ directorytodelete / purge
- rmdir c:\ directorytodelete