By default, PowerShell outputs drab directory listings. Unfortunately, there’s no built in solution to turning on colour, but it is possible with a few steps.
- This StackOverflow post gets us most of the way there. Towards the bottom of the question is some code that enables colourised output. I’ve modified it to suit my purposes (see below). This code should be put in your profile (see
$profile
to find the location). - As noted, the code depends on the New-CommandWrapper cmdlet from the Powershell Cookbook. In my PowerShell profile directory, I’ve created a
Scripts
directory as a sibling to the regularModules
directory and put the cmdlet there. - Ensure
New-CommandWrapper.ps1
is unblocked (right click, Properties, Unblock) and in your PATH. If using theScripts
directory, you can put$env:Path += ";$(Split-Path $profile)\Scripts"
in your profile. - Using Set-ExecutionPolicy, ensure your execution policy is set to
RemoteSigned
orUnrestricted
. - Start a new shell, type
dir
orls
and enjoy.
As mentioned, I’ve modified the code in the StackOverflow post to suit my needs:
- Cyan instead of Magenta directories. Magenta hurt my eyes.
- Ignoring colouring text files separately as yellow. I have a lot of text files using different extensions and colouring text files didn’t provide any benefit.
- Removed Perl, Python and Ruby extensions from executables. I don’t use Perl or Python and I have more Ruby code as part of a Rails app than standalone scripts.
- Adjusted column spacing.
- Don’t output a length for directories. It doesn’t show in the screenshot, but it displayed a length of
1
for directories. - Add coloured file count along with total file size at bottom.
- Override both
dir
andls
aliases. - Renamed functions according to PowerShell verb-noun conventions.
The code that goes in your profile is:
New-CommandWrapper Out-Default -Process { $regex_opts = ([System.Text.RegularExpressions.RegexOptions]::IgnoreCase) $compressed = New-Object System.Text.RegularExpressions.Regex( '\.(zip|tar|gz|rar|jar|war)$', $regex_opts) $executable = New-Object System.Text.RegularExpressions.Regex( '\.(exe|bat|cmd|msi|ps1|psm1|vbs|reg)$', $regex_opts) if(($_ -is [System.IO.DirectoryInfo]) -or ($_ -is [System.IO.FileInfo])) { if(-not ($notfirst)) { Write-Host "`n Directory: " -noNewLine Write-Host "$(pwd)`n" -foregroundcolor "Cyan" Write-Host "Mode Last Write Time Length Name" Write-Host "---- --------------- ------ ----" $notfirst=$true } if ($_ -is [System.IO.DirectoryInfo]) { Write-Host ("{0} {1} {2}" -f $_.mode, ([String]::Format("{0,10} {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))), $_.name) -ForegroundColor "Cyan" } else { if ($compressed.IsMatch($_.Name)) { $color = "DarkGreen" } elseif ($executable.IsMatch($_.Name)) { $color = "Red" } else { $color = "White" } Write-Host ("{0} {1} {2,10} {3}" -f $_.mode, ([String]::Format("{0,10} {1,8}", $_.LastWriteTime.ToString("d"), $_.LastWriteTime.ToString("t"))), $_.length, $_.name) -ForegroundColor $color } $_ = $null } } -end { Write-Host } function Get-DirSize { param ($dir) $bytes = 0 $count = 0 Get-Childitem $dir | Foreach-Object { if ($_ -is [System.IO.FileInfo]) { $bytes += $_.Length $count++ } } Write-Host "`n " -NoNewline if ($bytes -ge 1KB -and $bytes -lt 1MB) { Write-Host ("" + [Math]::Round(($bytes / 1KB), 2) + " KB") -ForegroundColor "White" -NoNewLine } elseif ($bytes -ge 1MB -and $bytes -lt 1GB) { Write-Host ("" + [Math]::Round(($bytes / 1MB), 2) + " MB") -ForegroundColor "White" -NoNewLine } elseif ($bytes -ge 1GB) { Write-Host ("" + [Math]::Round(($bytes / 1GB), 2) + " GB") -ForegroundColor "White" -NoNewLine } else { Write-Host ("" + $bytes + " bytes") -ForegroundColor "White" -NoNewLine } Write-Host " in " -NoNewline Write-Host $count -ForegroundColor "White" -NoNewline Write-Host " files" } function Get-DirWithSize { param ($dir) Get-Childitem $dir Get-DirSize $dir } Remove-Item alias:dir Remove-Item alias:ls Set-Alias dir Get-DirWithSize Set-Alias ls Get-DirWithSize
Leave a Reply