Search code examples
powershellazure-powershell

how to use hashtable to pass parameters to a powershell cmd that uses double dashes before the parameters


i m writing a script that makes use of a cmdlet from a console app, let's call the cmdlet as cmdA. I have no control over implementation of cmdA. cmdA takes parameters with a double dash (cmdA --param1 value1 --param2 value2 --param3 value3 --param4 value4 --param5 value5)

Now param2, param3, param4 and param5 are optional. The user of my script may or may not provide values for these optional parameters. In the script, i formed a hashtable using the parameters for which the user provided values. Let's call it paramHashtable.

I am executing cmdA @paramHashtable but this is not working. I think it has to do something with double dashes because this approach works fine with a cmd that takes parameters with single dash

What would be an efficient way to pass parameters to the cmdA (an inefficient way would be to use many if blocks to check which values were provided and make calls accordingly)

edited*

This is how i m creating the hashtable :-

$optionalParameters = @{}
$optionalParameters = ParameterSelection ${OutputFolder} ${PerfQueryIntervalInSec} ${StaticQueryIntervalInSec} ${NumberOfIterations}
$requiredParameters = @{"sqlConnectionStrings " = "$SqlConnectionStrings"}
$parameters = $requiredParameters + $optionalParameters

function ParameterSelection ([string] $outputFolder, [string] $perfQueryIntervalInSec, [string] $staticQueryIntervalInSec, [string] $numberOfIterations)
{
    $parametersList = @{}
    if($outputFolder -ne "")
    {
        $parametersList["outputFolder "] = $outputFolder    
    }
    if($perfQueryIntervalInSec -ne "")
    {
        $parametersList["perfQueryIntervalInSec "] = $perfQueryIntervalInSec 
    }
    if($staticQueryIntervalInSec -ne "")
    {
        $parametersList["staticQueryIntervalInSec "] = $staticQueryIntervalInSec
    }
    if($numberOfIterations -ne "")
    {
        $parametersList["numberOfIterations "] = $numberOfIterations 
    }

    return $parametersList
}

This is how i m calling it :-

& $ExePath actionName @parameters

The $ExePath has the path of the program to be executed The actionName takes parameters like this:-

actionName --sqlConnectionStrings "Data Source=Server1" --outputFolder C:\Output

Solution

  • Can splatting with hash table work on cmdlets / functions where it's parameter have dashes?

    It may work, but it is definitely not a good idea to have parameter names with dashes as this will result in a function / cmdlet where named parameters cannot be used, PowerShell binds the arguments positionally! (thanks mklement0 for pointing this out):

    function Test-Splatting {
        param(${-param1}, ${-param2})
        "${-param1} ${-param2}"
    }
    
    $param = @{ '--param1' = 'hello'; '--param2' = 'world' }
    Test-Splatting @param # => hello world
    

    Example of what was mentioned before using the same function above:

    # --param1 is bound positionally and not interpreted as a parameter:
    Test-Splatting --param1 hello # => --param1 hello
    

    As for an external programs, the linked answer in comments explains very well the approach you could take using a wrapper function and the use of the automatic variable $args:

    function myfunc {
        $binaryPath = 'path/to/file.exe'
        & $binaryPath actionName $args
        # or @args we can't be sure until testing
    }
    
    myfunc --sqlConnectionStrings "Data Source=Server1" --outputFolder C:\Output