alazyworkaholic
alazyworkaholic

Reputation: 587

How to pass array of commands to a dotnet cli application

A dll can be invoked in Powershell; it takes several parameters, and I must run it several times while most of them stay the same, like this:

dotnet C:\App\App.dll AppCmd --MySwitch --Param1 ab --Param2 cd --Param30 xx
dotnet C:\App\App.dll AppCmd --MySwitch --Param1 ab --Param2 cd --Param30 yy
dotnet C:\App\App.dll AppCmd --MySwitch --Param1 ab --Param2 cd --Param30 zz --Param31 x:y y:z

I'd like to 'splat' the common parameters and manually write out only what is unique to each invocation, like:

$CommonArgs = @{
Param1 = 'ab',
Param2 = 'cd'
...
}
dotnet C:\App\App.dll AppCmd --MySwitch --Param30 xx -- @CommonArgs
dotnet C:\App\App.dll AppCmd --MySwitch --Param30 yy -- @CommonArgs
dotnet C:\App\App.dll AppCmd --MySwitch --Param30 zz --Param31 x:y y:z -- @CommonArgs

The App stops complaining about missing required parameters with the above syntax but it returns an error: Unhandled Exception: System.FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters. I'm not sure whether that error message comes from the Application or Powershell itself.

I figured out splatting within Powershell functions and I read the -- should pass the parameters along to the dotnet call but apparently I'm still missing something. What is it?

Upvotes: 3

Views: 468

Answers (2)

mklement0
mklement0

Reputation: 440132

Using hashtable-based splatting with external programs rarely works, because of the very specific format that PowerShell translates the hashtable entries to: -<key>:<value> - this won't work in your case.

For external programs, array-based splatting is the better choice - and, in fact, you don't even need the splatting sigil (@ instead of $) at all and you can just pass an array variable as-is:

$CommonArgs = @( # array, not hashtable
  '--Param1', 'ab',
  '--Param2', 'cd'
  # ...
)

# ...
dotnet C:\App\App.dll AppCmd --MySwitch --Param30 zz --Param31 x:y $CommonArgs y:z
  • Note how each argument - irrespective of whether it represents a parameter name or a value - must be its own array element.

    • PowerShell simply space-concatenates the array elements when building the command line to use for invocation behind the scenes, applying double-quoting around elements with embedded spaces as needed.
  • I've omitted --, because it would be passed through to the external program - not sure if that's the intent (only for PowerShell-native commands is it removed by the parameter binder).

Troubleshooting tip:

  • The bottom section of this answer shows how to build a helper executable that can be used to echo the exact command line it was given, as well as how it parsed it into individual arguments (using .NET's parsing rules, which are based on Microsoft's C/C++ compiler).

Upvotes: 2

Theo
Theo

Reputation: 61218

Too long for a comment, and I have no idea if this would work, but perhaps you can use a small helper function to convert the common arguments from the splatting Hashtable into commandline syntax like

function Format-CliArguments {
    param (
        $prefix = '--'
    )
    $numTypes = 'byte','sbyte','int','int16','int32','int64','uint16','uint32',
                'uint64','long','float','single','double','decimal'
    $cliCommand = for ($i = 0; $i -lt $args.Count; $i += 2) {
        if ($numTypes -contains $args[$i + 1].GetType().Name) {
            '{0}{1} {2}' -f $prefix, $args[$i].Trim("-:"), $args[$i + 1]
        }
        else {
            '{0}{1} "{2}"' -f $prefix, $args[$i].Trim("-:"), $args[$i + 1]
        }
    }
    $cliCommand -join ' '
}

# you can make this [ordered]@{..} if the sequence is important
$CommonArgs = @{          
    Parameter1 = 'ab'
    Parameter2 = 123
    Parameter3 = 'zz'
}


$standardArgs = Format-CliArguments @CommonArgs

dotnet C:\App\App.dll AppCmd --MySwitch --Param30 xx $standardArgs
dotnet C:\App\App.dll AppCmd --MySwitch --Param30 yy $standardArgs

etc.

Upvotes: 1

Related Questions