Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a switch parameter work with 'valuefrompipelinebypropertyname'?

I am building a function. At times, I want to be able to provide parameter inputs for the function via the pipeline, because often the values are found on a csv file:

$CsvData = @"
Label,Key, IsSubTrigger
Function10,f10, 0
Function11,f11, 1
Function12,f12, true
Function13,f13, false
"@ |ConvertFrom-Csv

The following is the bare bones function:

Function foo{
     [CmdletBinding()]
     Param(
        [parameter(ValueFromPipelineByPropertyName)]
        [string]$Label,
        [parameter(valuefrompipelinebypropertyname)]
        [string]$key,
        [parameter(valuefrompipelinebypropertyname)]
        [switch]$IsSubTrigger,
        
        [parameter(ValueFromPipeline)]
        [string]$Path
     )

     Process{
        "Label:" + $Label,
        "key: " + $Key,
        "IsSubTrigger: " + $IsSubTrigger
     }
}

Invoking $CsvData | foo outputs an error for each csv row:

foo: Cannot process argument transformation on parameter 'IsSubTrigger'. Cannot convert value "System.String" to type "System.Management.Automation.SwitchParameter". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.

I have tried solving this but but have sadly gotten nowhere.

like image 441
GaryAtlan82 Avatar asked Nov 18 '25 15:11

GaryAtlan82


1 Answers

PowerShell doesn't know how to properly coerce a string into a SwitchParameter, which leads to the issue you're observing:

[switch] 'true'
# InvalidArgument: Cannot convert the "true" value of type "System.String" to type "System.Management.Automation.SwitchParameter".

What you can do to help it, is create an argument transformation class, essentially a class that inherits from ArgumentTransformationAttribute, that handles the logic for converting a string into a bool, then that bool can be coerced into SwitchParameter without issues later on:

class BoolParseTransformation : System.Management.Automation.ArgumentTransformationAttribute {
    [Object] Transform([System.Management.Automation.EngineIntrinsics] $engineIntrinsics, [Object] $inputData) {
        $int = 0
        if ([int]::TryParse($inputData, [ref] $int)) {
            return [bool] $int
        }

        return [bool]::Parse($inputData)
    }
}

Then in your param block, you can implement it like this:

function foo {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Label,

        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $key,

        [Parameter(ValueFromPipelineByPropertyName)]
        [BoolParseTransformation()]
        [switch] $IsSubTrigger,

        [Parameter(ValueFromPipeline)]
        [string] $Path
    )
    
    process { $PSBoundParameters }
}
like image 116
Santiago Squarzon Avatar answered Nov 21 '25 07:11

Santiago Squarzon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!