1

I need my program to give me every folder containing files which are out of the Windows' number of characters limit. It means if a file has more than 260 characters (248 for folders), I need it to write the address of the file's parent. And I need it to write it only once. For now, I'm using this code:

$maxLength = 248

Get-ChildItem $newPath -Recurse |
    Where-Object { ($_.FullName.Length -gt $maxLength) } |
    Select-Object -ExpandProperty FullName |
    Split-Path $_.FullName

But the Split-Path won't work (this is the first time I use it). It tells me the -Path parameter has a null value (I can write -Path but it doesn't change anything).

If you want an example of what I need: imagine folder3 has a 230-character address and file.txt has a 280-character address:

C:\users\folder1\folder2\folder3\file.txt

Would write:

C:\users\folder1\folder2\folder3

I'm using PS2, by the way.

sodawillow
  • 12,497
  • 4
  • 34
  • 44
Kikopu
  • 155
  • 1
  • 2
  • 10

3 Answers3

0

Spoiler: the tool you are building may not be able to report paths over the limit since Get-ChildItem cannot access them. You can try nevertheless, and also find other solutions in the links at the bottom.

Issue in your code: $_ only works in specific contexts, for example a ForEach-Object loop.

But here, at the end of the pipeline, you're only left with a string containing the full path (not the complete file object any more), so directly passing it to Split-Path should work:

$maxLength = 248

Get-ChildItem $newPath -Recurse |
    Where-Object { ($_.FullName.Length -gt $maxLength) } |
    Select-Object -ExpandProperty FullName |
    Split-Path

as "C:\Windows\System32\regedt32.exe" | Split-Path would output C:\Windows\System32

Sidenote: what do (Get-Item C:\Windows\System32\regedt32.exe).DirectoryName and (Get-Item C:\Windows\System32\regedt32.exe).Directory.FullName output on your computer ? These both show the directory on my system.

Adapted code example:

$maxLength = 248

Get-ChildItem $newPath -Recurse |
    Where-Object { ($_.FullName.Length -gt $maxLength) } |
    ForEach-Object { $_.Directory.FullName } |
    Select-Object -Unique

Additional information about MAX_PATH:

How do I find files with a path length greater than 260 characters in Windows?

Why does the 260 character path length limit exist in Windows?

http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx

https://gallery.technet.microsoft.com/scriptcenter/Get-ChildItemV2-to-list-29291aae

Community
  • 1
  • 1
sodawillow
  • 12,497
  • 4
  • 34
  • 44
  • I didnt try Directory.fullName but DirectoryName only works with PS3. How do you want me to test Directory.fullName in my program ? I do have troubles with pipelines – Kikopu Dec 11 '15 at 07:50
  • I have added another snippet to my answer – sodawillow Dec 11 '15 at 08:08
  • Okay, it works, and it is faster ! The last step is the condition, but it wont be a problem. Thanks for your help ! Edit : Erm we didnt solve the "unique" problem, the file mustn't contain 2 times the same folder. – Kikopu Dec 11 '15 at 08:29
  • Pipe the list to `Select-Object -Unique` :-) (last example updated to reflect this). – sodawillow Dec 11 '15 at 08:56
  • Here is another recent tool to address the overlength path issue : https://gallery.technet.microsoft.com/scriptcenter/Get-ChildItemV2-to-list-29291aae – sodawillow Dec 12 '15 at 10:24
0

you cannot use get-childitem to list paths greater than the windows character limit.

There are a couple of alternatives for you. Try an external library like 'Alphafs' or you can use robocopy. Boe Prox has a script that utilizes robocopy and it is available on technet but i am not sure if it will work on PSV2. Anyway you can give it a try.

Kiran Reddy
  • 2,836
  • 2
  • 16
  • 20
  • Well actually it seems like the program is working, the only problem is that lots of folders are written many times – Kikopu Dec 11 '15 at 09:06
  • By `program` do you mean the technet script that i linked? if so just use the `select-object -unique` like @sodawillow suggested.. – Kiran Reddy Dec 11 '15 at 09:31
  • I mean the `get-childitem`, now i'm waiting to see if the `select-object -unique` is going to work – Kikopu Dec 11 '15 at 09:41
  • `get-childitem` will most certainly not work with paths more than 260 characters...but if it working for you then all i can say is great :)...i am off now..good luck. – Kiran Reddy Dec 11 '15 at 09:57
-1

I've had a similar problem and resolved it like this:

$PathTooLong = @()

Get-ChildItem -LiteralPath $Path -Recurse -ErrorVariable +e -ErrorAction SilentlyContinue

$e | where {$_.Exception -like 'System.IO.PathTooLongException*'} | ForEach-Object {
    $PathTooLong += $_.TargetObject
    $Global:Error.Remove($_)
}

$PathTooLong

On every path that is too long, or that the PowerShell engine can't handle, Get-ChildItem will throw an error. This error is saved in the ErrorVariable called e in the example above.

When all errors are collected in $e you can filter out the ones you need by checking the error Exception for the string System.IO.PathTooLongException.

Hope it helps you out.

DarkLite1
  • 13,637
  • 40
  • 117
  • 214