Did you ever want your Cmdlets tp support pipeline input but never took the time to correctly implement it? There is an easy way of handling input either from pipeline or as a parameter (regardless it being a sigle object or an array of objects). You just have to decorate a generic input parameter with the “ValueFromPipeline” attribute and iterate over it in the “PROCESS” block of your Cmdlet. Just make sure you do not define a datatype on the parameter as you might get a conversion error (or at least define it as an array so a single object will be converted to an array implicitly). Pre- and Post-Processing can still be done in the “BEGIN” and “END” block respectively:
function Test-ValueFromPipeline { [CmdletBinding( SupportsShouldProcess=$true, ConfirmImpact="Low" )] Param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] $InputObject ) BEGIN { } # BEGIN PROCESS { try { foreach($Object in $InputObject) { if($PSCmdlet.ShouldProcess($Object)) { Write-Host $Object } # if } # foreach } # try catch {} finally {} } # PROCESS END { } # END } # Test-ValueFromPipeline
You now can call the Cmdlet with a string from the pipeline or as a named (or even positional) parameter. When the InputObject is only a single object foreach just iterates over it once.
PS > Test-ValueFromPipeline @("Peter","Paul","Mary") Peter Paul Mary PS > Test-ValueFromPipeline "Peter" Peter PS > "Peter" | Test-ValueFromPipeline Peter PS > @("Peter","Paul","Mary") | Test-ValueFromPipeline Peter Paul Mary
As you noticed the Cmdlet declared it supports “ShouldProcess”. That logic placed inside the “foreach” loop lets the user choose to process each object separately:
PS > @("Peter","Paul","Mary","Tom") | Test-ValueFromPipeline -Confirm Confirm Are you sure you want to perform this action? Performing operation "Test-ValueFromPipeline" on Target "Peter". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y Peter Confirm Are you sure you want to perform this action? Performing operation "Test-ValueFromPipeline" on Target "Paul". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): N Confirm Are you sure you want to perform this action? Performing operation "Test-ValueFromPipeline" on Target "Mary". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): A Mary Tom
Of course this works with any input, not just arrays of strings:
PS > Get-ChildItem | Test-ValueFromPipeline -WhatIf What if: Performing operation "Test-ValueFromPipeline" on Target "Contacts". What if: Performing operation "Test-ValueFromPipeline" on Target "Desktop". What if: Performing operation "Test-ValueFromPipeline" on Target "Documents". What if: Performing operation "Test-ValueFromPipeline" on Target "Downloads". What if: Performing operation "Test-ValueFromPipeline" on Target "Favorites". What if: Performing operation "Test-ValueFromPipeline" on Target "Links". What if: Performing operation "Test-ValueFromPipeline" on Target "Music". What if: Performing operation "Test-ValueFromPipeline" on Target "Pictures". What if: Performing operation "Test-ValueFromPipeline" on Target "Roaming". What if: Performing operation "Test-ValueFromPipeline" on Target "Saved Games". What if: Performing operation "Test-ValueFromPipeline" on Target "Searches". What if: Performing operation "Test-ValueFromPipeline" on Target "Videos". What if: Performing operation "Test-ValueFromPipeline" on Target "Credential.xml". What if: Performing operation "Test-ValueFromPipeline" on Target "history.txt". What if: Performing operation "Test-ValueFromPipeline" on Target "hto.xml". What if: Performing operation "Test-ValueFromPipeline" on Target "readme.txt". What if: Performing operation "Test-ValueFromPipeline" on Target "uri.xml". What if: Performing operation "Test-ValueFromPipeline" on Target "users.csv".