powershell colored directory listing


I still continue to fiddle about with PowerShell scripting on Windows 10. With PowerShell Core, PowerShell is also available for Linux and macOS. With that kind of cross-platform availability I’ve been trying to write code that works across Windows 10 Desktop as well as the Core implementations. This post is about a colored directory lister written in PowerShell that does that.

If you’re a Linux user, then you’re probably used to the colorization abilities of Gnu ls. I wanted that basic capability for Windows 10 and I wanted it to operate the same across all platforms. One feature I wanted was for this colored directory to show soft links, that is, identify a soft link and show what it pointed to. I managed to get that to work. The code follows.

function Get-ColoredDir {$regex_opts =([System.Text.RegularExpressions.RegexOptions]::IgnoreCase `  -bor [System.Text.RegularExpressions.RegexOptions]::Compiled)# Save the foreground and background colors. We'll restore when finished.$fore = $Host.UI.RawUI.ForegroundColor$back = $Host.UI.RawUI.BackgroundColor# Create regular expressions for finding compressed, executable, and text files.# We'll use these distinctions for our coloration below.$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|py|pl|ps1|psm1|vbs|rb|reg|msi|sh)$', $regex_opts)$text_files =New-Object System.Text.RegularExpressions.Regex('\.(txt|cfg|conf|ini|csv|log|xml|html|java|c|cpp|cs)$', $regex_opts)Invoke-Expression ("Get-ChildItem $args -Force") | ForEach-Object {$timestamp ='{0,2}/{1,2}/{2:D4} {3:D2}:{4:D2}:{5:D2}' -f$_.LastWriteTime.Month,$_.LastWriteTime.Day,$_.LastWriteTime.Year,$_.LastWriteTime.Hour,$_.LastWriteTime.Minute,$_.LastWriteTime.Second;$foretext = '{0, -10} {1} {2, 10} ' -f $_.Mode, $timestamp, $_.Length# Look to see if any of the objects found is a soft link.# Microsoft's term for a soft link is ReparsePoint.# Note the use of -Force to pick up hidden files, or files that start# with a period (.)$linkedItem = ''if ($_.Attributes -match "ReparsePoint") {$linkedItem = Get-Item -Force $_ | select-object -expandproperty Target}if ($_.GetType().Name -eq 'DirectoryInfo') {$Host.UI.RawUI.ForegroundColor = 'Cyan'if ($_.Attributes -match "ReparsePoint") {$Host.UI.RawUI.ForegroundColor = 'Magenta'}}elseif ($compressed.IsMatch($_.Name)) {$Host.UI.RawUI.ForegroundColor = 'Yellow'}elseif ($executable.IsMatch($_.Name)) {$Host.UI.RawUI.ForegroundColor = 'Red'}elseif ($text_files.IsMatch($_.Name)) {$Host.UI.RawUI.ForegroundColor = 'White'}else {$Host.UI.RawUI.ForegroundColor = $fore}if ($linkedItem.length -gt 0) {'{0}{1} -> {2}' -f $foretext, $_.Name, $linkedItem} else {'{0}{1}' -f $foretext, $_.Name}}$Host.UI.RawUI.ForegroundColor = $fore$Host.UI.RawUI.BackgroundColor = $back}

I wouldn’t call this particularly exciting PowerShell code. I’m quite certain that a real PowerShell scripting guru would come up with something far more elegant. But it works, and it has examples of how to extract information for directory objects in a PowerShell environment, especially when determining soft links and what they resolve to. I hope you find it useful.

If you’re interested in PowerShell Core, you can find it on GitHub here: https://github.com/PowerShell/PowerShell