Looks like you have a nice and complex command to run which makes these
things really difficult but luckily you are running Ansible 2.4 where the
escaping rules are now aligned to Microsoft standard
https://msdn.microsoft.com/en-us/library/17w5ykft(v=vs.85).aspx. We've
created a very basic executable that you are more than welcome to use to
test how your arguments look when being passed to an application from
win_command. To test it out you can run the following playbook.
- hosts: windows
gather_facts: no
vars:
app_url: http://google.com
tasks:
- name: download argv executable
win_get_url:
url: https:
//s3.amazonaws.com/ansible-ci-files/test/integration/roles/test_win_module_utils/PrintArgv.exe
dest: C:\temp\PrintArgv.exe
- name: output args found
win_command: C:\temp\PrintArgv.exe set config -section:system.
applicationHost/sites /+\"[name='{{ app_url
}}'].logFile.customFields.[logFieldName='X-Forwarded-For',sourceName='X-Forwarded-For',sourceType='RequestHeader']\"
/commit:apphost
register: output
- debug:
var: output.stdout_lines
This tests your example and it results in
ok: [SERVER2016.domain.local] => {
"output.stdout_lines": [
"set",
"config",
"-section:system.applicationHost/sites",
"/+\"[name='http://google.com'].logFile.customFields.[logFieldName='X-Forwarded-For',sourceName='X-Forwarded-For',sourceType='RequestHeader']\""
,
"/commit:apphost"
]
}
Once you take into account basic JSON escaping rules (\\ becomes \ and \"
becomes "), you can see the following arguments in your example are;
Argv[0] - set
Argv[1] - config
Argv[2] - -section:system.applicationHost/sites
Argv[3] -
/+"[name='http://google.com'].logFile.customFields.[logFieldName='X-Forwarded-For',sourceName='X-Forwarded-For',sourceType='RequestHeader']"
Argv[4] - /commit:apphost
While this is what your raw command looks like, if when you saw raw command
you mean this is what you run in cmd.exe and it works the double quotes in
Argv[3] are probably what's causing the issues. When reading the rules for
command-line arguments, 2 rules that pertain to double quotes are;
* A string surrounded by double quotation marks ("*string*") is interpreted
as a single argument, regardless of white space contained within. A quoted
string can be embedded in an argument.
* A double quotation mark preceded by a backslash (\") is interpreted as a
literal double quotation mark character (").
This means that when you just have " without a preceding \, the parser will
interpret that as the start of a quoted argument and ignore whitespaces as
an argument delimiter until another double quote is found. If you preceed
the double quote with \, it will use the double quote as an argument char
and not start/end the whitespace escaping. This means in your example, the
" char is being passed into the appcmd.exe (we can see this in the
PrintArgv.exe test) as an argument whereas your raw command indicates it is
just being used as a whitespace switch. I would try the following command
in Ansible and see how that goes (I changed \" in the complex arg to just "
so that the " literal isn't passed into the application).
- win_command: C:\temp\PrintArgv.exe set config -section:system.
applicationHost/sites /+"[name='{{ app_url
}}'].logFile.customFields.[logFieldName='X-Forwarded-For',sourceName='X-Forwarded-For',sourceType='RequestHeader']"
/commit:apphost
When testing that with the PrintArgv.exe test I can see the following
arguments are being passed into the application
TASK [debug]
************************************************************************************************************************************************
ok: [SERVER2016.domain.local] => {
"output.stdout_lines": [
"set",
"config",
"-section:system.applicationHost/sites",
"/+[name='http://google.com'].logFile.customFields.[logFieldName='X-Forwarded-For',sourceName='X-Forwarded-For',sourceType='RequestHeader']"
,
"/commit:apphost"
]
}
Once again, escaping the JSON escaping rules we can see the following
arguments are being passed into the application;
Argv[0] - set
Argv[1] - config
Argv[2] - -section:system.applicationHost/sites
Argv[3] -
/+[name='http://google.com'].logFile.customFields.[logFieldName='X-Forwarded-For',sourceName='X-Forwarded-For',sourceType='RequestHeader']
Argv[4] - /commit:apphost
Also because you don't have any whitespace characters in Argv[3], you
probably don't even need the double quotes at all but I'll leave that up to
you for testing, it may be prudent to leave them in there depending on what
the value for name is.
I honestly don't know the rules for appcmd.exe so I don't really know how
it actually expects the argument to be but I'm just going by your raw
command example and trying to predict what it is expecting.
Thanks
Jordan
--
You received this message because you are subscribed to the Google Groups
"Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/ansible-project/8139f32f-f48d-4e83-a6cf-0b38d6cc4d29%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.