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

Check out these related posts: