Working around long file and folder names with ICACLS and TAKEOWN
I currently deal with a client which has an extremely organized file structure which we inherited. So organized in fact that there are folder trees seven levels deep, that contain only a single document at the very end of the tree, and nothing else in any other level. The problem we’ve encountered is that some of these files become completely inaccessible via many applications. You can drill down 20 levels, and then you start encountering access denied and File not found, errors. Add to this, attempting to take ownership, or change file permissions through Explorer encounters the same problem, and in the case of ownership changes, quits after first failure. Not only does it not continue on after the first failure, but you don’t get any sort of logging information, so the GUI is pretty much out.
So, to the command line and Takeown. Since Server 2003 Takeown has let admins do what the name implies. It works recursively, and forces an ownership change. Unfortunately, it, like the rest of Windows, isn’t any good at parsing file and directory links that have paths over 260 characters long. Also, unfortunately it doesn’t give you anything more helpful than ”The system cannot find the path specified.” Which isn’t exactly helpful. CD’ing to the directory that it failed on and attempting to takeown from there didn’t work either. Opening the path in Explorer and taking ownership worked, but many of these directories contained 20 subdirectories, which all contained subdirectories, and numerous files. None of which you could take ownership of in bulk, so that solution was pretty much out as well.
So, let’s try it in PowerShell, the be all end all of shells for all platforms. Same thing. But at least it gave me the error information I needed: “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.”
So, now I at least know exactly what the issue I’m dealing with is. The issue is an oft-cursed Windows based limitation called MAX_PATH. This led me on a long bunch of searches about what causes this limitation (legacy compliance), and why it’s artificial (NTFS can handle paths up to 32,000 characters long). It also offers a solution for programmers to get around the limit, but not sysadmins. There’s one MSKB that gives a workaround for it, which is to rename the folders to a shorter length, but since this is what we’re trying to get the users to do, that wasn’t an option. The other was to do a net use, or subst to shorten the path through a symbolic link. I’d thought about using junction points to get around this, but once I began travelling through the directory path, I realized there was no way I was going to be able to do it, without creating thousands of junction points. So, both that and net use were out.
I looked around online for a while, but the only tool I found looked sketchy. I recall doing something like this with Cygwin years ago, but given the sensitive nature of the client data, we weren’t allowed to install any unapproved/untested/etc software. The POSIX extensions could probably deal with it since it’s not an actual kernel or file system limitation, but, not allowed; so I guess not.
I then tried using short names, but for some reason, using Takeown in the normal command prompt refused to accept them after the directory they were representing’s path was too big. That is, any directory it couldn’t access with the full name, it was also unable to access via the short name. Luckily, PowerShell was able to access them with the shortnames, so I was able to takeown all but a dozen or so folders, which I did by hand. Those directories were longer than MAX_PATH even when using the short name.