Home > Software engineering >  Powershell syntax "Value count of the command line argument is out of range"
Powershell syntax "Value count of the command line argument is out of range"

Time:01-05

The following line works when executed from cmd but fails with powershell:

SSISDeploy.exe -s:"C:\Users\Monica\FinProj\bin\Development\FinProj.ispac" -d:catalog;"/SSISDB/Fin";"TESTSERVER01" -at:win

The error I'm getting is:

"Failed to parse the command line arguments: The value count of the
command line argument '-destination|-d:<type>;<path>[;server]' is out
 of range".

How to fix the syntax?

CodePudding user response:

Semicolon, double and single quotes are interpreted differently and without knowing the syntax needed for SSISDeploy.exe, the first ; after "catalog" is going to kick off the call, since it's not escaped which inevitably lets the exe fail due to argument mismatch.

My best guess for the Syntax in Powershell would be:

.\SSISDeploy.exe -s "C:\<...>\FinProj.ispac" -d 'catalog;"/SSISDB/Fin";"TESTSERVER01"' -at "win"

  • -s is most likely the source, meaning a path will be passed here. Double quotes will do the trick.

  • -d seems to be rather finicky in the required syntax but carries semicolon and double quotes which cause a problem to Powershell without escaping. Better stick to the cmd-syntax and put the entire content into single quotes. If the flag is taking an array, a clean powershell example could look like: -d "catalog","/SSISDB/Fin","TESTSERVER01"

  • -at looks like a standard flag that takes a string as value - go with double quotes

If you want to try casting all flags into an array, try:

$flags = "'C:\<...>\FinProj.ispac'","catalog;/SSISDB/Fin;TESTSERVER","win"

and run the thing like this:

.\SSISDeploy.exe -s $flags[0] -d $flags[1] -at $flags[2]

Hope this helps. Like I said, I'm not experienced in SSISDeploy.exe but since this issue is escaping-/ character-interpetation-related, these hints should help you out.

CodePudding user response:

; is a metacharacter in PowerShell (of which there are several more compared to cmd.exe - see this answer), namely the statement separator.

  • If ; is used unquoted, as in your attempt (-d:catalog;"/SSISDB/Fin";"TESTSERVER01"), it ends the current statement, which is your immediate problem.

You have several options:

  • Given that your command uses only literal arguments (no PowerShell variables or expressions), --%, the stop-parsing token, allows you to use your cmd.exe command line as-is, if you precede the arguments with it:

    # Note the --% token before the first argument.
    SSISDeploy.exe --% -s:"C:\Users\Monica\FinProj\bin\Development\FinProj.ispac" -d:catalog;"/SSISDB/Fin";"TESTSERVER01" -at:win
    
  • You may also call via cmd /c, which, if you use an expandable (double-quoted) string ("..."), would allow you to embed PowerShell variable values and expressions; since no expansion (string interpolation) is needed in your case, a verbatim (single-quoted) string ('...') is used here:

    # Note the '...' around the entire /c argument.
    cmd /c 'SSISDeploy.exe -s:"C:\Users\Monica\FinProj\bin\Development\FinProj.ispac" -d:catalog;"/SSISDB/Fin";"TESTSERVER01" -at:win'
    
  • Assuming that SSISDeploy.exe doesn't have special quoting requirements, the following, pure PowerShell solution should do (the line-ending ` for line-continuation are used for readability only - if you use them, be sure that they are at the very end of the line: not even whitespace is allowed after them):

    SSISDeploy.exe -s:C:\Users\Monica\FinProj\bin\Development\FinProj.ispac `
                   '-d:catalog;/SSISDB/Fin;TESTSERVER01' `
                   -at:win
    
    • It is important to note that - unlike cmd.exe - PowerShell (of necessity) performs re-quoting behind the scenes after it has completed its own parsing, when it construct the actual process command line to launch the target program with.

    • In other words: Except if you use --%, PowerShell does not give you full control over the process command line: whatever quoting you use on the PowerShell side is not guaranteed to carry through to the process command line; for instance:

      • Argument '-d:catalog;/SSISDB/Fin;TESTSERVER01', even though quoted (as a whole) on the PowerShell side, is placed without quotes on the process command line, because it contains no spaces.

      • The same applies to partial quoting (which in PowerShell only works if the first substring is unquoted); e.g., -d:'foo' would become -d:foo.

      • Argument values with spaces are invariably enclosed in "...", as a whole; e.g., -d:"foo bar" becomes "-d:foo bar"

      • Therefore, those CLIs with nonstandard command-line parsing that require partial quoting aren't directly supported; e.g., msiexec.exe requires a property argument to use partial quoting on its command line, such as PROPERTY="foo bar" rather than what PowerShell passes, "PROPERTY=foo bar"

      • A commonly used workaround is to embed the " characters as a literal part of the argument, e.g. PROPERTY='"foo bar"'; however, this should never have worked and should therefore be avoided; it only works, because, up to PowerShell 7.2.x, PowerShell's handling of embedded " characters in arguments when calling external programs is fundamentally broken - see this answer.

  • Related