I wrote a post last week about how to write functions for use in the PowerShell pipeline and I’ve been using the template I wrote in that post as the basis for several of my other scripts … and I’ve been gradually fleshing it out, and improving it, so I thought I’d drop it here with all of it’s inline comments. Hopefully that will be better than what you would get if I just trying to explain it in a blog post .
Incidentally, this script is also on PowerShellCentral scripts Repository where I will probably post any future modifications …
## A Template for functions which can _also_ be executed in the pipeline ....
## by Joel Bennett, in hopes it will help...
## Version History
## v1.0 First public release (after over 9 different versions in my various other functions)
## v1.2 Show the use of Write-Output, and change "return" in the BEGIN to "Write-Output" to avoid
## the pooling of the output from the process block when it's invoked as a function.
## v1.3 Switched back to "break" instead of "return" so that if you pass via the pipeline AND via
## the inputObject, only the inputObject gets process (this is how cmdlets behave).
###################################################################################################
## The simplest thing is to make -inputObject the very last argument and make sure that you name
## each parameter that you expect to see ... as always you'll have to specify a value for each
## parameter, or specifically name the inputObject parameter.
##
function Test-Pipeline($Parameter1=$null, $inputObject=$null) {
BEGIN {
if ($inputObject) {
### If you're accepting $args, you need to pass those in...
# Write-Output $io | &($MyInvocation.InvocationName) $args;
Write-Output $inputObject | &($MyInvocation.InvocationName) $Parameter1;
break;
}
else
{ ## DO ONCE: (on the re-invoke when using -inputObject)
Write-host "Begin $Parameter1 $args"
}
}
PROCESS {
## You have to at least make sure it's got a value
## Really you should check it's TYPE to make sure you can do something useful...
if($_) {
Write-Host "Write-HOST: $_"
## You should make a practice of explicitly calling Write-Output on things
## That's how you emit them into the pipeline instead of just printing them
Write-Output "Write-OUTPUT $_"
## Most of the time, piping to Out-Default is a lot like using Write-Host...
"Out-Default $_" | Out-Default
}
}
END {
if (-not $inputObject)
{ ## DO ONCE: (on the re-invoke when using -inputObject)
$x = 0
$args | % { $x++; "$x - $_" }
Write-host "End"
}
}
}
###################################################################################################
## Sample call:
##
## [1]> Test-Pipeline Foo! @("one", "two", "three")
## Begin Foo!
## Write-HOST: one
## Write-OUTPUT one
## Out-Default one
## Write-HOST: two
## Write-OUTPUT two
## Out-Default two
## Write-HOST: three
## Write-OUTPUT three
## Out-Default three
## End
## [2]> "one", "two", "three" | Test-Pipeline Foo!
## Begin Foo!
## Write-HOST: one
## Write-OUTPUT one
## Out-Default one
## Write-HOST: two
## Write-OUTPUT two
## Out-Default two
## Write-HOST: three
## Write-OUTPUT three
## Out-Default three
## End
## ## ## To demonstrate the point of output, assign the value, or pipe it into something...
## [3]> $pipeline = "one", "two", "three" | Test-Pipeline Foo!
## Begin Foo!
## Write-HOST: one
## Out-Default one
## Write-HOST: two
## Out-Default two
## Write-HOST: three
## Out-Default three
## End