Making Junctions/ReparsePoints visible in PowerShell
I'm not sure if this the right way to do this, and I'm sure someone more clever will speak up but...I use a lot of junctions/reparsepoints in my development here, and I was used to seeing them called out when I typed "dir" from cmd.exe.
(Notice in the screenshot from cmd.exe that the "foo" directory is actually marked <junction>)
In PowerShell when you type Dir, you're getting an Array of System.IO.FileInfo/System.IO.DirectoryInfo objects that are displayed using some default formatting. That default Formatting is a combination of two things, a Type definition and a View definition.
First, there's no "Mode" property on a DirectoryInfo, so how is one being shown? In PowerShell you can "tack on" new properties with Script. This isn't derivation, as it's type extension. Adding to functionality, type-wide (within the context of PowerShell) for any .NET type. So, in C:\program files\Windows PowerShell\v1.0\ there's a file called types.ps1xml that has this little bit of info:
<Type>
<Name>System.IO.DirectoryInfo</Name>
<Members>
<ScriptProperty>
<Name>Mode</Name>
<GetScriptBlock>
here's where the magic happens...
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
So, I created a personal My.Types.Ps1.xml file in my PSConfiguration folder that looked like this, where 1024 is the value of the [int]([System.IO.FileAttributes]::ReparsePoint) enum and "-band" is "bitwise and."
<Types>
<Type>
<Name>System.IO.DirectoryInfo</Name>
<Members>
<ScriptProperty>
<Name>ExtMode</Name>
<GetScriptBlock>
$catr = "";
if ( $this.Attributes -band 1024 ) { $catr += "j" } else { $catr += "-" };
if ( $this.Attributes -band 16 ) { $catr += "d" } else { $catr += "z" };
if ( $this.Attributes -band 32 ) { $catr += "a" } else { $catr += "-" } ;
if ( $this.Attributes -band 1 ) { $catr += "r" } else { $catr += "-" } ;
if ( $this.Attributes -band 2 ) { $catr += "h" } else { $catr += "-" } ;
if ( $this.Attributes -band 4 ) { $catr += "s" } else { $catr += "-" } ;
$catr
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
<Type>
<Name>System.IO.FileInfo</Name>
<Members>
<ScriptProperty>
<Name>ExtMode</Name>
<GetScriptBlock>
# Added the extra "-" to make sure things line up when FileInfos and DirectoryInfos are listed together
$catr = "-";
if ( $this.Attributes -band 16 ) { $catr += "d" } else { $catr += "-" } ;
if ( $this.Attributes -band 32 ) { $catr += "a" } else { $catr += "-" } ;
if ( $this.Attributes -band 1 ) { $catr += "r" } else { $catr += "-" } ;
if ( $this.Attributes -band 2 ) { $catr += "h" } else { $catr += "-" } ;
if ( $this.Attributes -band 4 ) { $catr += "s" } else { $catr += "-" } ;
$catr
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
</Types>
Then in my Microsoft.PowerShell_profile.ps1 (the file that gets executed every time I start a PowerShell) I added:
$profileTypes = $profile | split-path | join-path -childPath "My.Types.ps1xml"
Update-TypeData $profileTypes
Now, I'm not sure how to get dir (alias get-childitem) to use MY ExtMode rather than its own, but I think I'd need to override the default View Definition. It's a little tricky with these scoped XML files, because I originally named my new property "Mode" and was chastised for my efforts:
Microsoft.PowerShell, C:\Documents and Settings\shanselm\My Documents\PSConfigu
ration\My.Types.ps1xml(39) : Error in type "System.IO.FileInfo": Member "Mode"
is already present.
So, I named it "ExtMode." We shall see if there's a better way, until then, this function worked.
function edir
{
dir | select ExtMode, LastWriteTime, Length, Name
}
and got me this output. Notice the "j" now in the ExtMode column.
If I can't override dir's default view, I probably could also have removed the alias for "dir" and replaced it with my own:
if (test-path alias:\dir) { remove-item -force alias:\dir }
set-alias dir edir
but edir is fine for me now.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Comments are closed.
To answer your specific problem, use the -prependpath option to Update-FormatData. You might find this post (part 3 of a 3-part series) helpful: http://www.leeholmes.com/blog/DESCRIPTIONSupportInMonadPart3.aspx