How to Use Out-String in PowerShell: Don’t

In my PowerShell Help Commands For Linux Users post, I showed you this pattern for searching for command aliases:

Get-Alias | Out-String -stream | Select-String -Pattern 'move'

A beginner mistake! Here’s the problem:

I’m used to the Unix shells, like bash, where everything is a string. When you run alias in bash, you get this:

$ alias
alias hello='echo hello'
alias la='ls -a'
alias ll='ls -l'

A multiline string with one alias per line. You search those aliases like this:

$ alias | grep hello
alias hello='echo hello'

grep does a pattern match on each string of those lines, one line at a time.

PowerShell is object-oriented. Its Get-Alias command doesn’t return a multiline string, it returns an array of objects. Those object have properties like Name. If you want to find aliases whose name match a pattern, you just iterate the array:

Get-Alias | Where-Object Name -Match ".*move.*"

Where-Object checks the Name property of each object in the array to see if it matches the .*move.* pattern. (Technically Where-Object isn’t doing the iteration, PowerShell is unpacking the array and sending the objects through the pipe one at a time)

This is so much better. It’s like writing Python. Standard data types and logic.

In my past post, I piped to Out-String, which converts objects into strings. That allowed me to imitate the Linux pattern by searching with Select-String (basically the PowerShell grep). Totally unnecessary. In PowerShell you can just match on object properties directly. You don’t need to cast to strings.

In a simple case like this PowerShell’s object-oriented nature is mostly a novelty, but in more complex cases it ends up being hugely powerful. More posts coming!

Happy automating,

Adam

If this was helpful and you want to save time by getting “copy and paste” patterns for PowerShell in your inbox, subscribe here.