I am writing a search tool on Powershell and I ran into a problem that I cannot suppress the return of a function and it is always printed to console. To make it clear I made some smaller test functions.
Function test1
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = 0)
write-host "alfa"
return ($PrevRes+1)
}
Function test2
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = 0)
write-host "beta"
return ($PrevRes+1)
}
Function test3
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = 0)
write-host "omega"
return ($PrevRes+1)
}
test1 gives:
alfa
1
when test1 | test2:
alfa
beta
2
when test | test2 | test3:
alfa
beta
omega
3
when test | test3 | test2:
alfa
omega
beta
3
The problem is I do not know in what order these functions will be called and what I need is to make sure if there is no pipeline at the end, the return would not be printed to the screen, but I still need to access the value itself.
I want an output like this:
test1 gives:
alfa
when test1 | test2:
alfa
beta
when test | test2 | test3:
alfa
beta
omega
when test | test3 | test2:
alfa
omega
beta
This is a tool for a customer so solution like:
$tst = test1 |test2
is not good because you know, a customer is a customer, he wouldn't know how to use it.
Is there a way to do it with powershell which I missed online?
Any solution would be useful if it does not involve any action from the customer
Thank you in advance
To answer the question
is there a way to determine in the function itself if the return value is pipelined or not?
Yes there is. Inspect the $MyInvocation
automatic variable and compare the PipelineLength
and PipelinePosition
properties:
if($MyInvocation.PipelinePosition -lt $MyInvocation.PipelineLength){
return $PrevRes + 1
}
Original answer follows below.
Very simple solution:
Write-Host
in your scripts.As the name indicates, it will write stuff directly to the host application
If you need to keep these statements for debugging purposes, use the Write-Debug
or Write-Verbose
cmdlets instead:
function test1
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = 0)
Write-Verbose "alfa"
return ($PrevRes+1)
}
function test2
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = 0)
Write-Verbose "beta"
return ($PrevRes+1)
}
function test3
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = 0)
Write-Verbose "omega"
return ($PrevRes+1)
}
If you need to increment the $PrevRes
value between cmdlets you could use a variable from the calling scope (although this is somewhat of an anti-pattern, and I would strongly recommend against it):
function test1 {
Write-Host 'alpha'
$global:PrevRes++
}
function test2 {
Write-Host 'beta'
$global:PrevRes++
}
function test3 {
Write-Host 'omega'
$global:PrevRes++
}
Then use like:
PS> test1; test2; test3
alpha
beta
omega
PS> $PrevRes
3