Powershell: Add symlink target information to the default output format of Get-ChildItem / Get-Item

Created on 25 Mar 2018  路  2Comments  路  Source: PowerShell/PowerShell

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:

  • doesn't show the target pathin its default output
  • doesn't show the _type_ of link only l in the Mode property indicates that it is a link _in the abstract_ - though that may well be good enough

Given the importance of symlinks in the Unix world and their increasing importance on Windows, it would be convenient to include the symlink target paths:

Desired behavior

# 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} 

Environment data

Written as of:

PowerShell Core v6.0.2
Issue-Enhancement WG-Engine

Most helpful comment

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...)

All 2 comments

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.

Was this page helpful?
0 / 5 - 0 ratings