5

I am looking for a way to get and set file attributes (hidden and readonly) in PowerShell for files where the combined path and filename are longer than 260 characters. I know that the .NET classes don't support longer file paths; I've already tried that. Attrib doesn't work either. I get error "Parameter format not correct -". Likewise Dir doesn't work either.

I am using Robocopy to obtain the filenames. Robocopy has no issues with long paths. However, I can't use Robocopy to get/set attributes since I am just using the /L list mode of Robocopy.

Anyone have workarounds for PowerShell?

Update:

subst does not support extra-long paths. It does seem to work with partial paths though.

mklink requires local volumes.

net use does not support extra-long paths. It does seem to work with partial paths though.

New-PSDrive does not support extra-long paths, not even partial paths.

Benjamin Hubbard
  • 2,797
  • 22
  • 28
  • The 260 limit is from windows I believe not .NET. – Mike Cheel Dec 17 '13 at 18:38
  • 1
    Have you tried converting the filenames to [8.3 format](http://support.microsoft.com/kb/142982)? I have no idea if that would work or be too onerous in your environment nor if it would surmount the issue! Just a thought :) – nimizen Dec 17 '13 at 18:39
  • 2
    Based on [Long Paths in .NET, Part 2 of 3: Long Path Workarounds](http://blogs.msdn.com/b/bclteam/archive/2007/03/26/long-paths-in-net-part-2-of-3-long-path-workarounds-kim-hamilton.aspx) and [SetFileAttributes (kernel32)](http://pinvoke.net/default.aspx/kernel32.SetFileAttributes), I think you could write a C# dll and use the information in http://stackoverflow.com/questions/3666337/how-to-use-new-object-of-a-class-present-in-a-c-sharp-dll-using-powershell to use it in PowerShell. – Andrew Morton Dec 17 '13 at 19:15
  • @nimizen: That seems a little unreliable because I can't guarantee that files and paths won't have similar names. I am working with terabytes and terabytes of files. – Benjamin Hubbard Dec 17 '13 at 21:08
  • Did you try creating share on the system hosting the long path? That is `net share foo=c:\some\path...` and then `net use \\server\foo` – vonPryz Dec 18 '13 at 22:04
  • It's a linux server, but I don't have access to the shell. – Benjamin Hubbard Dec 18 '13 at 23:11

2 Answers2

1

I guess using subst command to map the path as a drive letter is worth a shot. It is based on the olden days of DOS and still works on Winndows like so,

subst k: c:\some\really\complex\path\with\too\many\subdirs\and\suff\...

If subst doesn't work, try sharing a directory close to the file and access it via UNC path.

vonPryz
  • 22,996
  • 7
  • 54
  • 65
0

Building on vonPryz's answer and your idea to use partial paths, the following works although it's slow and requires error suppression:

subst m: 'Insert\a\complete\path\close\to\character\limit'
sleep 1
Push-Location 'm:\rest\of\path\to\the\file' -ErrorAction SilentlyContinue
Get-ChildItem | %{
attrib $_
}
subst m: /d
sleep 1

This answer also uses SUBST to get close to where we want to be; then, Push-Location sets the long file-names' parent directory as the 'current working directory' see here. Push-Location complains about it but it works anyway insofar as Get-ChildItem and ATTRIB appear to work with this 'current working directory' rather than parsing the entire path and as a result, ATTRIB works.

nimizen
  • 3,345
  • 2
  • 23
  • 34