问题
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?
回答1:
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
回答2:
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
回答3:
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
回答4:
Unfortunately no. You have to leverage an if statement. Such would work for boolean or switch values, example:
param(
[String]$FieldSeparator=",",
[String[]]$Header,
[switch]$Compress
)
$input | ConvertFrom-Csv -Delimiter $FieldSeparator | ConvertTo-JSON -Compress:$Compress
Note: You may be able to do it using MyInvocation.BoundParameter and splatting but I doubt this will make your script more readable.
来源:https://stackoverflow.com/questions/40549297/passing-an-optional-parameter