Powershell again. Pipes, and 'This is not an output'
My experiences with PowerShell continue and every so often realize that I never
really understood something I thought I’d “got” some while back. I’ve spent most
of my time trying not to use the Write-
cmdlets to send output to the screen.
After all, if I want to write “Hello, World” to the screen I can have a function
No need for a Print
, Write
, Echo
or any other command: in PowerShell, an output
with nowhere else to go ends up on the screen.
If I want formatted output,
Format-List
and Format-Table
do a great job, especially since I “discovered”
calculated fields. Since I always used to get my queries in Access to do loads
of work, shoving the work onto Format-Table
seems natural enough, even if the
syntax is little weird. A calculated field is written as a hash table:
@{label="Text", Expression={some code} }
. Of course, “Some code” can do anything
you want and what it returns goes in the table. So, I had a bright idea over
the weekend. I can have a menu using Format-Table
. Here the code:
So I set a counter, get a list of processes, and then format a table; in formatting the table I output and increment the counter. Then I ask the user to input a number to choose one and that gives me the offset into the array of processes of the one to return. When I run it, here’s what I get:
PS C:\Users\Jamesone\> choose-proc
ID ProcessName
-- -----------
0 audiodg
1 CcmExec
Which one ?: 1
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
744 29 13128 10560 92 2204 CcmExec
Of course, I want to save the result, so I type in $proc=choose-proc
and I get this:
Which one ?:
What the … ? Where did my menu go ? And the answer is: the menu was
OUTPUT. Where did I tell PowerShell that Format-Table
wasn’t to send to
standard output but $proc[offset]
was? I didn’t: so both ended up being
stored in the result.
Anyone who’s explored PowerShell’s providers will have found there is one for
variables. Now I get it
$varName= MyFunction
is equivalent to MyFunction > Variable:varName
.
If it goes to standard output it goes into the variable. This behaviour can work for or against you depending on the situation, and here
I need to pipe Format-Table
into Out-Host
to force output to go the console and not to standard Output
I guess I was still thinking in Basic, where the last line of your function usually returns the result. PowerShell’s Outputs are different, they go down the “Standard Output” pipe unless told otherwise and standard output ends up on the screen if the “end of pipe” is left Open; just like you’d expect from a Shell. And since I was quoting my university lecturers a little while ago here’s something which was written on the board in our first programming class.
It is practically impossible to teach good programming style to students that
have had prior exposure to BASIC; as potential programmers they are mentally
mutilated beyond hope of regeneration.
( Edsger Dijkstra )
This post originally appeared on my TechNet blog in 2007