Reputation: 587
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
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.
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:
Upvotes: 2
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