First of all, I didn’t see that extra_args was supported in the documents so this may, or may not, be officially supported. After looking at the source code, it appears that extra_args can be passed with the win_msi module so I attempted to use this.
After attempting with one variable, all is well. As soon as multiple variables separated by a space are added, the msiexec process just hangs that’s kicked off by the win_msi.ps1 script. I have to kill the msiexec process on the Win machine to let the playbook continue.
Here is both the win_msi.ps1 and arguments files that are sent over the wire and remains on the Win machine after I told the control machine to not delete the files.
win_msi.ps1 - https://gist.github.com/itshanney/9a98c6c2f3975b43f8a8
arguments: https://gist.github.com/itshanney/0afb89dc2cb427d973b1
Finally, here is the -vvvv output from the ansible-playbook run:
https://gist.github.com/itshanney/e14878e8446552ed8da0
I would be happy to give you other debugging information if you can direct me how to retrieve what you need.
After more research on this, it appears to be the result of the problem described in this article:
http://w3facility.org/question/how-to-suppress-quotes-in-powershell-commands-to-executables/
The msiexec command that the win_msi.ps1 code is calling is not correctly handling the quoting that may be required when passing in $extra_args. An example to use for testing is the following variable, which is used to set the installation directory for the MSI. Since the directory may have spaces, you have to quote the path. The quotes then need to be escaped with backticks.
TARGETDIR='C:\Program Files\Blah\Blah\Blah
"
The code is making the assumption that the $extra_args are simple key=value pairs. For the most part, this will work. But for the cases where you have to have quotes for paths, msiexec is very persnickety in how it is expecting the parameters passed in to it. Just blindly passing $extra_args isn’t working for this edge case.
I don’t claim to be a PowerShell exerpt so I’m hoping one will be able to provide a more sound fix. I’m wondering if the approach needs to be slightly modified to build the msiexec command and then use Invoke-Expression|Command to execute the built command?
Forgot to give a concrete example. The win_msi.ps1 code is producing a command that looks like this:
msiexec.exe /i $params.path /l $logfile $extra_args;
If I manually replace the code above with the following, it works fine.
msiexec.exe /x $params.path /l $logfile TARGETDIR="D:\Program Files\Blah\Blah
"
If I were to just say the following by manually specifying $extra_args, it fails as well. It’s only when I manually type in the TARGETDIR that it works.
$extra_args = ‘TARGETDIR="D:\Program Files\Blah\Blah
"’;
It appears that the conversion from Ansible YAML → JSON → PowerShell → $extra_args → msiexec just isn’t working somewhere along the line. I can’t come up with the magic combo string to make it work.