You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PSUseProcessBlockForPipelineCommand does not recognize use of $input within an End block #1912
Invoke-ScriptAnalyzer-IncludeRule PSUseProcessBlockForPipelineCommand `-ScriptDefinition 'Param([Parameter(ValueFromPipeline=$true)][psobject] $Item); End {$input |ConvertTo-Json}'
Expected behavior
(no output)
Actual behavior
RuleName Severity ScriptName Line Message
-------- -------- ---------- ---- -------
PSUseProcessBlockForPipelineCommand Warning 1 Command accepts pipeline input but has not defined a
process block.
Environment data
>$PSVersionTable
Name Value
---------
PSVersion 7.3.4
PSEdition Core
GitCommitId 7.3.4
OS Microsoft Windows 10.0.22621
Platform Win32NT
PSCompatibleVersions {1.0,2.0,3.0,4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0> (Get-Module-ListAvailable PSScriptAnalyzer).Version |ForEach-Object { $_.ToString() }
1.21.0
This is by design, if you take a parameter that takes input from a pipeline then there is an expectation that the process block is going to handle it since it has to run multiple times. Begin and end blocks only run once in a pipeline. Its not complaining about $input but $Item because $Item needs to be handled in a process block.
In the example above, $input includes all of the values of $Item. This is a pattern that can be used when all of the input needs to be gathered before using it, such as when using Write-Progress to display the percentage that has been completed after each item.
I think since you still have a parameter $Item the takes ValueFromPipeline it needs to be in a process block. I'd have to rely on James Truher (@JamesWTruher) for a deeper explanation or fix.
Steven Bucher (@StevenBucher98) There's more than one way to consume that pipeline data. Explicit usage in the Process block is certainly the most common way, but if you try to use that approach, it'll consume the data before you can use it in the End block, which is a legitimate alternative method for processing the data. You can't mix them.
Brian Lalonde (@brianary) using $input in the end is not something that we recommend and will likely lead to misunderstandings as the following example shows.
functionf1 {
param ([parameter(ValueFromPipeline=$true)]$a)
BEGIN { "input value: '$input' `tinput count: $($input.count)`tvalue of a: '$a'" }
PROCESS { "input value: '$input' `tinput count: $($input.count)`tvalue of a: '$a'" }
END { "input value: '$input' `tinput count: $($input.count)`tvalue of a: '$a'" }
}
when run, the output is as follows:
PS>1..3| f1
input value: '' input count: 0 value of a: ''
input value: '1' input count: 1 value of a: '1'
input value: '2' input count: 1 value of a: '2'
input value: '3' input count: 1 value of a: '3'
input value: '' input count: 0 value of a: '3'
As you can see, $input has no value in both the BEGIN and END blocks and a has the last value that $a was set to in the END block.
This rule is expressing the appropriate expectation that if you have pipelined parameters, you need to handle them in a PROCESS block. The rule violation has nothing to do with $input in the END block, only that you have failed to handle the pipeline variable in the appropriate block.
Activity
StevenBucher98 commentedon May 9, 2023
This is by design, if you take a parameter that takes input from a pipeline then there is an expectation that the process block is going to handle it since it has to run multiple times. Begin and end blocks only run once in a pipeline. Its not complaining about
$inputbut$Itembecause$Itemneeds to be handled in a process block.brianary commentedon May 9, 2023
Steven Bucher (@StevenBucher98) The
$inputvariable is an automatic variable: "In the end block, the $input variable enumerates the collection of all input to the function."In the example above,
$inputincludes all of the values of$Item. This is a pattern that can be used when all of the input needs to be gathered before using it, such as when usingWrite-Progressto display the percentage that has been completed after each item.StevenBucher98 commentedon May 9, 2023
I think since you still have a parameter
$Itemthe takesValueFromPipelineit needs to be in a process block. I'd have to rely on James Truher (@JamesWTruher) for a deeper explanation or fix.brianary commentedon May 9, 2023
Steven Bucher (@StevenBucher98) There's more than one way to consume that pipeline data. Explicit usage in the
Processblock is certainly the most common way, but if you try to use that approach, it'll consume the data before you can use it in theEndblock, which is a legitimate alternative method for processing the data. You can't mix them.JamesWTruher commentedon May 9, 2023
Brian Lalonde (@brianary) using $input in the end is not something that we recommend and will likely lead to misunderstandings as the following example shows.
when run, the output is as follows:
As you can see, $input has no value in both the
BEGINandENDblocks andahas the last value that$awas set to in theENDblock.This rule is expressing the appropriate expectation that if you have pipelined parameters, you need to handle them in a
PROCESSblock. The rule violation has nothing to do with$inputin theENDblock, only that you have failed to handle the pipeline variable in the appropriate block.brianary commentedon May 10, 2023
James Truher (@JamesWTruher)
Yes, you can't mix
$inputin multiple blocks, as I said, because it consumes the values.