I am trying to pass ansible variables to my powershell script as parameters. While they are successfully being passed, the path of my file is being cut short. For example, when passing a string '/Microsoft SQL Server/files/blah', and printing it in the code, it becomes '/Microsoft'.
Here is my playbook file:
- name: Deploy Report
hosts: ******
tasks:
- name: Run Powershell Script
script: "../deploy.ps1 -input1 '{{ input1 }}'"
args:
executable: powershell
Any help is greatly appreciated
Judging by the documentation of the Ansible script
module (and since confirmed to be correct by you):
A given script and its arguments are executed via a shell.
On Windows that shell appears to be PowerShell (powershell.exe
, the Windows PowerShell CLI), and it appears that what follows the script:
property is passed to the -Command
(-c
) parameter.
;
For that reason, you do not need to specify an executable:
argument in order to execute PowerShell scripts on Windows, and the following should suffice (note that I'm using the module's FCQN (Fully Qualified Collection Name), ansible.builtin.script
instead of the short name script:
, as recommended in the docs):
- name: Deploy Report
hosts: ******
tasks:
- name: Run Powershell Script
ansible.builtin.script: "../deploy.ps1 -input1 '{{ input1 }}'"
As for what you tried:
By specifying powershell
as an executable:
argument under args:
, you ended up nesting two instances of PowerShell: one that is implicitly used for execution, and the other is the one you're calling explicitly.
-Command
(-c
) nor -File
(-f
) before a command in a powershell.exe
call implies -Command
(-c
)This nesting is not only unnecessary, but causes the effective loss of the '...'
quoting in your script:
command line, which explains your symptom.
The following example demonstrates this - run it from an interactive cmd.exe
session (to simulate a no-shell invocation of powershell.exe
; if you place -noexit
before -c
, you can also invoke the command from the Windows Run
dialog (WinKey+R) for a true no-shell call):
powershell.exe -c powershell.exe -c Write-Output 'foo bar'
This doesn't output verbatim foo bar
, as one might expect, but outputs foo
and bar
on separate lines; that is, the '...'
enclosure was effectively lost, and what was ultimately executed was
Write-Output foo bar
, i.e, two arguments were passed.
The reasons are subtle:
When PowerShell executes an external program - including its own CLI - it must translate its '...'
quoting into "..."
quoting behind the scenes, given that Windows CLIs can only be expected to understand the latter form.
Therefore, when the outer powershell
call invokes the inner one, it translates 'foo bar'
into "foo bar"
behind the scenes.
However, powershell.exe
considers (unescaped) "..."
quoting to merely have syntactic function on the command line, and such quoting is removed before the resulting argument(s) are interpreted as PowerShell code, so that the inner powershell.exe
ends up executing Write-Output foo bar
If you use "..."
quoting to begin with, you can see the problem even with a single call to powershell.exe
(again, foo
and bar
print on separate lines, due to two arguments getting passed):
powershell -c Write-Output "foo bar"
[1] Notably, this default changed to -File
(-f
) in pwsh
, the PowerShell (Core) 7+ CLI.