Weekend Scripter: Sort Process Names by Length of Name

Doctor Scripto

Summary: Microsoft Scripting Guy, Ed Wilson, takes some time out to play around with the Format-Wide cmdlet.

Microsoft Scripting Guy, Ed Wilson, is here. Well, the Scripting Wife and I are hanging out on the beach this weekend. Because I have a long weekend (thanks to a way cool Scripting Manager) I feel like it is a holiday or something. Well, what do I like to do when I have a holiday? I enjoy playing around with Windows PowerShell—that’s what. Well, I was reviewing the Formatting Windows PowerShell Output chapter for my forthcoming Windows Windows PowerShell 3.0 First Steps book by Microsoft Press (available now with Pre-Order) and I was reminded about using the Format-Wide cmdlet.

Format-Wide? Dude!

Now, I will be honest, I seldom use the Format-Wide cmdlet—most of the time when I could use it, I simply forget about it. It is not one of my most favorite tools, nor do I find it indispensable. Which means, there is probably some things I have not been doing with it.

Now, if I use the Get-Process cmdlet and pipe the process objects to the Format-Wide cmdlet and choose only process names, the output appears jumbled. This command and output are shown in the figure that follows.

The reason for the jumbled output is the length of process names that spread through the output. Hmmmmm. I wonder if there is any way to sort the process names by length of the name? Would that produce a nicer output?

Well Format-Wide has no length parameter

If I want to organize the output from the Format-Wide cmdlet by length of the process name, I am going to have to sort the process names by length prior to arriving at the Format-Wide cmdlet in the pipeline. Ok.

But the Get-Process cmdlet does not have a length parameter I can use to sort by process name length. Hmm … I guess I will need to add a length property to the process object I want to use. In that way, I can use the Sort-Object cmdlet before entering Format-Wide. Sounds like a plan, so how do I do that?

First use a ScriptBlock with Select-Object

The first thing I need to do is to create a custom object with Select-Object. This technique of using the Select-Object cmdlet to create a custom object is one of my favorite Windows PowerShell tricks. Here I need to get the length of each process name. So, I first pipe the results from Get-Process to the Select-Object cmdlet. I can choose the name property easily enough, but to get the length of the name property I need to first ensure the name is a string, and then call a string property (length). The basic syntax for ensuring the process name is a string and calling the string property length is shown here.

13:57 C:\> (gps)[0].name.tostring().length


Sweet, it works. Now I know what I want to do, so all I have to do is to create the code to do this for each of the process names. I decide to use a custom hash table type of syntax to create a synthetic property (this hash table sort of technique works with Format-Table, Format-List, but not Format-Wide as well—it is used to create a custom label and a computed value for a standard property. This technique is shown here to create a custom table output.

14:01 C:\> gps | ft name, @{label=”length”;Expression={$_.name.tostring().Length}} -auto 

Name                       length

—-                       ——

armsvc                          6

audiodg                         7

BtwRSupportService             18

…<Output Truncated>

So, I can simply replace the Format-Table cmdlet with the Sort-Object cmdlet, and I am creating a custom object that meets my needs. Here is the code so far.

Get-Process |

Select-Object name, @{label=”length”;Expression={$_.name.tostring().Length}}

Put it together, sort and format

Now, all I need to do is sort the output by the length and pipe the results to the Format-Wide cmdlet. Of course, Format-Wide does only one property at a time, so I will lose the length in the process, but that is fine. Here is the command up with which I arrived (gps is an alias for Get-Process, select is an alias for Select-Object, sort is an alias for Sort-Object, and fw is the alias for Format-Wide).

gps |

select name, @{label=”length”;Expression={$_.name.tostring().Length}} |

sort length |

fw -Property name -Column 5

The following figure shows the command (a one-liner) and the output associated with the command. As you can see, the output is much more aesthetically pleasing.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy


Discussion is closed.

Feedback usabilla icon