Passing an optional parameter

萝らか妹 提交于 2019-12-10 15:53:42

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!