cmd.exe shows the target paths of symlinks by default when you use dir; e.g., assuming a directory with directory symlink tf.l, file symlink tl.txt, and (directory) junction tmp.j, dir will show:
Directory of C:\Users\jdoe\foo
03/23/2018 04:50 PM <SYMLINKD> tf.l [tf]
03/23/2018 04:49 PM <SYMLINK> tl.txt [t.txt]
04/06/2017 02:07 PM <JUNCTION> tmp.j [\??\C:\tmp]
By contrast, PowerShell:
l in the Mode property indicates that it is a link _in the abstract_ - though that may well be good enoughGiven the importance of symlinks in the Unix world and their increasing importance on Windows, it would be convenient to include the symlink target paths:
# Emulated with the following command
# Get-ChildItem | Select-Object Mode, LastWriteTime, Length, Name, Target | Format-Table
# Should be implemented analogously for Get-Item.
PS> Get-ChildItem
Mode LastWriteTime Length Name Target
---- ------------- ------ ---- ------
d----l 3/23/2018 4:50:06 PM tf.l {tf}
d----l 4/6/2017 2:07:17 PM tmp.j {C:\tmp}
-a---l 3/23/2018 4:49:21 PM 0 tl.txt {t.txt}
Written as of:
PowerShell Core v6.0.2
This is really a formatting & output issue, not a cmdlet one. Since we don't currently have an Area-FormattingAndOutput I've changed this to be Area-Engine.
To fix this, the default formatting for FileInfo should be updated to include information about symbolic links and their targets. Now adding an extra field Target to the default output that will be empty most of the time seems inefficient so perhaps we can do what ls -l on *nix does and display something like
lrwxrwxrwx 1 root root 8 Mar 26 10:43 link.txt -> target.txt
Also note the 'l' in the mode field indicating a symbolic link. We set a symlink indication on 5.1 but apparently not on 6.0.2. And even on 5.1, the flag seems to be in the wrong place. On *nix it occupies the directory flag position (left-most bit). On 5.1, it is the right most bit. (I'm not sure if this is deliberate or a bug...)
I think this is deliberate on 5.1: On Windows, l represents that a filesystem item is a _reparse point_ (superset of symbolic link).
It looks like 6.x does the same thing here for Windows reparse points and symbolic links on OS X/Linux.
Unequivocally querying Target may be expensive on Windows. Since symbolic links and junctions _are_ reparse points, they must be opened with FILE_FLAG_OPEN_REPARSE_POINT and the reparse point read and parsed. For things like OneDrive or GVFS, this might fault the file and force a network request/download even if the reparse point does not represent a symbolic link.
Most helpful comment
This is really a formatting & output issue, not a cmdlet one. Since we don't currently have an
Area-FormattingAndOutputI've changed this to beArea-Engine.To fix this, the default formatting for
FileInfoshould be updated to include information about symbolic links and their targets. Now adding an extra fieldTargetto the default output that will be empty most of the time seems inefficient so perhaps we can do whatls -lon *nix does and display something likeAlso note the 'l' in the mode field indicating a symbolic link. We set a symlink indication on 5.1 but apparently not on 6.0.2. And even on 5.1, the flag seems to be in the wrong place. On *nix it occupies the directory flag position (left-most bit). On 5.1, it is the right most bit. (I'm not sure if this is deliberate or a bug...)