I have a PowerShell script CSV2JSON.ps1
with the following code:
param(
[String]$FieldSeparator=",",
[String[]]$Header
)
$input | ConvertFrom-Csv -Delimiter $FieldSeparator -Header $Header | ConvertTo-JSON
If I call it as .\CSV2JSON.ps1 -FieldSeparator "|" -Header "name|age"
it works fine. However, if I drop the optional parameter Header
, the ConvertFrom-Csv
cmdlet complains that Header
cannot be null:
ConvertFrom-Csv : Cannot validate argument on parameter 'Header'.
The argument is null. Supply a non-null argument and try the command again.
I don't want to pass the -Header
parameter at all, if it's not provided. Is there a neat way to pass on optional parameters without getting into If
statements?
If we do not pass any parameter to the optional arguments, then it takes its default value. The default value of an optional parameter is a constant expression. The optional parameters are always defined at the end of the parameter list. Or in other words, the last parameter of the method, constructor, etc. is the optional parameter.
As the name suggests, optional parameters are not mandatory. This helps developers not to pass arguments for some of the method's parameters. Nowadays this is a very common interview question.
We can implement optional parameters by assigning a default value for the parameters. This is the easiest and simple way to make the methods parameter optional. In this way, we just need to define the optional parameter with its default values when we create our methods.
If anyone wants to add just two numbers, they can invoke the method such as: On the other side if we want to add 10 numbers then we can simply invoke the method: We can implement optional parameters by assigning a default value for the parameters. This is the easiest and simple way to make the methods parameter optional.
I'm surprised no one has suggested splatting the $PSBoundParameters
automatic variable.
$PSBoundParameters
is a hashtable containing all the parameter arguments that was passed to the command.
Simply rename the $FieldSeparator
parameter to $Delimiter
and you're good to go.
You can provide the FieldSeparator
name as a parameter alias if needed:
param(
[Alias('FieldSeparator')]
[String]$Delimiter=",",
[String[]]$Header
)
$input | ConvertFrom-Csv @PSBoundParameters | ConvertTo-JSON
If the -Header
parameter is omitted when executing the calling function/script, it'll also be omitted from the call to ConvertFrom-Csv
Martin Brandl is right, you must use an if
, but I would recommend combining it with splatting so that you only make your call once:
param(
[String]$FieldSeparator=",",
[String[]]$Header
)
$params = @{
Delimeter = $FieldSeparator
}
if ($Header) {
$params.Header = $Header
}
$input | ConvertFrom-Csv @params | ConvertTo-JSON
OK, I have another option based on the feedback from Martin. This works well when the parameter names match:
param(
$Path,
$Delimiter,
$Header
)
$params = @{}
$MyInvocation.BoundParameters.Keys | Where {$_} |
% {$params.Add($_, (Get-Variable $_).Value )}
Import-Csv @params
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With