Search code examples
powershellpipeline

Value for switch parameter from pipeline


I need to pass parameters to a script from pipeline input by importing the required values from CSV file. The original script has more than 15 parameters to be passed and input values are stored in a CSV file. I am posting a simple example to express the issue.

Below are the contents of CSV file (Input.csv)

ResourceGroupName,SetThrottling
TestRG1,1
TestRG2,0
TestRG3,1
TestRG4,0
TestRG5,0

Script file - Switch-FromPipelineTest.ps1

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
  [String]$ResourceGroupName,

  [Parameter(ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
  [Switch]$SetThrottling
)

Begin {}
Process {
  Function TestingValues {
    Param(
      $ResourceGroupName,
      $SetThrottling
    )

    Write-Host "$ResourceGroupName is set to $SetThrottling"
  }

  TestingValues -ResourceGroupName $ResourceGroupName -SetThrottling $SetThrottling
}
End {}

If I run the command Import-Csv .\Input.csv | .\Switch-FromPipelineTest.ps1 it gives an error as given below:

C:\Scripts\Switch-FromPipelineTest.ps1 : Cannot process argument
transformation on parameter 'SetThrottling'. 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.
At line:1 char:26
+ Import-Csv .\Input.csv | .\Switch-FromPipelineTest.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (@{ResourceGroup...etThrottling=1}:PSObject) [Swith-FromPipelineTest.ps1], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Switch-FromPipelineTest.ps1

In order to make this work, I have to run below command:

Import-Csv -Path .\Input.csv -Verbose |
  Select-Object -Property ResourceGroupName,@{n='SetThrottling';e={[bool][int]$_.SetThrottling}} |
  .\Switch-FromPipelineTest.ps1

Is there a way we can omit the type casting done by using custom property expression in the second command? As in the original script, I have several [switch] parameters and I need to do the same thing for each [switch] parameter.


Solution

  • Convert the string values to boolean values upon importing the CSV:

    Import-Csv 'C:\path\to\input.csv' |
        Select-Object -Property *,@{n='SetThrottling';e={
            [bool][int]$_.SetThrottling
        }} -Exclude SetThrottling | ...
    

    You need to do this for every switch parameter you want to import from a CSV.

    If you want to avoid this, change your parameters from switches to set-validated parameters and adjust the parameter evaluation accordingly:

    [Parameter(ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
    [ValidateSet('0', '1')]
    [string]$SetThrottling