[BOLT-159] Bolt commands on Powershell require triple quoting Created: 2017/10/06  Updated: 2019/02/21  Resolved: 2019/02/20

Status: Resolved
Project: Puppet Task Runner
Component/s: Windows
Affects Version/s: BOLT 0.4.1
Fix Version/s: BOLT 1.12.0

Type: Bug Priority: Normal
Reporter: John Duarte Assignee: Ethan Brown
Resolution: Fixed Votes: 0
Labels: docs_reviewed, known-issue-added, resolved-issue-added
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to BOLT-1130 Bolt PowerShell wrapper should allow ... Closed
Template:
Sprint: Bolt Kanban
Method Found: Automated Test
Release Notes: Known Issue
Release Notes Summary: String segments in commands must be triple-quoted in PowerShell.
QA Risk Assessment: Needs Assessment

 Description   

This is a "gotcha" for bolt Powershell users.

The following command that can be given to a bolt controller running *nix to be executed on *nix nodes via SSH is digested without fanfare:

bolt command run 'echo "hi from $(hostname)"' --nodes my_nix_node

...needs to have the internal quoted command triple quoted when using Windows as a bolt controller to execute the command on *nix nodes via SSH:

bolt command run 'echo """hi from $(hostname)"""' --nodes my_nix_node

...otherwise Powershell attempts to eat the command resulting in the following error.

PS C:\Users\Administrator> bolt command run 'echo "hello from $(hostname)"' --nodes my_nix_node
unknown argument(s) from, $(hostname)



 Comments   
Comment by Michael Smith [ 2018/10/04 ]

https://github.com/chef/chef/issues/3026#issuecomment-85229208 is not encouraging.

Comment by Alex Dreyer [ 2019/02/12 ]

It looks like this is an issue in how we wrap bolt in a function. If there is a better way to escape `$args` or a commandlet we can use to run ruby that will bypass the shell parsing we may be able to solve this specific case.

Comment by Ethan Brown [ 2019/02/13 ]

This is a good post that I use for reference whenever nested quoting comes into play on Windows - https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/

Comment by Ethan Brown [ 2019/02/19 ]

The following comment was left on PR describing what's improved:

While this is not a complete solution to more complex argument passing with --params (new BOLT ticket filed as BOLT-1130), for the more trivial cases where additional escaping is not required, this moves the ball forward.

Given the command bolt command run 'echo "hi from $(hostname)"' --modulepath . --nodes winrm://localhost -u Administrator -p redacted --no-ssl

Prior behavior was the following

debug output listing arguments passed to Ruby

command run echo "hi from $(hostname)" --modulepath . --nodes winrm://localhost -u Administrator -p *redacated* --no-ssl

output

ruby.exe : Unknown argument(s) from, $(hostname)
At line:4 char:5
+     &$env:RUBY_DIR\bin\ruby -S -- $env:RUBY_DIR\bin\bolt $args
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Unknown argument(s) from, $(hostname):String 
   ) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 

With this change the behavior is now

debug output listing arguments passed to Ruby

command run echo """hi from $(hostname)""" --modulepath . --nodes winrm://localhost -u Administrator -p *redacted* --no-ssl

output

Started on localhost...
Finished on localhost:
  STDOUT:
    hi from fzh53hksnquvviv
 
Successful on 1 node: winrm://localhost
Ran on 1 node in 0.95 seconds

This also now better handles PowerShell escaped quotes as in the following example:

bolt command run 'echo "hi from `"foo`""' --modulepath .  --nodes winrm://localhost -u Administrator -p *redacted* --no-ssl

output (with debug)

command run echo "hi from `"foo`"" --modulepath . --nodes winrm://localhost -u Administrator -p *redacted* --no-ssl
 
ruby.exe : Unknown argument(s) from, `foo`" --modulepath . --nodes winrm://localhost -u Administrator -p *redacted* --no-ssl
At line:4 char:5
+     &$env:RUBY_DIR\bin\ruby -S -- $env:RUBY_DIR\bin\bolt $args
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Unknown argumen...cted* --no-ssl:String) [] 
   , RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
 
command run echo """hi from `"""foo`"""""" --modulepath . --nodes winrm://localhost -u Administrator -p *redacted* --no-ssl
 
Started on localhost...
Finished on localhost:
  STDOUT:
    hi from "foo"
 
Successful on 1 node: winrm://localhost
Ran on 1 node in 0.97 seconds

Comment by Ethan Brown [ 2019/02/19 ]

Merged into master as https://github.com/puppetlabs/bolt-vanagon/commit/ae57a50ea979077b34493785967fc44bbd627f3a

Comment by Melissa Amos [ 2019/02/21 ]

Docs update:
http://docs-internal.puppet.com/docs/bolt/dev/bolt_resolved_issues.html#string-segments-in-commands-had-to-be-triple-quoted-in-powershell-1-12-0

Also removed from known issues.

Generated at Sat Feb 22 05:20:44 PST 2020 using JIRA 7.7.1#77002-sha1:e75ca93d5574d9409c0630b81c894d9065296414.