2

I am trying to handle errors when scanning through folders. Let's say I have something like:

Get-ChildItem $somepath -Directory | ForEach-Object {
   if(error occurred due to too long path) {
        skip this folder then
   } else {
       Write-Host $_.BaseName
   }
}

When I do this I print the folders in $somepath until one of them is too long and then the loop stops. Even when using SilentlyContinue. I want to print even after reaching a folder that is too long.

Matt
  • 45,022
  • 8
  • 78
  • 119
  • Don't ask your question again by double posting. http://stackoverflow.com/questions/39572006/error-handling-a-too-long-path-in-a-foreach-object-loop-in-powershell – Matt Sep 23 '16 at 14:17
  • 1
    you could handle the exception: [System.IO.PathTooLongException] – Austin T French Sep 23 '16 at 14:49

3 Answers3

6

If you can install a non-ancient PowerShell version (3.0 or newer), simply prepend the path with \\?\ to overcome the 260-character limit for full path:

Get-ChildItem "\\?\$somepath" | ForEach {
    # ............
}
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • 1
    I have to find a reference but I was under the impression this does not work anymore. – Matt Sep 23 '16 at 14:31
  • 2
    Likely in my ignorance but I get errors running this: `Illegal characters in path.` or `Cannot retrieve the dynamic parameters for the cmdlet.`.... – Matt Sep 23 '16 at 14:52
  • PS5.1+Win7: https://puu.sh/rlaUh/748082bbdb.png and yeah it won't work in PS2 as I've just tried by running `powershell -version 2` – wOxxOm Sep 23 '16 at 14:55
  • That part makes sense then. I'm on 10 running v5. Thanks for the picture. – Matt Sep 23 '16 at 16:25
  • 1
    If anyone is curious for some documentation on this: https://msdn.microsoft.com/en-us/library/aa365247.aspx – Alex Feb 14 '18 at 21:51
0

You could try ignoring the files longer 260 characters by using the Where-Object cmdlet.

Get-ChildItem $somepath -Directory -ErrorAction SilentlyContinue `
    | Where-Object {$_.length -lt 261} `
    | ForEach-Object { Write-Host $_.BaseName }

Or you could use the following (Ref).

cmd /c dir $somepath /s /b | Where-Object {$_.length -lt 261} 
Community
  • 1
  • 1
Richard
  • 6,812
  • 5
  • 45
  • 60
0

I will add my solution since the neither on this page worked for me. I am using relative paths, so I can't use the \\ prefix.

$TestFiles = Get-ChildItem $pwd "*Tests.dll" -Recurse | Where-Object {$_.FullName.length -lt 261} | Select-Object FullName -ExpandProperty FullName | Where-Object FullName -like "*bin\Release*"
Write-Host "Found TestFiles:"
foreach ($TestFile in $TestFiles) {
    Write-Host "   $TestFile"
}
Jess
  • 23,901
  • 21
  • 124
  • 145