In most common programming languages, a function (or method) defines a block of code that does some work internally, and returns a value at the end, either implicitly (the result of processing the last line is returned), or explicitly (a keyword such as return
is used to specify the return-value). In Powershell on the other hand, everything is returned out. Take the following example for instance:
function get-an-array { "Creating an array..." $arr = "one","two","three" "Array created; returning it now:" return $arr } #calling the function: $myArray = get-an-array
In most languages, you would expect $myArray
to contain just that – an array after executing the code above. Also, you might have expected the messages in between to have been written out to the screen. Not so! The actual content of the resulting variable will be as follows:
Creating an array… Array created; returning it now: one two three
That`s right: The entire result of running the function’s code will be stored in the variable.
So what can you do if you want to output some information along the way, without “polluting” the result of the function?
Write-Information to the rescue!
Here’s how to output information directly; this will print directly to the screen, and not clutter your function’s result:
Write-Information "Informational string..." -InformationAction Continue
Replace each plain string in the function above with that, and your code should run as you probably intended, returning only the array into $myArray
.
Clean up your code with an alias
I find write-information
to be a little long and messy though, so I wrote a small function and an alias to clean things up a little:
# Function that calls Write-Information for me: function show-information { param([string]$value) Write-Information $value -InformationAction Continue } # Create an alias for the function above, # allowing it to be called using: "OP <output-string>": Set-Alias -Name OP -Value show-information
It should be reasonably clear what this does. Add that to the top of your script, and you will be able to use it throughout the rest of it. In this way, the new version of the function above now becomes:
function get-an-array { OP "Creating an array..." $arr = "one","two","three" OP "Array created; returning it now:" return $arr }
The only difference in syntax is that OP
is prepended to the strings intended as information / debug-info. The result however, is that they are output along the way as intended, and that the result of the function is limited to the value of $arr
.
A word of caution regarding aliases
It is generally recommended that you avoid using aliases in scripts. The reasoning is that aliases may complicate and obscure what the code does, and that there may be no guarantee that it will work the same way on all environments. Besides that, aliases are mostly shortcuts to be used when working interactively on the command line – arguably, you should not need them in a script.
I think those are fair rules in general. In this particular case though, I feel that breaking them is warranted for a couple of reasons:
- This is a small, simple, locally defined function and alias.
You can add them to the top of each script without it adding too much clutter. In fact, you can have the whole function on a single line, and the alias on the next. - It simplifies the code significantly, and it’s usage is pretty clear
Even if you didn’t see the function definition at the top of the script, it should be pretty easy to guess what it does when you see it in use (personally, I actually find the attributeInformationAction Continue
more confusing).
My advice: Consider shortcuts like this on a case-by-case basis, but keep the general advice of avoiding aliases in scripts in mind.