Formatting Strings In PowerShell Using Fixed Width Columns

Working with strings in PowerShell is fun, I don’t care what you say. In this post, I’m going to show you how to clean up the strings your code outputs, at least in some situations.

Say you have a variable $fileExtensions which you populated with this command.

PS> $fileExtensions = Get-ChildItem | Group-Object -Property Extension

And, for some reason, instead of the default output which is formatted like a table, I want output presented like this.

.ps1     file extension: 11
.xlsx    file extension: 3
.dll     file extension: 1

This is a silly example, but notice that even though there are extensions of varying length (.ps1 and .dll are four characters including the dot, and .xlsx is five), all of the “file extension: <number>” is aligned.

How’d I do that? Let’s start with some code that doesn’t work.

PS&gt; $fileExtensions | foreach-object { "$($_.Name) file extension: $($_.Count)" }

.ps1 file extension: 11
.xlsx file extension: 3
.dll file extension: 3

How incredibly unfortunately unattractive! Luckily, it’s not too hard to fix. Check out this code.

PS&gt; $fileExtensions | foreach-object { "{0,-8} file extension: {1}" -f $_.Name, $_.Count }


.ps1     file extension: 11
.xlsx    file extension: 3
.dll     file extension: 3

Oh yes look at that goodness. In this example I’m using the -f  operator to insert the variables into the string. Let’s break down the new string I’m creating.

{0} and {1] are basically placeholders. The -f operator is going to insert the variables that come after it ($_.Name and $_.Count) into the 0 and 1 spots.

The ,-8 is a formatting instruction. The 8 means that this part of the string is going to be a column that takes up 8 characters worth of space. The negative sign means that the data inserted is left aligned. If I had used “positive eight” it would have been right aligned.

Now you can take this and run, to do fun things like this.

# Input
$header = "[$(Get-Date -format G)]"
Write-Output "$header First line"
Write-Output $("{0,$($header.Length)} Second line" -f " ")
Write-Output $("{0,$($header.Length)} Third line" -f " ")

# Output

[11/2/2017 12:47:58 PM] First line
                        Second line
                        Third line
Written on December 13, 2017