Introduction
Integrating pipeline support into your own functions is not only good practice, but also extends the functionality and reusability of the code. Providing pipeline support in your own functions requires an understanding of pipeline mechanisms and the application of appropriate parameter and processing techniques. Throughout this article, we will explain these concepts from rudimentary to advanced functions and illustrate how you can maximize pipeline efficiency in your scripts.
I want to execute a Select-Object and where Object command within a pipe under the if condition. I have searched for this case, but can find only the case with for-each-object and a specific value of a cell of the csv.
Does anyone have an idea?
[bool] $existdate = 1
[bool] $existstock = 1
import-csv 'C:\temp\in.csv' |
if (!$existdate) {Select-Object * -ExcludeProperty 'deliverydate1', 'deliverydate2' } |
#[...some more code]
if ($existstock) {where-Object {[decimal]$_.stock_supplier -le 30} | where-Object stock_supplier -NotLike '0' | where stock_supplier -NotLike '' } else {where stock_supplier -Like 'low stock' } |
export-csv 'C:\temp\out.csv'asked Aug 30, 2023 at 15:25
You cannot use entire language statements such as if directly in a pipeline.
Instead, you must build the conditional logic into Where-Object or Where-Object calls, or, if feasible, conditionally construct command arguments ahead of time.
Applied to your case:
[bool] $existdate = $true
[bool] $existstock = $true
# Determine what properties to exclude ahead of time, depending
# on the value of $existdate
$excludedProperties = if ($existdate) { @() } else { 'deliverydate1', 'deliverydate2' }
Import-Csv 'C:\temp\in.csv' | Select-Object * -ExcludeProperty $excludedProperties | Where-Object { # Apply the conditional logic to each input object ($_) if ($existstock) { [decimal] $_.stock_supplier -le 30 -and $_.stock_supplier -NotLike '0' -and $_.stock_supplier -NotLike '' } else { $_.stock_supplier -Like 'low stock' } } #[...some more code] | Export-Csv 'C:\temp\out.csv'answered Aug 30, 2023 at 16:01
68 gold badges673 silver badges862 bronze badges
The $Input automatic variable
While many PowerShell developers are familiar with the $_ pipeline variable, $Input is less well known but provides valuable functionality in certain scenarios.
Here is a simple example:
function Sort-InputData {
process {
$dataArray = @($Input)
$sortedData = $dataArray | Sort-Object
$sortedData
}
}In this Soft-InputData function, we first collect all pipeline inputs in an array $dataArray and then sort this data. The result is a sorted list of numbers.
When to use $Input?
Using $Input is particularly useful when you want to perform multiple operations on the entire pipeline input without processing each value individually. However, it is important to understand the difference between $Input and $_ and choose the right variable for the scenario.
Advanced functions with Named Parameters
While simple functions and filters are sufficient for many tasks, advanced functions in PowerShell allow for greater control and flexibility, especially when it comes to working with pipelines. One of the keys to this advanced functionality are Named Parameters.
Named Parameters
Named Parameters allow us to control the input of data in a structured and understandable way. Not only can you specify types for the input parameters, but you can also define default values and add validations.
Here is an example of an advanced function with Named Parameters:
function Get-ModifiedFiles {
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[string]$Path,Here is an exemplary call:
"./" | Get-ModifiedFiles -Since (Get-Date).AddDays(-7)
In this call, the current directory is passed to the Get-ModifiedFiles function as a simple string, and all files that have been modified in the last seven days are returned.
Named Parameters provide a clear and explicit way to control the function inputs and allow finer control over data processing within the function.
Pipeline support basics
To use the pipeline in PowerShell effectively, it’s important to understand some basics. Two key elements here are the filter keyword and the special variable $_. They play a crucial role when it comes to creating a simple function that provides pipeline support.
The filter keyword in PowerShell makes it possible to create a type of function that is specifically designed to process pipeline input. A filter takes input from the pipeline, processes it and returns something to the pipeline. The $_ variable represents the current object in the pipeline that is being processed. Here is a simple function that shows how the filter keyword and the $_ variable can be used:
Filter Convert-ToUpperCase {
Write-Output "Input in uppercase: $($_.ToUpper())"
}In this example, we have created a filter called Convert-ToUpperCase. This filter takes text entries from the pipeline, and for each entry, the ToUpper method is called to convert the text to uppercase. There is also a direct output to the console. If you use this filter in a pipeline, each text entry is processed individually and forwarded to the output in capital letters:
"hello", "world" | Convert-ToUpperCaseThe output would be:
Input in uppercase: HELLO
Input in uppercase: WORLDIn the next section, we will look at Named Parameters and create an advanced function that goes beyond the scope of a simple function and provides more ways to interact with the pipeline.
Implementation of ByPropertyName in own functions
So far, we have dealt with passing values ByValue to functions. However, PowerShell also offers the option of passing ByPropertyName values. This enables a more flexible and intuitive interaction with functions.
ByPropertyName vs. ByValue
- ByValue: Here, the value of an argument is passed directly to the corresponding parameter of the function. This is straightforward, but can lead to confusion in situations where the parameter relationships are not clear.
- ByPropertyName: With this method, the value of an argument is passed based on the name of the parameter. This can be particularly useful if the function has many parameters or if the function is used in a pipeline where the output of the previous cmdlet is used as input for the next cmdlet.
Here is an example to demonstrate the implementation of ByPropertyName:
function Get-FileDetail {
param (
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$FullName
)
In the Get-FileDetail function, we have defined the parameter $FullName with the attribute ValueFromPipelineByPropertyName=$true. This allows the function to accept values from the pipeline that are assigned based on the name of the $FullName parameter. In the example call, the output of Get-ChildItem is forwarded to Get-FileDetail, where the FullName property of the output objects of Get-ChildItem is mapped to the $FileName parameter of Get-FileDetail.
By using ByPropertyName, functions can be used more intuitively and flexibly in pipelines, and the assignment of input values to functions becomes more transparent.
Structuring functions with Begin, Process, End and Clean blocks
- The Begin block is executed once at the start of the function and is suitable for initialization actions.
- The Process block is executed for each object that is passed through the pipeline and is the main location for data processing.
- The End block is executed once after all pipeline objects have been processed and is suitable for final actions.
function Get-Size {
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[string]$Path
)- The Begin creates a temporary directory that is used during processing.
- The Process block checks whether the passed path is a file, collects information about the file, updates the total size and stores file information in a temporary file.
- Der End block outputs the total size of all processed files.
- Der Clean block deletes the temporary directory after processing is complete to ensure that no unwanted data is left behind.
$files = @()
$files += "/Users/philip/Code/blog-post-code-examples/blog.docx"
$files += "/Users/philip/Code/blog-post-code-examples/image.dmg"
$files | Get-SizeTotal size of all processed files: 615.562695503235 MBConclusion
PowerShell pipelines are undoubtedly one of the most important features of PowerShell. Their ability to transfer data efficiently and seamlessly between different cmdlets and functions sets them apart from other scripting languages. For any IT professional looking to automate complex tasks and optimize workflows, they are an indispensable tool.
Your ultimate PowerShell cheat sheet
Unleash the full potential of PowerShell with our handy poster. Whether you’re a beginner or a seasoned pro, this cheat sheet is designed to be your go-to resource for the most important and commonly used cmdlets.
The poster is available for download and in paper form.

Get your poster here!



