0

I have a bunch of directories on my file servers that are ridiculously long: think 2,000 directories and 20,000+ characters deep.

There are tons of articles and strategies using Robocopy (w/purge or mir) to get rid of these--none of them worked.

I'm using PowerShell with the Windows API to both recursively get the deepest parts of the path and to delete the contents (using the 'wide' versions of the relevant functions).

So the process I'm performing is:

  1. Get a recursive list of all of the directory paths of the offending deep target
  2. Loop through the list (backwards) and RemoveDirectory() each path

The problem I'm running into is that the Kernel32, RemoveDirectory() function appears to be horrendously slow for some reason.

Am I doing something wrong or is the slowness due to the depth of the directory or something else someone could help with?

Add-Type -TypeDefinition $filesearcher

$delete = @'
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool RemoveDirectory(string path);
'@

Add-Type -MemberDefinition $delete -Name 'Kernel32'

#[Reflection.Assembly]::LoadWithPartialName('System.Collections.Generic')


$f = @()
$d = @()

$d1 = "\\?\C:\temp\temp"
if (([FileSearcher]::FindNextFilePInvokeRecursiveParalleled($d1, [ref]$f, [ref]$d))) 
{
    for ($i=($d.Count-1); $i -gt 0; $i--) {

        "$($d.Count - ($d.Count - $i))/$($d.Count)"
        if (![Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes.Kernel32]::RemoveDirectory($d[$i].FullName)) {
            break
        }
    }
}

How I'm creating the horrendously deep directory as a test-case:

mkdir 'C:\temp2'

$p = 'C:\temp'
0..5000 | % { $p += '\temp' }

.\Robocopy.exe c:\temp2 $p /MIR /E
thepip3r
  • 2,855
  • 6
  • 32
  • 38
  • Why do you need to write the recursion yourself? Just remove the top level folder. – David Heffernan Dec 04 '19 at 21:42
  • RemoveDirectory only works on empty directories so since the root has 5000 children, AFAIK, I have to recurse in reverse to delete them level by level. – thepip3r Dec 04 '19 at 21:43
  • del /s works fine, no need for powershell. But if you must use powershell, and perhaps cmd doesn't like long names, then the dupe shows you what to do. – David Heffernan Dec 04 '19 at 22:39
  • I will have to test this tomorrow but this whole exercise it's centered around pads that are too deep for the common tools. I'll test it tomorrow and get back. – thepip3r Dec 04 '19 at 23:20
  • In Win10 you can enable long filepaths: https://betanews.com/2016/05/29/long-paths-windows-10/ and together with the -literalpath switch in Powershell this would allow you to delete long paths and those with strange characters much easier - just use a Win10 machine to remotely do the work. – Scepticalist Dec 05 '19 at 08:23
  • @DavidHeffernan del /s doesn't work for deep paths. Why was this closed? The linked article isn't valid for my situation and my question hasn't been answered. – thepip3r Dec 05 '19 at 14:20
  • @Scepticalist -- A win10 answer would be great if that were the OS involved. This is occurring on Windows 2008 R2 and Windows 2012 R2. – thepip3r Dec 05 '19 at 14:21
  • Then use a Win10 machine to remove the folders remotely? – Scepticalist Dec 05 '19 at 15:39
  • Why not Linux? Would serve the same function of being able to accomplish what I can't in my current environment with available OS's. – thepip3r Dec 05 '19 at 16:28
  • Pretty sure the duplicate is accurate. – David Heffernan Dec 05 '19 at 18:35
  • @DavidHeffernan, please recreate the 25,000 path with the code I supplied above and test whether 'rd' or 'Remove-Item' works -- they're both limited by the 260 character paths on pre-Win10 and Win10 without long-path support. – thepip3r Dec 05 '19 at 18:41
  • The duplicate is about the question. Is it the same question? – David Heffernan Dec 05 '19 at 22:16
  • No -- the specified-duplicate is just about a simple recursive directory delete. Mine is about deleting things beyond the MAX_PATH limit. – thepip3r Dec 06 '19 at 15:03
  • just a thought, I use 7zip with the delete option after packing an archive then I delete the archive. It works from command line also. – jetstreamin Mar 05 '20 at 20:40
  • @jetstreamin, while I appreciate the comment, I work in an environment where we can't sideload any app without a huge bureaucratic nightmare--even for awesome apps like 7-zip. I had a way via Robocopy that worked fine for directories that were > 260 limit but something < MAX_PATH. Meaning somewhere towards the latter end of the spectrum of the Unicode path limit, Robocopy fails for some reason. Thus, I had to attempt to resolve this myself as it was hindering other apps that were trying to read the share (backup, migration software, etc.). For clarification, the above worked, was just slow – thepip3r Mar 06 '20 at 15:57

0 Answers0