Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a native|portable tool that can give me an unicode (or at least system local-compatible) list of all files and directories under a path recursively, without recursing into junction points or links, in Windows?

For example, the built-in dir command, as well as takeown and icacls run into an infinite loop with the Application Data directory (1).

EDIT I would like to be able to get a text file or at least easy clipboard transfer as output.

share|improve this question
    
I would like to avoid using a scripting language (eg. python's os.walk), because I'd prefer a solution more easily portable (eg. a smaller single-file tool) – n611x007 Jan 5 '13 at 11:00
    
Oh, and the tool should handle paths with spaces. :) – n611x007 Jan 5 '13 at 11:13
    
Note the text file doesn't have to be 'plain', it can be xml, csv, tsv, or anything text. – n611x007 Jan 5 '13 at 11:16
2  
I believe you could do this with robocopy, using the /L flag to prevent it from actually doing any copying. – Harry Johnston Jan 7 '13 at 2:24
    
@HarryJohnston indeed, with robocopy /XJ /L /E <dir> <dummy-target>, the /XJ flag skips the junctions and the /L causes to list only! /E is for recursion. Problem: too verbose. But it can be made slightly better with a win32 build of gnu's grep: robocopy /XJ /L /E <dir> <dummy-target> | grep -i "new dir\|new file". Still needs "applying" the containing directory for each file. – n611x007 Mar 22 '13 at 12:56
up vote 4 down vote accepted

This was somehow a hard question. Even StackOverflow has only fancy solutions.
But here is a simple one for listing all files recursively without junction folder loops.

Use PowerShell and test each file if it contains the attribute "ReparsePoint"

function Recurse($path) {

  $fc = new-object -com scripting.filesystemobject
  $folder = $fc.getfolder($path)

  foreach ($i in $folder.files) { $i | select Path }

  foreach ($i in $folder.subfolders) {
    $i | select Path        
    if ( (get-item $i.path).Attributes.ToString().Contains("ReparsePoint") -eq $false) {        
        Recurse($i.path)
    }
  }
}

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$outputlist = Recurse($scriptPath) | Out-File -Filepath .\outputlist.txt 
  1. Paste the code into a text file and save it as PowerShell (.ps1) script
  2. Place the script inside your desired folder to list all files+folder recursively
  3. Execute the script with PowerShell. A new file called outputlist.txt at the same location will appear

Quick comparison between the Powershell script and a common batch command

powershell  - good, no indefinite loops

enter image description here

batch "DIR /B /S" - bad, indefinite loops through junctions points

enter image description here

share|improve this answer
    
To test it, I've just created a junction with sysinternals tool junction.exe in a folder to itself, and unfortunately for me Directory List & Print did get into recursion. – n611x007 Jan 5 '13 at 12:37
    
@naxa A late response. But better late, then never. – nixda Aug 18 '13 at 17:15
    
I love the fact that you sorted it out, and it just works! Thanks nixda! As my original problem was gone (and I don't tend to keep a powershell at home), it took me too some time but I've finally tested it and it works just like I wanted!! Also, I'm absolutely fond of better late than never myself. :) – n611x007 Sep 26 '13 at 11:05
1  
For powershell beginners like me, powershell -ExecutionPolicy Unrestricted -File <yourfilename-here.ps1> will execute the script (my file association was set to notepad :).) – n611x007 Sep 26 '13 at 11:06
    
Well, actually, now that I think of it, I think my original problem was never finished... it got to a point but now it's actually on hold. Hey, thanks, now I can finish the project. :D – n611x007 Sep 26 '13 at 11:15

Using powershell more succinctly:

$items = @(pwd);
while($items){ $newitems = $items | Get-ChildItem | Where-Object -Property Attributes -NotLike *ReparsePoint*; $newitems; $items = $newitems | Where-Object -Property Attributes -Like *Directory* }

To get this all into a text file, just surround the whole thing with parenthesis and pipe it into out-file.

( $items = @(pwd); while($items){ $newitems = $items | gci | where -Property Attributes -NotLike *ReparsePoint*; $newitems; $items = $newitems | where -Property Attributes -Like *Directory* } ) out-file myfile.txt
share|improve this answer

The problem here is that someone has removed the anti recursion from Application Data folder.

It needs to have a DENY to EVERYONE to List Folder/Read Data.

If you want to go into it use the AppData folder which is where it points.

There are two junction points - one in %userprofile% and another in %userprofile%\local.

share|improve this answer
1  
So how does one fix this problem. You have told the author WHAT the problem is but not HOW to fix it. An acceptable answer contains both. – Ramhound Jun 7 '15 at 18:51
    
He can work out him/herself that if it needs something to give it. The poster sabotaged their system. – trigger Jun 7 '15 at 18:53
    
@trigger nice information! I still need the directory walk that avoids the junctions because the Application Data was just an example. It takes too much time to detect all the possible problems. So you need your traversal program to skip recursing into the symlinks. I gave a +1 for the knowledge however! – n611x007 Jun 8 '15 at 9:43
    
I have to agree with Ramhound. Seeing as the person who answered this seems unwilling to provide a complete solution, hopefully someone else will provide both in another answer so that this one can be removed. Also, not sure if the comment about the poster sabotaging their system is supposed to imply that the majority of Windows installs out there don't allow any directory listing tools to recurse into the backwards-compatible WinVista+ %userprofile% junction points, but in my experience this very much depends on the application doing the recursing. – user66001 May 4 at 18:41

This problem might be due to anti recursion permissions being removed from the Application Data folder (like may apply to any Windows Vista+ Junction Point created for backward-compatibility).

These junction points should have DENY to EVERYONE on List Folder/Read Data permissions, which will take precedence over any ALLOW permissions, and hopefully not be circumvented by any directory recursing program due to the way it accesses the File system.

From https://msdn.microsoft.com/en-us/library/windows/desktop/bb968829(v=vs.85).aspx it would appear Junction points are identified by having the ReparsePoint attribute, alongside the Hidden and System attributes.

The following Powershell command is the basis of what seems to be a simpler solution to excluding Junction Points from directory recursions, than any previous answer.

get-childitem $RootDirectoryForRecusion -recurse -force | where-object {-not ($_.Attributes -match "ReparsePoint" -and $_.Attributes -match "Hidden" -and $_.Attributes -match "System")}

share|improve this answer

In PowerShell 3.0 there is a new parameter Attribute:

Lists directory structure without junction folders:

Get-ChildItem -Path $RootDirectory -Attributes !ReparsePoint -Recurse -Force -ErrorAction SilentlyContinue

Lists junction folders only from a directory structure:

Get-ChildItem -Path $RootDirectory -Attributes ReparsePoint -Recurse -Force -ErrorAction SilentlyContinue

More info: Use PowerShell 3.0 to Filter Files Based on Advanced Attributes

share|improve this answer

From a CMD prompt:

dir /A:-L /S /B

EDIT: While this won't list the actual junction in the directory it resides, it will recurse down the junction.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .