3

I am running powershell script over ssh as ssh user@host "powershell -Comand - < script.ps1. It works as expected until I start passing arguments.

When I put it as powershell -Command - my args it fails (as documented) '-' was specified with the -Command parameter; no other arguments to -Command are permitted.

While the other way around powershell my args -Command - it fails with:

The term 'my' is not recognized as the name of a cmdlet, function, script file,
 or operable program. Check the spelling of the name, or if a path was included
, verify that the path is correct and try again.
At line:1 char:3
    + my <<<<  args -Command -
    + CategoryInfo          : ObjectNotFound: (my:String) [], CommandNotFoundE 
   xception
    + FullyQualifiedErrorId : CommandNotFoundException

I intend to put in arbitrary list of parameter without any parsing.

Edit:

As I investigate further, it seems I am doing something wrong even when the command is specified explicitly:

(local bash) $ echo '\n' | ssh -i master-key [email protected] '$SYSTEMROOT/System32/WindowsPowerShell/v1.0/powershell' -Command 'Write-Host \$\(\$args.Count\)' "my" "args"
0 my args

It seems that passes no arguments but they are printed on console for some reason. Avoiding the ssh does not seems to change anything:

(cygwin) $ $SYSTEMROOT/System32/WindowsPowerShell/v1.0/powershell -Command 'Write-Host $($args.Count)' "my" "args"
0 my args
3
  • 1
    Did you try putting my args in quotes? Commented Oct 22, 2015 at 14:54
  • I tried to doublequote the args in both variants (both together and separately) and the messages are the same as with the unquoted variants. Commented Oct 22, 2015 at 17:49
  • How about powershell remoting with ssh? Commented Oct 8, 2019 at 2:48

2 Answers 2

2

You can't do that directly, but I think this can be done, if you wrap your script in scriptblock and pass arguments to it:

echo "& { $(cat script.ps1) } 'my' 'args'" | ssh user@host "powershell -Command"

Since -Command parameter can't handle multiline strings, there is a way to pass it in (though not via standard input) using Base64 encoded value of -EncodedCommand parameter, but it's ugly:

ssh user@host "powershell -encodedcommand $((echo "& {"; cat script.ps1 ; echo "} 'my' 'args'") |  iconv -f ascii -t utf-16le | base64 -w0 ; echo -e "\n")
Sign up to request clarification or add additional context in comments.

3 Comments

Great, almost there. It seems to do nothing when my script has multiple lines. Edit: CRLF line endings seems to make no difference.
@OliverGondža Looks like -Command can't handle newlines, see updated answer.
Or separate statements with semicolon.
0

This one works as expected:

script=$(cat <<-'SCRIPT'
{ 
    $a=$Args[0];
    $b=$Args[1];
    # Do not enclose $script into "" to avoid this comment spread till the EOL
    Write-Host "This is 'a': $a";
    Write-Host "This is 'b': $b";
} # <- call as [[[ -c "& { $script } ... " ]]] if you ommit braces '{}' here 
SCRIPT
)
a="THE VALUE OF THE \"a\""
b="B B B B"
powershell -nologo -executionpolicy bypass  -c "& $script '$a' '$b'"

output:

> This is 'a': THE VALUE OF THE "a"
> This is 'b': B B B B

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.