Packer: powershell provisioner quoting issue

Created on 23 Oct 2016  路  21Comments  路  Source: hashicorp/packer

Packer v0.11.1.dev (f463239b00d6d937f45c275f9198b823a2ec267a)
winrm communicator
vmware-vmx builder
VMware Fusion 8.5
Guest: Windows server 2016 with powershell 5

Not sure why this issue didn't show up earlier in my testing but something is not correct with powershell provisioner and the way it handles quoting. I see this pr from a while ago removed quote escaping. https://github.com/mitchellh/packer/commit/1b186f16136d0c1c012108ca9873ca0e2e7d3d5d

Compare these two lines from debug logs and the quoting issue is visible. The first two quotes match and powershell attempts to run the builder name vmware-iso as a command.
https://gist.github.com/trodemaster/00e977e3716fd24f7537eefc63de185e

Here is the template I'm using to narrow down this issue. Seems like every powershell provisioner would fail based on what I'm seeing.
https://gist.github.com/trodemaster/b6dc899ebd30539f5fed294d02599b2a

Not sure why the escaping of quoting was removed but sure seems like it needs to be there to me.

Blake

bug provisionepowershell regression waiting-reply

All 21 comments

Probably introduced in #3371 which fixed #2785.

@trodemaster @simonguest @carlskii @shannonlowder
Does this work or break for you in 0.11.0 and which versions of PowerShell/Windows have you tried

It's breaking things for me on 0.11.0. I'm testing on windows server 2016 with powershell 5. I can review logs for older OS versions as the syntax is broken in a way that should not work on any of them.

It's interesting since I expect that it worked for @simonguest on at least one combination of versions.

Just installed 0.11.0 (on macOS) and ran a build to create a Windows Server 2012 R2 (Powershell v4.0) image - and everything appears to be working. However, I think I've tracked down the source of the problem:

In our builds, we are using a custom execute command (this was done as environment vars were not being passed to powershell scripts in 0.10.1 - I believe the result of another unrelated bug):

