Reputation: 316
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
Upvotes: 0
Views: 1350
Reputation: 175065
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
Upvotes: 3
Reputation: 2728
@Mathias is correct but from the looks of your question you are using the Write-Host
outputs as your actual return values for the user rather than actually returning data. In which case you really want to do something more like this. but as was already said, DO NOT use Write-Host for anything outside of early development/debugging of a script.
Function test1
{
param(
[Parameter(Mandatory=$false,ValueFromPipeline=$True)]
$PrevRes = @())
$PrevRes += 'alpha'
return ($PrevRes)
}
Upvotes: 1