I want to set a default strategy for displaying FileInfo and DirectoryInfo objects in Powershell to display only file paths.
PS C:\Users\user> gci
Directory: C:\Users\user
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2023-04-05 1:29 .cache
d---- 2023-03-30 22:41 .dbus-keyrings
d---- 2023-04-15 22:32 .docker
d---- 2023-07-12 15:22 .gfclient
d---- 2023-04-04 4:41 .gradle
d---- 2023-04-16 0:30 .keras
-a--- 2023-09-08 14:36 10629 _viminfo
-a--- 2023-02-09 21:03 2 --help
-a--- 2023-07-21 14:57 13675 .bash_history
PS C:\Users\user> gci
C:\Users\user\.cache
C:\Users\user\.dbus-keyrings
C:\Users\user\.docker
C:\Users\user\.gfclient
C:\Users\user\.gradle
C:\Users\user\.keras
C:\Users\user\_viminfo
C:\Users\user\--help
C:\Users\user\.bash_history
Desired behaviour can be achieved through appending | % fullname
to command, which will print fullname
property of every object in a pipe, but I need a powershell custom view which will do it every time objects of these types will end up in the end of pipe.
I assume my question is to be solved by creating custom view for appropriate object types and assigning this view as default.
get-help about_format.ps1xml
Get-FormatData -TypeName system.io.fileinfo | Export-FormatData -Path formatOrigFile.ps1xml
This is format file I've created by changing default file:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>children</Name>
<ViewSelectedBy>
<TypeName>System.IO.DirectoryInfo</TypeName>
</ViewSelectedBy>
<!-- <GroupBy>
<PropertyName>PSParentPath</PropertyName>
</GroupBy> -->
<TableControl>
<TableHeaders>
<TableColumnHeader />
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<Wrap />
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>$_ | Resolve-Path -Relative</ScriptBlock>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
<HideTableHeaders>true</HideTableHeaders>
</TableControl>
</View>
<View>
<Name>childrenWithHardlink</Name>
<ViewSelectedBy>
<TypeName>System.IO.DirectoryInfo</TypeName>
</ViewSelectedBy>
<!-- <GroupBy>
<PropertyName>PSParentPath</PropertyName>
</GroupBy> -->
<TableControl>
<TableHeaders>
<TableColumnHeader />
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<Wrap />
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>$_ | Resolve-Path -Relative</ScriptBlock>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
<HideTableHeaders>true</HideTableHeaders>
</TableControl>
</View>
<View>
<Name>children</Name>
<ViewSelectedBy>
<TypeName>System.IO.DirectoryInfo</TypeName>
</ViewSelectedBy>
<!-- <GroupBy>
<PropertyName>PSParentPath</PropertyName>
</GroupBy> -->
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<ScriptBlock>$_ | Resolve-Path -Relative</ScriptBlock>
</ListItem>
</ListItems>
</ListEntry>
<ListEntry>
<EntrySelectedBy>
<TypeName>System.IO.FileInfo</TypeName>
</EntrySelectedBy>
<ListItems>
<ListItem>
<ScriptBlock>$_ | Resolve-Path -Relative</ScriptBlock>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
<!-- <HideTableHeaders>true</HideTableHeaders> -->
</ListControl>
</View>
<View>
<Name>children</Name>
<ViewSelectedBy>
<TypeName>System.IO.DirectoryInfo</TypeName>
</ViewSelectedBy>
<!-- <GroupBy>
<PropertyName>PSParentPath</PropertyName>
</GroupBy> -->
<WideControl>
<WideEntries>
<WideEntry>
<WideItem>
<ScriptBlock>$_ | Resolve-Path -Relative</ScriptBlock>
</WideItem>
</WideEntry>
<WideEntry>
<EntrySelectedBy>
<TypeName>System.IO.DirectoryInfo</TypeName>
</EntrySelectedBy>
<WideItem>
<ScriptBlock>$_ | Resolve-Path -Relative</ScriptBlock>
</WideItem>
</WideEntry>
</WideEntries>
<!-- <HideTableHeaders>true</HideTableHeaders> -->
</WideControl>
</View>
</ViewDefinitions>
</Configuration>
This is how it is loaded: Update-FormatData -PrependPath C:\Users\user\Desktop\format.ps1xml
After that, instead of desired behavior, gci
produces this:
PS C:\Users\user> gci
..\.cache
..\.dbus-keyrings
..\.docker
..\.gfclient
..\.gradle
..\.keras
LastWriteTime : 2023-09-08 14:36:29
Length : 10629
Name : _viminfo
LastWriteTime : 2023-07-21 14:57:46
Length : 13675
Name : .bash_history
LastWriteTime : 2023-07-20 13:15:58
Length : 101
Name : .gitconfig
LastWriteTime : 2023-07-05 19:27:42
Length : 2200
Name : .h2.server.properties
It applies new view settings only for directories, not for files.
How should I change format.ps1xml
? Or how do I get what I need in different way?
As @santiago-squarzon pointed out, answer to another question on SO has a better template for a format.ps1xml file. This is my final version:
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>CustomIODisplay</Name>
<ViewSelectedBy>
<TypeName>System.IO.DirectoryInfo</TypeName>
<TypeName>System.IO.FileInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Path</Label>
</TableColumnHeader>
<!-- <TableColumnHeader>
<Label>Length</Label>
</TableColumnHeader> -->
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<Wrap />
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>
# text colors: https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#text-formatting
if ($_.PSIsContainer) {
$colors = @()
# $colors += '32' #greenFg
$colors += '44' #blueBg
$colors = $colors -join ';'
}
$e = [char]27
"$e[${colors}m$($_.FullName)${e}[0m"
</ScriptBlock>
</TableColumnItem>
<!-- <TableColumnItem>
<ScriptBlock>$_.length</ScriptBlock>
</TableColumnItem> -->
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
<HideTableHeaders>true</HideTableHeaders>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
Import it: Update-FormatData -PrependPath .\formatGci2.ps1xml
(it changes view only for current session, add it to pwsh profile if auto-load is needed).
It achieves desired behavior (prints only fullnames), but also changes bg color for directories to blue color, as it is in default view. Also it has commented-out columnHeader and columnItem so it would be easy to add a new column if needed.