"execute_command":` "powershell '& { {{.Vars}}{{.Path}}; exit $LastExitCode}'"

The default powershell execute command uses double quotes instead of single quotes to wrap the command, so passing environment variables (if they are now working in 0.11.0) and not escaping them will indeed break this behavior.

I can do some additional testing tomorrow, and if the default powershell command now works with environment vars, we can likely roll back the PR that removed the quotes.

Ok thanks for confirming what you have been seeing. Not sure what the problem with using environment variables with powereshell you had. Here is an example of how I have been using them for a few releases now. https://github.com/trodemaster/packer-win-pc/blob/master/Win10.json

Just checked, and using the default powershell execute command does indeed cause an issue related to the environment variables not being escaped. We should go ahead and revert those changes. I can create another PR if needed - or if someone has the permissions to revert the changes made in #3371, that might be easier.

RE: on the environment variables issue: From memory, regular environment variables were being passed without issues, but the default PACKER_BUILDER_TYPE and PACKER_BUILD_NAME were not coming through. However, it looks like this has now been addressed in 0.11.0.

Hey @simonguest can you do a PR for this one? I can spend some time testing and validating it. My attempts at rolling back the merge didn't result in a clean revert or working build.

@trodemaster @simonguest could you verify this is fixed by #4069?

@rickard-von-essen I validated that #4069 fixes the powershell provisioner with non-elevated powershell invocation.

This does fix the reported issue! Thanks for getting this one cleaned up!

Cheers,
Blake

Just checked out #4069. Ran a build, and I seem to be getting errors. Here is my provisioner:

{
      "type": "powershell",
      "scripts": [
        "./scripts/vagrant/configure-static-ip.ps1"
      ]
}

The script does end up running, but I get an error related to the environment variables (which don't get set):

2016/10/26 18:32:19 packer: 2016/10/26 18:32:19 starting remote command: powershell "& { $env:PACKER_BUILDER_TYPE=\"vmware-iso\"; $env:PACKER_BUILD_NAME=\"vmware-iso\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}"
2016/10/26 18:32:22 ui:     vmware-iso: :PACKER_BUILDER_TYPE=vmware-iso : The term ':PACKER_BUILDER_TYPE=vmware-iso'
    vmware-iso: :PACKER_BUILDER_TYPE=vmware-iso : The term ':PACKER_BUILDER_TYPE=vmware-iso'
2016/10/26 18:32:22 ui:     vmware-iso: is not recognized as the name of a cmdlet, function, script file, or operable
    vmware-iso: is not recognized as the name of a cmdlet, function, script file, or operable
2016/10/26 18:32:22 ui:     vmware-iso: program. Check the spelling of the name, or if a path was included, verify
    vmware-iso: program. Check the spelling of the name, or if a path was included, verify
2016/10/26 18:32:22 ui:     vmware-iso: that the path is correct and try again.
    vmware-iso: that the path is correct and try again.
2016/10/26 18:32:22 ui:     vmware-iso: At line:1 char:5
    vmware-iso: At line:1 char:5
2016/10/26 18:32:22 ui:     vmware-iso: + & { :PACKER_BUILDER_TYPE="vmware-iso"; :PACKER_BUILD_NAME="vmware-iso";
    vmware-iso: + & { :PACKER_BUILDER_TYPE="vmware-iso"; :PACKER_BUILD_NAME="vmware-iso";
    vmware-iso: c:/Windo ...

The powershell command looks correctly escaped (as per the revert in #4069), so maybe I'm overlooking something else?

@simonguest can you double check that you are running the patched version with packer version.

Packer v0.11.1.dev

In your log the $env is missing from the command when it's executed. That seems like a shell is expanding that to a value of nothing.

: :PACKER_BUILDER_TYPE=vmware-iso : The term ':PACKER_BUILDER_TYPE=vmware-iso'

The syntax of the command is clearly correct when it's constructed and logged as you can run that successfully at the cmd prompt.

powershell "& { $env:PACKER_BUILDER_TYPE=\"vmware-iso\"; $env:PACKER_BUILD_NAME=\"vmware-iso\"; c:/Windows/Temp/script.ps1; exit $LastExitCode}"

I suspect something else about your template/host os or related is causing that $env to get expanded to nothing before this is ran. The quoting is now correct but setting the variable needs to be as follows.
$env:PACKER_BUILD_NAME=\"vmware-iso\"
not
:PACKER_BUILD_NAME=\"vmware-iso\"

Also getting this on 0.11.0 on OSX Sierra with Fusion 8

==> vmware-iso: Provisioning with shell script: scripts/windows/common/install-chocolatey.ps1
    vmware-iso: vmware-iso : The term 'vmware-iso' is not recognized as the name of a cmdlet,
    vmware-iso: function, script file, or operable program. Check the spelling of the name, or
    vmware-iso: if a path was included, verify that the path is correct and try again.
    vmware-iso: At line:1 char:30
    vmware-iso: + & { $env:PACKER_BUILDER_TYPE=vmware-iso; $env:PACKER_BUILD_NAME=vmwar ...
    vmware-iso: +                              ~~~~~~~~~~
    vmware-iso: + CategoryInfo          : ObjectNotFound: (vmware-iso:String) [], CommandN
    vmware-iso: otFoundException
    vmware-iso: + FullyQualifiedErrorId : CommandNotFoundException
    vmware-iso:
    vmware-iso: vmware-iso : The term 'vmware-iso' is not recognized as the name of a cmdlet,
    vmware-iso: function, script file, or operable program. Check the spelling of the name, or
    vmware-iso: if a path was included, verify that the path is correct and try again.
    vmware-iso: At line:1 char:65
    vmware-iso: + ... ER_BUILDER_TYPE=vmware-iso; $env:PACKER_BUILD_NAME=vmware-iso; c:/Win ...
    vmware-iso: +                                                        ~~~~~~~~~~
    vmware-iso: + CategoryInfo          : ObjectNotFound: (vmware-iso:String) [], CommandN
    vmware-iso: otFoundException
    vmware-iso: + FullyQualifiedErrorId : CommandNotFoundException
    vmware-iso:

@simonguest It should say something like:
Packer v0.11.1.dev (f17bd30070df1644007c8e436909503cbd020bcc+CHANGES)

I'll merge the fix for this. Please open new issues for any related errors. I'd really like this to work flawlessly in 0.12.0.

Hitting this on:

  • packer 0.12.0
  • virtualbox 5.0.28 r111378 (cant update because vagrant downgraded due to an issue and it doesnt work with newer versions)
  • mac sierra 10.12.2 Beta (16C48b)
    virtualbox-iso: The term ':PACKER_BUILDER_TYPE=virtualbox-iso' is not recognized as the name of
    virtualbox-iso: a cmdlet, function, script file, or operable program. Check the spelling of th
    virtualbox-iso: e name, or if a path was included, verify that the path is correct and try agai
    virtualbox-iso: n.
    virtualbox-iso: At line:1 char:42
    virtualbox-iso: + & { :PACKER_BUILDER_TYPE="virtualbox-iso" <<<< ; :PACKER_BUILD_NAME="virtualb
    virtualbox-iso: ox-iso"; c:/Windows/Temp/script.ps1; exit }
    virtualbox-iso: + CategoryInfo          : ObjectNotFound: (:PACKER_BUILDER_TYPE=virtualbox
    virtualbox-iso: -iso:String) [], CommandNotFoundException
    virtualbox-iso: + FullyQualifiedErrorId : CommandNotFoundException
    virtualbox-iso:
    virtualbox-iso: The term ':PACKER_BUILD_NAME=virtualbox-iso' is not recognized as the name of a
    virtualbox-iso: cmdlet, function, script file, or operable program. Check the spelling of the
    virtualbox-iso: name, or if a path was included, verify that the path is correct and try again.
    virtualbox-iso: At line:1 char:79
    virtualbox-iso: + & { :PACKER_BUILDER_TYPE="virtualbox-iso"; :PACKER_BUILD_NAME="virtualbox-iso
    virtualbox-iso: " <<<< ; c:/Windows/Temp/script.ps1; exit }
    virtualbox-iso: + CategoryInfo          : ObjectNotFound: (:PACKER_BUILD_NAME=virtualbox-i
    virtualbox-iso: so:String) [], CommandNotFoundException
    virtualbox-iso: + FullyQualifiedErrorId : CommandNotFoundException

@johnypony3 gist a full debug log. Most likely your install of Packer is broken.

@rickard-von-essen I think you're right, i am using brew as my macs package utility, i think there were issues which were resolved with me installing newer versions, which are/were not yet available on brew. Thank you!

i confirmed that all powershell scripts work:

config.vm.provision 'shell', inline: $script
config.vm.provision 'shell', inline: 'Write-Host hi there'
config.vm.provision 'shell', inline: "Write-Host 'hi there'"

$script = <<SCRIPT
  Write-Host 'hi there'
SCRIPT

https://github.com/taliesins/packer/commit/1526524bcc3174329bf32800e09b30c598d17e8a

I think this is what you are after. It will base 64 encode powershell snippets so they don't get interpreted before running.

@trodemaster is correct about $env

Was this page helpful?
0 / 5 - 0 ratings